diff --git a/src/asn1c/OBJECT_IDENTIFIER.c b/src/asn1c/OBJECT_IDENTIFIER.c
new file mode 100644
index 0000000..24f4e0e
--- /dev/null
+++ b/src/asn1c/OBJECT_IDENTIFIER.c
@@ -0,0 +1,766 @@
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <INTEGER.h>
+#include <OBJECT_IDENTIFIER.h>
+#include <OCTET_STRING.h>
+#include <limits.h>	/* for CHAR_BIT */
+#include <errno.h>
+
+/*
+ * OBJECT IDENTIFIER basic type description.
+ */
+static const ber_tlv_tag_t asn_DEF_OBJECT_IDENTIFIER_tags[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (6 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
+	"OBJECT IDENTIFIER",
+	"OBJECT_IDENTIFIER",
+	ASN__PRIMITIVE_TYPE_free,
+	OBJECT_IDENTIFIER_print,
+	OBJECT_IDENTIFIER_constraint,
+	ber_decode_primitive,
+	der_encode_primitive,
+	OBJECT_IDENTIFIER_decode_xer,
+	OBJECT_IDENTIFIER_encode_xer,
+	OCTET_STRING_decode_uper,
+	OCTET_STRING_encode_uper,
+	OCTET_STRING_decode_aper,
+	OCTET_STRING_encode_aper,
+	0, /* Use generic outmost tag fetcher */
+	asn_DEF_OBJECT_IDENTIFIER_tags,
+	sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
+	    / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
+	asn_DEF_OBJECT_IDENTIFIER_tags,	/* Same as above */
+	sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
+	    / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
+	0,	/* No PER visible constraints */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
+
+int
+OBJECT_IDENTIFIER_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+		asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+	const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
+
+	if(st && st->buf) {
+		if(st->size < 1) {
+			_ASN_CTFAIL(app_key, td, sptr,
+				"%s: at least one numerical value "
+				"expected (%s:%d)",
+				td->name, __FILE__, __LINE__);
+			return -1;
+		}
+	} else {
+		_ASN_CTFAIL(app_key, td, sptr,
+			"%s: value not given (%s:%d)",
+			td->name, __FILE__, __LINE__);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+int
+OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, unsigned int arclen, signed int add, void *rvbufp, unsigned int rvsize) {
+	unsigned LE GCC_NOTUSED = 1; /* Little endian (x86) */
+	const uint8_t *arcend = arcbuf + arclen;	/* End of arc */
+	unsigned int cache = 0;	/* No more than 14 significant bits */
+	unsigned char *rvbuf = (unsigned char *)rvbufp;
+	unsigned char *rvstart = rvbuf;	/* Original start of the value buffer */
+	int inc;	/* Return value growth direction */
+
+	rvsize *= CHAR_BIT;	/* bytes to bits */
+	arclen *= 7;		/* bytes to bits */
+
+	/*
+	 * The arc has the number of bits
+	 * cannot be represented using supplied return value type.
+	 */
+	if(arclen > rvsize) {
+		if(arclen > (rvsize + CHAR_BIT)) {
+			errno = ERANGE;	/* Overflow */
+			return -1;
+		} else {
+			/*
+			 * Even if the number of bits in the arc representation
+			 * is higher than the width of supplied * return value
+			 * type, there is still possible to fit it when there
+			 * are few unused high bits in the arc value
+			 * representaion.
+			 * 
+			 * Moreover, there is a possibility that the
+			 * number could actually fit the arc space, given
+			 * that add is negative, but we don't handle
+			 * such "temporary lack of precision" situation here.
+			 * May be considered as a bug.
+			 */
+			uint8_t mask = (0xff << (7-(arclen - rvsize))) & 0x7f;
+			if((*arcbuf & mask)) {
+				errno = ERANGE;	/* Overflow */
+				return -1;
+			}
+			/* Fool the routine computing unused bits */
+			arclen -= 7;
+			cache = *arcbuf & 0x7f;
+			arcbuf++;
+		}
+	}
+
+	/* Faster path for common size */
+	if(rvsize == (CHAR_BIT * sizeof(unsigned long))) {
+		unsigned long accum;
+		/* Gather all bits into the accumulator */
+		for(accum = cache; arcbuf < arcend; arcbuf++)
+			accum = (accum << 7) | (*arcbuf & ~0x80);
+		if(accum < (unsigned)-add) {
+			errno = ERANGE;	/* Overflow */
+			return -1;
+		}
+		*(unsigned long *)(void *)rvbuf = accum + add;	/* alignment OK! */
+		return 0;
+	}
+
+#ifndef	WORDS_BIGENDIAN
+	if(*(unsigned char *)&LE) {	/* Little endian (x86) */
+		/* "Convert" to big endian */
+		rvbuf += rvsize / CHAR_BIT - 1;
+		rvstart--;
+		inc = -1;	/* Descending */
+	} else
+#endif	/* !WORDS_BIGENDIAN */
+		inc = +1;	/* Big endian is known [at compile time] */
+
+	{
+		int bits;	/* typically no more than 3-4 bits */
+
+		/* Clear the high unused bits */
+		for(bits = rvsize - arclen;
+			bits > CHAR_BIT;
+				rvbuf += inc, bits -= CHAR_BIT)
+				*rvbuf = 0;
+
+		/* Fill the body of a value */
+		for(; arcbuf < arcend; arcbuf++) {
+			cache = (cache << 7) | (*arcbuf & 0x7f);
+			bits += 7;
+			if(bits >= CHAR_BIT) {
+				bits -= CHAR_BIT;
+				*rvbuf = (cache >> bits);
+				rvbuf += inc;
+			}
+		}
+		if(bits) {
+			*rvbuf = cache;
+			rvbuf += inc;
+		}
+	}
+
+	if(add) {
+		for(rvbuf -= inc; rvbuf != rvstart; rvbuf -= inc) {
+			int v = add + *rvbuf;
+			if(v & (-1 << CHAR_BIT)) {
+				*rvbuf = (unsigned char)(v + (1 << CHAR_BIT));
+				add = -1;
+			} else {
+				*rvbuf = v;
+				break;
+			}
+		}
+		if(rvbuf == rvstart) {
+			/* No space to carry over */
+			errno = ERANGE;	/* Overflow */
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+ssize_t
+OBJECT_IDENTIFIER__dump_arc(const uint8_t *arcbuf, int arclen, int add,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	char scratch[64];	/* Conservative estimate */
+	unsigned long accum;	/* Bits accumulator */
+	char *p;		/* Position in the scratch buffer */
+
+	if(OBJECT_IDENTIFIER_get_single_arc(arcbuf, arclen, add,
+			&accum, sizeof(accum)))
+		return -1;
+
+	if(accum) {
+		ssize_t len;
+
+		/* Fill the scratch buffer in reverse. */
+		p = scratch + sizeof(scratch);
+		for(; accum; accum /= 10)
+			*(--p) = (char)(accum % 10) + 0x30; /* Put a digit */
+
+		len = sizeof(scratch) - (p - scratch);
+		if(cb(p, len, app_key) < 0)
+			return -1;
+		return len;
+	} else {
+		*scratch = 0x30;
+		if(cb(scratch, 1, app_key) < 0)
+			return -1;
+		return 1;
+	}
+}
+
+int
+OBJECT_IDENTIFIER_print_arc(const uint8_t *arcbuf, int arclen, int add,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+
+	if(OBJECT_IDENTIFIER__dump_arc(arcbuf, arclen, add, cb, app_key) < 0)
+		return -1;
+
+	return 0;
+}
+
+static ssize_t
+OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
+	ssize_t wrote_len = 0;
+	int startn;
+	int add = 0;
+	int i;
+
+	for(i = 0, startn = 0; i < st->size; i++) {
+		uint8_t b = st->buf[i];
+		if((b & 0x80))			/* Continuation expected */
+			continue;
+
+		if(startn == 0) {
+			/*
+			 * First two arcs are encoded through the backdoor.
+			 */
+			if(i) {
+				add = -80;
+				if(cb("2", 1, app_key) < 0) return -1;
+			} else if(b <= 39) {
+				add = 0;
+				if(cb("0", 1, app_key) < 0) return -1;
+			} else if(b < 79) {
+				add = -40;
+				if(cb("1", 1, app_key) < 0) return -1;
+			} else {
+				add = -80;
+				if(cb("2", 1, app_key) < 0) return -1;
+			}
+			wrote_len += 1;
+		}
+
+		if(cb(".", 1, app_key) < 0)	/* Separate arcs */
+			return -1;
+
+		add = OBJECT_IDENTIFIER__dump_arc(&st->buf[startn],
+				i - startn + 1, add, cb, app_key);
+		if(add < 0) return -1;
+		wrote_len += 1 + add;
+		startn = i + 1;
+		add = 0;
+	}
+
+	return wrote_len;
+}
+
+static enum xer_pbd_rval
+OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
+	OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr;
+	const char *chunk_end = (const char *)chunk_buf + chunk_size;
+	const char *endptr;
+	long s_arcs[10];
+	long *arcs = s_arcs;
+	int arcs_count;
+	int ret;
+
+	(void)td;
+
+	arcs_count = OBJECT_IDENTIFIER_parse_arcs(
+		(const char *)chunk_buf, chunk_size, arcs,
+			sizeof(s_arcs)/sizeof(s_arcs[0]), &endptr);
+	if(arcs_count < 0) {
+		/* Expecting more than zero arcs */
+		return XPBD_BROKEN_ENCODING;
+	} else if(arcs_count == 0) {
+		return XPBD_NOT_BODY_IGNORE;
+	}
+	assert(endptr == chunk_end);
+
+	if((size_t)arcs_count > sizeof(s_arcs)/sizeof(s_arcs[0])) {
+		arcs = (long *)MALLOC(arcs_count * sizeof(long));
+		if(!arcs) return XPBD_SYSTEM_FAILURE;
+		ret = OBJECT_IDENTIFIER_parse_arcs(
+			(const char *)chunk_buf, chunk_size,
+			arcs, arcs_count, &endptr);
+		if(ret != arcs_count)
+			return XPBD_SYSTEM_FAILURE;	/* assert?.. */
+	}
+
+	/*
+	 * Convert arcs into BER representation.
+	 */
+	ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, sizeof(*arcs), arcs_count);
+	if(arcs != s_arcs) FREEMEM(arcs);
+
+	return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
+}
+
+asn_dec_rval_t
+OBJECT_IDENTIFIER_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
+	asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
+		const void *buf_ptr, size_t size) {
+
+	return xer_decode_primitive(opt_codec_ctx, td,
+		sptr, sizeof(OBJECT_IDENTIFIER_t), opt_mname,
+			buf_ptr, size, OBJECT_IDENTIFIER__xer_body_decode);
+}
+
+asn_enc_rval_t
+OBJECT_IDENTIFIER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+	int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
+	asn_enc_rval_t er;
+
+	(void)ilevel;
+	(void)flags;
+
+	if(!st || !st->buf)
+		_ASN_ENCODE_FAILED;
+
+	er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key);
+	if(er.encoded < 0) _ASN_ENCODE_FAILED;
+
+	_ASN_ENCODED_OK(er);
+}
+
+int
+OBJECT_IDENTIFIER_print(asn_TYPE_descriptor_t *td, const void *sptr,
+	int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
+
+	(void)td;	/* Unused argument */
+	(void)ilevel;	/* Unused argument */
+
+	if(!st || !st->buf)
+		return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+
+	/* Dump preamble */
+	if(cb("{ ", 2, app_key) < 0)
+		return -1;
+
+	if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0)
+		return -1;
+
+	return (cb(" }", 2, app_key) < 0) ? -1 : 0;
+}
+
+int
+OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *oid, void *arcs,
+		unsigned int arc_type_size, unsigned int arc_slots) {
+	void *arcs_end = (char *)arcs + (arc_type_size * arc_slots);
+	int num_arcs = 0;
+	int startn = 0;
+	int add = 0;
+	int i;
+
+	if(!oid || !oid->buf || (arc_slots && arc_type_size <= 1)) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	for(i = 0; i < oid->size; i++) {
+		uint8_t b = oid->buf[i];
+		if((b & 0x80))			/* Continuation expected */
+			continue;
+
+		if(num_arcs == 0) {
+			/*
+			 * First two arcs are encoded through the backdoor.
+			 */
+			unsigned LE = 1;	/* Little endian */
+			int first_arc;
+			num_arcs++;
+			if(!arc_slots) { num_arcs++; continue; }
+
+			if(i) first_arc = 2;
+			else if(b <= 39) first_arc = 0;
+			else if(b < 79)	first_arc = 1;
+			else first_arc = 2;
+
+			add = -40 * first_arc;
+			memset(arcs, 0, arc_type_size);
+			*(unsigned char *)((char *)arcs
+				+ ((*(char *)&LE)?0:(arc_type_size - 1)))
+					= first_arc;
+			arcs = ((char *)arcs) + arc_type_size;
+		}
+
+		/* Decode, if has space */
+		if(arcs < arcs_end) {
+			if(OBJECT_IDENTIFIER_get_single_arc(&oid->buf[startn],
+				i - startn + 1, add,
+					arcs, arc_type_size))
+				return -1;
+			startn = i + 1;
+			arcs = ((char *)arcs) + arc_type_size;
+			add = 0;
+		}
+		num_arcs++;
+	}
+
+	return num_arcs;
+}
+
+
+/*
+ * Save the single value as an object identifier arc.
+ */
+int
+OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, const void *arcval, unsigned int arcval_size, int prepared_order) {
+	/*
+	 * The following conditions must hold:
+	 * assert(arcval);
+	 * assert(arcval_size > 0);
+	 * assert(arcval_size <= 16);
+	 * assert(arcbuf);
+	 */
+#ifdef	WORDS_BIGENDIAN
+	const unsigned isLittleEndian = 0;
+#else
+	unsigned LE = 1;
+	unsigned isLittleEndian = *(char *)&LE;
+#endif
+	const uint8_t *tend, *tp;
+	unsigned int cache;
+	uint8_t *bp = arcbuf;
+	int bits;
+	uint8_t buffer[16];
+
+	if(isLittleEndian && !prepared_order) {
+		const uint8_t *a = (const unsigned char *)arcval + arcval_size - 1;
+		const uint8_t *aend = (const uint8_t *)arcval;
+		uint8_t *msb = buffer + arcval_size - 1;
+		uint8_t *tb;
+		for(tb = buffer; a >= aend; tb++, a--)
+			if((*tb = *a) && (tb < msb))
+				msb = tb;
+		tend = &buffer[arcval_size];
+		tp = msb;	/* Most significant non-zero byte */
+	} else {
+		/* Look for most significant non-zero byte */
+		tend = (const unsigned char *)arcval + arcval_size;
+		for(tp = (const uint8_t *)arcval; tp < tend - 1; tp++)
+			if(*tp) break;
+	}
+
+	/*
+	 * Split the value in 7-bits chunks.
+	 */
+	bits = ((tend - tp) * CHAR_BIT) % 7;
+	if(bits) {
+		cache = *tp >> (CHAR_BIT - bits);
+		if(cache) {
+			*bp++ = cache | 0x80;
+			cache = *tp++;
+			bits = CHAR_BIT - bits;
+		} else {
+			bits = -bits;
+		}
+	} else {
+		cache = 0;
+	}
+	for(; tp < tend; tp++) {
+		cache = (cache << CHAR_BIT) + *tp;
+		bits += CHAR_BIT;
+		while(bits >= 7) {
+			bits -= 7;
+			*bp++ = 0x80 | (cache >> bits);
+		}
+	}
+	if(bits) *bp++ = cache;
+	bp[-1] &= 0x7f;	/* Clear the last bit */
+
+	return bp - arcbuf;
+}
+
+int
+OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *oid, const void *arcs, unsigned int arc_type_size, unsigned int arc_slots) {
+	uint8_t *buf;
+	uint8_t *bp;
+	unsigned LE = 1;	/* Little endian (x86) */
+	unsigned isLittleEndian = *((char *)&LE);
+	unsigned int arc0;
+	unsigned int arc1;
+	unsigned size;
+	unsigned i;
+
+	if(!oid || !arcs || arc_type_size < 1
+	|| arc_type_size > 16
+	|| arc_slots < 2) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	switch(arc_type_size) {
+	case sizeof(char):
+		arc0 = ((const unsigned char *)arcs)[0];
+		arc1 = ((const unsigned char *)arcs)[1];
+		break;
+	case sizeof(short):
+		arc0 = ((const unsigned short *)arcs)[0];
+		arc1 = ((const unsigned short *)arcs)[1];
+		break;
+	case sizeof(int):
+		arc0 = ((const unsigned int *)arcs)[0];
+		arc1 = ((const unsigned int *)arcs)[1];
+		break;
+	default:
+		arc1 = arc0 = 0;
+		if(isLittleEndian) {	/* Little endian (x86) */
+			const unsigned char *ps, *pe;
+			/* If more significant bytes are present,
+			 * make them > 255 quick */
+			for(ps = (const unsigned char *)arcs + 1, pe = ps+arc_type_size;
+					ps < pe; ps++)
+				arc0 |= *ps, arc1 |= *(ps + arc_type_size);
+			arc0 <<= CHAR_BIT, arc1 <<= CHAR_BIT;
+			arc0 = *((const unsigned char *)arcs + 0);
+			arc1 = *((const unsigned char *)arcs + arc_type_size);
+		} else {
+			const unsigned char *ps, *pe;
+			/* If more significant bytes are present,
+			 * make them > 255 quick */
+			for(ps = (const unsigned char *)arcs, pe = ps+arc_type_size - 1; ps < pe; ps++)
+				arc0 |= *ps, arc1 |= *(ps + arc_type_size);
+			arc0 = *((const unsigned char *)arcs + arc_type_size - 1);
+			arc1 = *((const unsigned char *)arcs +(arc_type_size<< 1)-1);
+		}
+	}
+
+	/*
+	 * The previous chapter left us with the first and the second arcs.
+	 * The values are not precise (that is, they are valid only if
+	 * they're less than 255), but OK for the purposes of making
+	 * the sanity test below.
+	 */
+	if(arc0 <= 1) {
+		if(arc1 >= 39) {
+			/* 8.19.4: At most 39 subsequent values (including 0) */
+			errno = ERANGE;
+			return -1;
+		}
+	} else if(arc0 > 2) {
+		/* 8.19.4: Only three values are allocated from the root node */
+		errno = ERANGE;
+		return -1;
+	}
+	/*
+	 * After above tests it is known that the value of arc0 is completely
+	 * trustworthy (0..2). However, the arc1's value is still meaningless.
+	 */
+
+	/*
+	 * Roughly estimate the maximum size necessary to encode these arcs.
+	 * This estimation implicitly takes in account the following facts,
+	 * that cancel each other:
+	 * 	* the first two arcs are encoded in a single value.
+	 * 	* the first value may require more space (+1 byte)
+	 * 	* the value of the first arc which is in range (0..2)
+	 */
+	size = ((arc_type_size * CHAR_BIT + 6) / 7) * arc_slots;
+	bp = buf = (uint8_t *)MALLOC(size + 1);
+	if(!buf) {
+		/* ENOMEM */
+		return -1;
+	}
+
+	/*
+	 * Encode the first two arcs.
+	 * These require special treatment.
+	 */
+	{
+		uint8_t *tp;
+		uint8_t first_value[1 + 16];	/* of two arcs */
+		uint8_t *fv = first_value;
+
+		/*
+		 * Simulate first_value = arc0 * 40 + arc1;
+		 */
+		/* Copy the second (1'st) arcs[1] into the first_value */
+		*fv++ = 0;
+		arcs = ((const char *)arcs) + arc_type_size;
+		if(isLittleEndian) {
+			const uint8_t *aend = (const unsigned char *)arcs - 1;
+			const uint8_t *a1 = (const unsigned char *)arcs + arc_type_size - 1;
+			for(; a1 > aend; fv++, a1--) *fv = *a1;
+		} else {
+			const uint8_t *a1 = (const uint8_t *)arcs;
+			const uint8_t *aend = a1 + arc_type_size;
+			for(; a1 < aend; fv++, a1++) *fv = *a1;
+		}
+		/* Increase the first_value by arc0 */
+		arc0 *= 40;	/* (0..80) */
+		for(tp = first_value + arc_type_size; tp >= first_value; tp--) {
+			unsigned int v = *tp;
+			v += arc0;
+			*tp = v;
+			if(v >= (1 << CHAR_BIT)) arc0 = v >> CHAR_BIT;
+			else break;
+		}
+
+		assert(tp >= first_value);
+
+		bp += OBJECT_IDENTIFIER_set_single_arc(bp, first_value,
+			fv - first_value, 1);
+ 	}
+
+	/*
+	 * Save the rest of arcs.
+	 */
+	for(arcs = ((const char *)arcs) + arc_type_size, i = 2;
+		i < arc_slots;
+			i++, arcs = ((const char *)arcs) + arc_type_size) {
+		bp += OBJECT_IDENTIFIER_set_single_arc(bp,
+			arcs, arc_type_size, 0);
+	}
+
+	assert((unsigned)(bp - buf) <= size);
+
+	/*
+	 * Replace buffer.
+	 */
+	oid->size = bp - buf;
+	bp = oid->buf;
+	oid->buf = buf;
+	if(bp) FREEMEM(bp);
+
+	return 0;
+}
+
+
+int
+OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
+	long *arcs, unsigned int arcs_slots, const char **opt_oid_text_end) {
+	unsigned int arcs_count = 0;
+	const char *oid_end;
+	enum {
+		ST_LEADSPACE,
+		ST_TAILSPACE,
+		ST_AFTERVALUE,	/* Next character ought to be '.' or a space */
+		ST_WAITDIGITS,	/* Next character is expected to be a digit */
+	} state = ST_LEADSPACE;
+
+	if(!oid_text || oid_txt_length < -1 || (arcs_slots && !arcs)) {
+		if(opt_oid_text_end) *opt_oid_text_end = oid_text;
+		errno = EINVAL;
+		return -1;
+	}
+
+	if(oid_txt_length == -1)
+		oid_txt_length = strlen(oid_text);
+
+#define	_OID_CAPTURE_ARC(oid_text, oid_end)		do {	\
+	const char *endp = oid_end;				\
+	long value;						\
+	switch(asn_strtol_lim(oid_text, &endp, &value)) {	\
+	case ASN_STRTOL_EXTRA_DATA:				\
+	case ASN_STRTOL_OK:					\
+		if(arcs_count < arcs_slots)			\
+			arcs[arcs_count] = value;		\
+		arcs_count++;					\
+		oid_text = endp - 1;				\
+		break;						\
+	case ASN_STRTOL_ERROR_RANGE:				\
+		if(opt_oid_text_end)				\
+			*opt_oid_text_end = oid_text;		\
+		errno = ERANGE;					\
+		return -1;					\
+	case ASN_STRTOL_ERROR_INVAL:				\
+	case ASN_STRTOL_EXPECT_MORE:				\
+		if(opt_oid_text_end)				\
+			*opt_oid_text_end = oid_text;		\
+		errno = EINVAL;					\
+		return -1;					\
+	}							\
+  } while(0)
+
+	for(oid_end = oid_text + oid_txt_length; oid_text<oid_end; oid_text++) {
+	    switch(*oid_text) {
+	    case 0x09: case 0x0a: case 0x0d: case 0x20:	/* whitespace */
+		switch(state) {
+		case ST_LEADSPACE:
+		case ST_TAILSPACE:
+			continue;
+		case ST_AFTERVALUE:
+			state = ST_TAILSPACE;
+			continue;
+		case ST_WAITDIGITS:
+			break;	/* Digits expected after ".", got whitespace */
+		}
+		break;
+	    case 0x2e:	/* '.' */
+		switch(state) {
+		case ST_LEADSPACE:
+		case ST_TAILSPACE:
+		case ST_WAITDIGITS:
+			if(opt_oid_text_end)
+				*opt_oid_text_end = oid_text;
+			errno = EINVAL;	/* Broken OID */
+			return -1;
+			break;
+		case ST_AFTERVALUE:
+			state = ST_WAITDIGITS;
+			continue;
+		}
+		break;
+	    case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
+	    case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
+		switch(state) {
+		case ST_TAILSPACE:
+		case ST_AFTERVALUE:
+			if(opt_oid_text_end)
+				*opt_oid_text_end = oid_text;
+			errno = EINVAL;	/* "1. 1" => broken OID */
+			return -1;
+		case ST_LEADSPACE:
+		case ST_WAITDIGITS:
+			_OID_CAPTURE_ARC(oid_text, oid_end);
+			state = ST_AFTERVALUE;
+			continue;
+		}
+		break;
+	    default:
+		/* Unexpected symbols */
+		state = ST_WAITDIGITS;
+		break;
+	    } /* switch() */
+	    break;
+	} /* for() */
+
+
+	if(opt_oid_text_end) *opt_oid_text_end = oid_text;
+
+	/* Finalize last arc */
+	switch(state) {
+	case ST_LEADSPACE:
+		return 0; /* No OID found in input data */
+	case ST_WAITDIGITS:
+		errno = EINVAL;	/* Broken OID */
+		return -1;
+	case ST_AFTERVALUE:
+	case ST_TAILSPACE:
+		return arcs_count;
+	}
+
+	errno = EINVAL;	/* Broken OID */
+	return -1;
+}
+
+
