instrumentation
diff --git a/asn1c/tests/check-126.-gen-PER.c b/asn1c/tests/check-126.-gen-PER.c
index b28ed79..8b590b1 100644
--- a/asn1c/tests/check-126.-gen-PER.c
+++ b/asn1c/tests/check-126.-gen-PER.c
@@ -104,7 +104,7 @@
 		st = 0;
 
 		do {
-			fprintf(stderr, "Decoding bytes %d..%d (left %d) [%s]\n",
+			fprintf(stderr, "\nDecoding bytes %d..%d (left %d) [%s]\n",
 				fbuf_offset,
 					fbuf_chunk < fbuf_left
 						? fbuf_chunk : fbuf_left,
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index ad737ff..c824c04 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -1092,7 +1092,7 @@
 		pd->buffer = oldpd->buffer;
 		pd->nboff = oldpd->nboff - 1;
 		pd->nbits = oldpd->nbits;
-		ASN_DEBUG("Return from unclaimed");
+		ASN_DEBUG("Return from UNCLAIMED");
 		return 0;
 	}
 
@@ -1133,7 +1133,7 @@
 
 	_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx);
 
-	ASN_DEBUG("Getting open type from %d bits (%d+%d), %p", pd->nbits - pd->nboff, pd->nboff, pd->nbits, pd->buffer);
+	ASN_DEBUG("Getting open type off %d (%d+%d), %p", pd->moved, pd->nboff, pd->nbits, pd->buffer);
 	arg.oldpd = *pd;
 	arg.unclaimed = 0;
 	arg.ot_moved = 0;
@@ -1149,22 +1149,32 @@
 		td->name, pd->moved, arg.oldpd.moved,
 		arg.unclaimed, arg.repeat);
 
+	ASN_DEBUG("OT1 moved %d, estimated %d uncl=%d",
+		arg.oldpd.moved,
+		arg.oldpd.nboff + ((((int)arg.oldpd.buffer) & 0x7) << 3),
+		arg.unclaimed
+	);
+
 	padding = pd->moved % 8;
 	if(padding) {
+		int32_t pvalue;
 		if(padding > 7) {
 			ASN_DEBUG("Too large padding %d in open type",
 				padding);
 			rv.code = RC_FAIL;
 			return rv;
 		}
+		padding = 8 - padding;
 		ASN_DEBUG("Getting padding of %d bits", padding);
-		switch(per_get_few_bits(pd, padding)) {
+		pvalue = per_get_few_bits(pd, padding);
+		switch(pvalue) {
 		case -1:
 			ASN_DEBUG("Padding skip failed");
-			_ASN_DECODE_FAILED;
+			_ASN_DECODE_STARVED;
 		case 0: break;
 		default:
-			ASN_DEBUG("Non-blank padding");
+			ASN_DEBUG("Non-blank padding (%d bits 0x%02x)",
+				padding, pvalue);
 			_ASN_DECODE_FAILED;
 		}
 	}
@@ -1173,15 +1183,15 @@
 		if(1) _ASN_DECODE_FAILED;
 		arg.unclaimed += pd->nbits - pd->nboff;
 	}
-	arg.oldpd.nbits -= pd->moved - arg.ot_moved;
-	arg.oldpd.moved += pd->moved - arg.ot_moved;
-	pd->nboff = arg.oldpd.nboff;
-	pd->nbits = arg.oldpd.nbits;
-	pd->moved = arg.oldpd.moved;
+
+	/* Adjust pd back so it points to original data */
+	pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved);
+	pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved);
 	pd->refill = arg.oldpd.refill;
 	pd->refill_key = arg.oldpd.refill_key;
 
 	/* Skip data not consumed by the decoder */
+	if(arg.unclaimed) ASN_DEBUG("Getting unclaimed %d", arg.unclaimed);
 	while(arg.unclaimed) {
 		size_t toget = 24;
 		if(arg.unclaimed < toget)
@@ -1201,6 +1211,8 @@
 		}
 	}
 
+	assert(pd->moved == pd->nboff + ((((int)pd->buffer) & 0x7) << 3));
+
 	if(arg.repeat) {
 		ASN_DEBUG("Not consumed the whole thing");
 		rv.code = RC_FAIL;
@@ -1411,6 +1423,7 @@
 		/* Skip over overflow extensions which aren't present
 		 * in this system's version of the protocol */
 		for(;;) {
+			ASN_DEBUG("Getting overflow extensions");
 			switch(per_get_few_bits(&epmd, 1)) {
 			case -1: break;
 			case 0: continue;
@@ -1580,6 +1593,8 @@
 		void *memb_ptr;		/* Pointer to the member */
 		void **memb_ptr2;	/* Pointer to that pointer */
 
+		ASN_DEBUG("About to encode %s", elm->type->name);
+
 		/* Fetch the pointer to this member */
 		if(elm->flags & ATF_POINTER) {
 			memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
diff --git a/skeletons/per_encoder.c b/skeletons/per_encoder.c
index 960981a..f4bace0 100644
--- a/skeletons/per_encoder.c
+++ b/skeletons/per_encoder.c
@@ -88,6 +88,7 @@
 		}
 	default:
 		*buffer_r = key.buffer;
+		ASN_DEBUG("Complete encoded in %d bits", er.encoded);
 		return ((er.encoded + 7) >> 3);
 	}
 }
diff --git a/skeletons/per_encoder.h b/skeletons/per_encoder.h
index 32de082..95a6506 100644
--- a/skeletons/per_encoder.h
+++ b/skeletons/per_encoder.h
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2006, 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #ifndef	_PER_ENCODER_H_
@@ -42,7 +42,7 @@
  * A variant of uper_encode_to_buffer() which allocates buffer itself.
  * Returns the number of bytes in the buffer or -1 in case of failure.
  * WARNING: This function produces a "Production of the complete encoding",
- * with length of at least one octet. Contrast this to precise bit-preserving
+ * with length of at least one octet. Contrast this to precise bit-packing
  * encoding of uper_encode() and uper_encode_to_buffer().
  */
 ssize_t uper_encode_to_new_buffer(
diff --git a/skeletons/per_support.c b/skeletons/per_support.c
index 6187f2c..bfd733a 100644
--- a/skeletons/per_support.c
+++ b/skeletons/per_support.c
@@ -34,7 +34,7 @@
 		int32_t tailv, vhead;
 		if(!pd->refill || nbits > 31) return -1;
 		/* Accumulate unused bytes before refill */
-		ASN_DEBUG("Obtain the rest %d bits", nleft);
+		ASN_DEBUG("Obtain the rest %d bits (want %d)", nleft, nbits);
 		tailv = per_get_few_bits(pd, nleft);
 		if(tailv < 0) return -1;
 		/* Refill (replace pd contents with new data) */
@@ -47,9 +47,6 @@
 		return tailv;
 	}
 
-	ASN_DEBUG("[PER get %d bits from (%d@%d+%d)]",
-		nbits, pd->moved, pd->nboff, nleft);
-
 	/*
 	 * Normalize position indicator.
 	 */
@@ -89,7 +86,12 @@
 		return -1;
 	}
 
-	return (accum & (((uint32_t)1 << nbits) - 1));
+	accum &= (((uint32_t)1 << nbits) - 1);
+
+	ASN_DEBUG("[PER got %d bits from (%d@%d+%d) => 0x%x]",
+		nbits, pd->moved, pd->nboff, nleft, accum);
+
+	return accum;
 }
 
 /*
@@ -172,12 +174,13 @@
 uper_get_nslength(asn_per_data_t *pd) {
 	ssize_t length;
 
+	ASN_DEBUG("Getting normally small length");
+
 	if(per_get_few_bits(pd, 1) == 0) {
-		ASN_DEBUG("l=?");
-		length = per_get_few_bits(pd, 6);
+		length = per_get_few_bits(pd, 6) + 1;
+		if(length <= 0) return -1;
 		ASN_DEBUG("l=%d", length);
-		if(length < 0) return -1;
-		return length + 1;
+		return length;
 	} else {
 		int repeat;
 		length = uper_get_length(pd, -1, &repeat);
diff --git a/tests/126-per-extensions-OK.asn1 b/tests/126-per-extensions-OK.asn1
index 26503cd..3d70866 100644
--- a/tests/126-per-extensions-OK.asn1
+++ b/tests/126-per-extensions-OK.asn1
@@ -16,15 +16,16 @@
 		str-o	IA5String	OPTIONAL,
 		str-m	IA5String,
 		singl	Singleton,
-		pdu-2	PDU-2
+		pdu-2	PDU-2	OPTIONAL
 	}
 
 	Singleton ::= SEQUENCE {
-		mandatory IA5String DEFAULT "z"
+		opt-z	IA5String DEFAULT "z"
 	}
 
 	PDU-2 ::= CHOICE {
-		str-p2 IA5String
+		str-p2 IA5String,
+		...
 	}
 
 END