fix after UPER round-trip fuzz
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index d080ccb..bf4de7a 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -1,4 +1,4 @@
-/*-
+/*
  * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
  * All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
@@ -66,10 +66,9 @@
 /*
  * Check whether we are inside the extensions group.
  */
-#define	IN_EXTENSION_GROUP(specs, memb_idx)	\
-	( (((signed)(memb_idx)) > (specs)->ext_after)	\
-	&&(((signed)(memb_idx)) < (specs)->ext_before))
-
+#define IN_EXTENSION_GROUP(specs, memb_idx) \
+    ((specs)->first_extension >= 0          \
+     && (unsigned)(specs)->first_extension <= (memb_idx))
 
 /*
  * Tags are canonically sorted in the tag2element map.
@@ -209,24 +208,19 @@
 			elements[edx].flags, elements[edx].optional,
 			td->elements_count);
 
-		if(ctx->left == 0	/* No more stuff is expected */
-		&& (
-			/* Explicit OPTIONAL specification reaches the end */
-			(edx + elements[edx].optional
-					== td->elements_count)
-			||
-			/* All extensions are optional */
-			(IN_EXTENSION_GROUP(specs, edx)
-				&& specs->ext_before > (signed)td->elements_count)
-		   )
-		) {
-			ASN_DEBUG("End of SEQUENCE %s", td->name);
-			/*
-			 * Found the legitimate end of the structure.
-			 */
-			PHASE_OUT(ctx);
-			RETURN(RC_OK);
-		}
+        if(ctx->left == 0 /* No more stuff is expected */
+           && (
+                  /* Explicit OPTIONAL specification reaches the end */
+                  (edx + elements[edx].optional == td->elements_count) ||
+                  /* All extensions are optional */
+                  IN_EXTENSION_GROUP(specs, edx))) {
+            ASN_DEBUG("End of SEQUENCE %s", td->name);
+            /*
+             * Found the legitimate end of the structure.
+             */
+            PHASE_OUT(ctx);
+            RETURN(RC_OK);
+        }
 
 		/*
 		 * Fetch the T from TLV.
@@ -242,34 +236,31 @@
 		case -1: RETURN(RC_FAIL);
 		}
 
-		if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
-			if(LEFT < 2) {
-				if(SIZE_VIOLATION)
-					RETURN(RC_FAIL);
-				else
-					RETURN(RC_WMORE);
-			} else if(((const uint8_t *)ptr)[1] == 0) {
-			ASN_DEBUG("edx = %zu, opt = %d, ec=%d",
-				edx, elements[edx].optional,
-				td->elements_count);
-				if((edx + elements[edx].optional
-					== td->elements_count)
-				|| (IN_EXTENSION_GROUP(specs, edx)
-					&& specs->ext_before
-						> (signed)td->elements_count)) {
-					/*
-					 * Yeah, baby! Found the terminator
-					 * of the indefinite length structure.
-					 */
-					/*
-					 * Proceed to the canonical
-					 * finalization function.
-					 * No advancing is necessary.
-					 */
-					goto phase3;
-				}
-			}
-		}
+        if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
+            if(LEFT < 2) {
+                if(SIZE_VIOLATION) {
+                    RETURN(RC_FAIL);
+                } else {
+                    RETURN(RC_WMORE);
+                }
+            } else if(((const uint8_t *)ptr)[1] == 0) {
+                ASN_DEBUG("edx = %zu, opt = %d, ec=%d", edx,
+                          elements[edx].optional, td->elements_count);
+                if((edx + elements[edx].optional == td->elements_count)
+                   || IN_EXTENSION_GROUP(specs, edx)) {
+                    /*
+                     * Yeah, baby! Found the terminator
+                     * of the indefinite length structure.
+                     */
+                    /*
+                     * Proceed to the canonical
+                     * finalization function.
+                     * No advancing is necessary.
+                     */
+                    goto phase3;
+                }
+            }
+        }
 
 		/*
 		 * Find the next available type with this tag.
@@ -766,19 +757,13 @@
 			ctx->phase = 0;
 			/* Fall through */
 		case XCT_BOTH:
-			if(ctx->phase == 0) {
-				if(edx >= td->elements_count
-				   ||
-				   /* Explicit OPTIONAL specs reaches the end */
-				    (edx + elements[edx].optional
-					== td->elements_count)
-				   ||
-				   /* All extensions are optional */
-				   (IN_EXTENSION_GROUP(specs, edx)
-					&& specs->ext_before
-						> (signed)td->elements_count)
-				) {
-					XER_ADVANCE(ch_size);
+            if(ctx->phase == 0) {
+                if(edx >= td->elements_count ||
+                   /* Explicit OPTIONAL specs reaches the end */
+                   (edx + elements[edx].optional == td->elements_count) ||
+                   /* All extensions are optional */
+                   IN_EXTENSION_GROUP(specs, edx)) {
+                    XER_ADVANCE(ch_size);
 					ctx->phase = 4;	/* Phase out */
 					RETURN(RC_OK);
 				} else {
@@ -1113,11 +1098,11 @@
 	ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
 
 	/* Handle extensions */
-	if(specs->ext_before >= 0) {
+	if(specs->first_extension < 0) {
+		extpresent = 0;
+	} else {
 		extpresent = per_get_few_bits(pd, 1);
 		if(extpresent < 0) ASN__DECODE_STARVED;
-	} else {
-		extpresent = 0;
 	}
 
 	/* Prepare a place and read-in the presence bitmap */
@@ -1141,13 +1126,15 @@
 	/*
 	 * Get the sequence ROOT elements.
 	 */
-	for(edx = 0; edx < td->elements_count; edx++) {
-		asn_TYPE_member_t *elm = &td->elements[edx];
+    for(edx = 0;
+        edx < (specs->first_extension < 0 ? td->elements_count
+                                          : (size_t)specs->first_extension);
+        edx++) {
+        asn_TYPE_member_t *elm = &td->elements[edx];
 		void *memb_ptr;		/* Pointer to the member */
 		void **memb_ptr2;	/* Pointer to that pointer */
 
-		if(IN_EXTENSION_GROUP(specs, edx))
-			continue;
+		assert(!IN_EXTENSION_GROUP(specs, edx));
 
 		/* Fetch the pointer to this member */
 		if(elm->flags & ATF_POINTER) {
@@ -1210,7 +1197,7 @@
 		bmlength = uper_get_nslength(pd);
 		if(bmlength < 0) ASN__DECODE_STARVED;
 
-		ASN_DEBUG("Extensions %ld present in %s", (long)bmlength, td->name);
+		ASN_DEBUG("Extensions %zd present in %s", bmlength, td->name);
 
 		epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
 		if(!epres) ASN__DECODE_STARVED;
@@ -1228,38 +1215,35 @@
 			td->name, (long)bmlength, *epres);
 
 	    /* Go over extensions and read them in */
-	    for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
-		asn_TYPE_member_t *elm = &td->elements[edx];
-		void *memb_ptr;		/* Pointer to the member */
-		void **memb_ptr2;	/* Pointer to that pointer */
-		int present;
+        for(edx = specs->first_extension; edx < td->elements_count; edx++) {
+            asn_TYPE_member_t *elm = &td->elements[edx];
+            void *memb_ptr;   /* Pointer to the member */
+            void **memb_ptr2; /* Pointer to that pointer */
+            int present;
 
-		if(!IN_EXTENSION_GROUP(specs, edx)) {
-			ASN_DEBUG("%zu is not an extension", edx);
-			continue;
-		}
+            /* Fetch the pointer to this member */
+            if(elm->flags & ATF_POINTER) {
+                memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+            } else {
+                memb_ptr = (void *)((char *)st + elm->memb_offset);
+                memb_ptr2 = &memb_ptr;
+            }
 
-		/* Fetch the pointer to this member */
-		if(elm->flags & ATF_POINTER) {
-			memb_ptr2 = (void **)((char *)st + elm->memb_offset);
-		} else {
-			memb_ptr = (void *)((char *)st + elm->memb_offset);
-			memb_ptr2 = &memb_ptr;
-		}
+            present = per_get_few_bits(&epmd, 1);
+            if(present <= 0) {
+                if(present < 0) break; /* No more extensions */
+                continue;
+            }
 
-		present = per_get_few_bits(&epmd, 1);
-		if(present <= 0) {
-			if(present < 0) break;	/* No more extensions */
-			continue;
-		}
-
-		ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2);
-		rv = uper_open_type_get(opt_codec_ctx, elm->type,
-			elm->encoding_constraints.per_constraints, memb_ptr2, pd);
-		if(rv.code != RC_OK) {
-			FREEMEM(epres);
-			return rv;
-		}
+            ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name,
+                      *memb_ptr2);
+            rv = uper_open_type_get(opt_codec_ctx, elm->type,
+                                    elm->encoding_constraints.per_constraints,
+                                    memb_ptr2, pd);
+            if(rv.code != RC_OK) {
+                FREEMEM(epres);
+                return rv;
+            }
 	    }
 
 		/* Skip over overflow extensions which aren't present
@@ -1274,6 +1258,8 @@
 					FREEMEM(epres);
 					ASN__DECODE_STARVED;
 				}
+                ASN_DEBUG("Skipped overflow extension");
+                continue;
 			}
 			break;
 		}
@@ -1281,28 +1267,33 @@
 		FREEMEM(epres);
 	}
 
-	/* Fill DEFAULT members in extensions */
-	for(edx = specs->roms_count; edx < specs->roms_count
-			+ specs->aoms_count; edx++) {
-		asn_TYPE_member_t *elm = &td->elements[edx];
-		void **memb_ptr2;	/* Pointer to member pointer */
+    if(specs->first_extension >= 0) {
+        unsigned i;
+        /* Fill DEFAULT members in extensions */
+        for(i = specs->roms_count; i < specs->roms_count + specs->aoms_count;
+            i++) {
+            asn_TYPE_member_t *elm;
+            void **memb_ptr2; /* Pointer to member pointer */
 
-		if(!elm->default_value_set) continue;
+            edx = specs->oms[i];
+            elm = &td->elements[edx];
 
-		/* Fetch the pointer to this member */
-		if(elm->flags & ATF_POINTER) {
-			memb_ptr2 = (void **)((char *)st
-					+ elm->memb_offset);
-			if(*memb_ptr2) continue;
-		} else {
-			continue;	/* Extensions are all optionals */
-		}
+            if(!elm->default_value_set) continue;
 
-		/* Set default value */
-        if(elm->default_value_set(memb_ptr2)) {
-            ASN__DECODE_FAILED;
-		}
-	}
+            /* Fetch the pointer to this member */
+            if(elm->flags & ATF_POINTER) {
+                memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+                if(*memb_ptr2) continue;
+            } else {
+                continue; /* Extensions are all optionals */
+            }
+
+            /* Set default value */
+            if(elm->default_value_set(memb_ptr2)) {
+                ASN__DECODE_FAILED;
+            }
+        }
+    }
 
 	rv.consumed = 0;
 	rv.code = RC_OK;
@@ -1312,54 +1303,52 @@
 static int
 SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr,
                             asn_per_outp_t *po1, asn_per_outp_t *po2) {
-    const asn_SEQUENCE_specifics_t *specs
-		= (const asn_SEQUENCE_specifics_t *)td->specifics;
-	int exts_present = 0;
-	int exts_count = 0;
-	size_t edx;
+    const asn_SEQUENCE_specifics_t *specs =
+        (const asn_SEQUENCE_specifics_t *)td->specifics;
+    int exts_present = 0;
+    int exts_count = 0;
+    size_t edx;
 
-	if(specs->ext_before < 0)
-		return 0;
+    if(specs->first_extension < 0) {
+        return 0;
+    }
 
-	/* Find out which extensions are present */
-	for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
-		asn_TYPE_member_t *elm = &td->elements[edx];
-        const void *memb_ptr; /* Pointer to the member */
+    /* Find out which extensions are present */
+    for(edx = specs->first_extension; edx < td->elements_count; edx++) {
+        asn_TYPE_member_t *elm = &td->elements[edx];
+        const void *memb_ptr;         /* Pointer to the member */
         const void *const *memb_ptr2; /* Pointer to that pointer */
         int present;
 
-		if(!IN_EXTENSION_GROUP(specs, edx)) {
-			ASN_DEBUG("%s (@%zu) is not extension", elm->type->name, edx);
-			continue;
-		}
-
-		/* Fetch the pointer to this member */
-		if(elm->flags & ATF_POINTER) {
+        /* Fetch the pointer to this member */
+        if(elm->flags & ATF_POINTER) {
             memb_ptr2 =
                 (const void *const *)((const char *)sptr + elm->memb_offset);
             present = (*memb_ptr2 != 0);
-		} else {
+        } else {
             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
             memb_ptr2 = &memb_ptr;
 			present = 1;
 		}
 
-		ASN_DEBUG("checking %s (@%zu) present => %d",
-			elm->type->name, edx, present);
-		exts_count++;
-		exts_present += present;
+        ASN_DEBUG("checking %s:%s (@%zu) present => %d", elm->name,
+                  elm->type->name, edx, present);
+        exts_count++;
+        exts_present += present;
 
-		/* Encode as presence marker */
-		if(po1 && per_put_few_bits(po1, present, 1))
-			return -1;
-		/* Encode as open type field */
-		if(po2 && present && uper_open_type_put(elm->type,
-				elm->encoding_constraints.per_constraints, *memb_ptr2, po2))
-			return -1;
+        /* Encode as presence marker */
+        if(po1 && per_put_few_bits(po1, present, 1)) {
+            return -1;
+        }
+        /* Encode as open type field */
+        if(po2 && present
+           && uper_open_type_put(elm->type,
+                                 elm->encoding_constraints.per_constraints,
+                                 *memb_ptr2, po2))
+            return -1;
+    }
 
-	}
-
-	return exts_present ? exts_count : 0;
+    return exts_present ? exts_count : 0;
 }
 
 asn_enc_rval_t
@@ -1382,20 +1371,19 @@
 
 	ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
 
-
 	/*
 	 * X.691#18.1 Whether structure is extensible
 	 * and whether to encode extensions
 	 */
-	if(specs->ext_before >= 0) {
-		n_extensions = SEQUENCE__handle_extensions(td, sptr, 0, 0);
-		if(n_extensions < 0)
-			ASN__ENCODE_FAILED;
-		if(per_put_few_bits(po, n_extensions ? 1 : 0, 1))
-			ASN__ENCODE_FAILED;
-	} else {
-		n_extensions = 0;	/* There are no extensions to encode */
-	}
+    if(specs->first_extension < 0) {
+        n_extensions = 0; /* There are no extensions to encode */
+    } else {
+        n_extensions = SEQUENCE__handle_extensions(td, sptr, 0, 0);
+        if(n_extensions < 0) ASN__ENCODE_FAILED;
+        if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) {
+            ASN__ENCODE_FAILED;
+        }
+    }
 
 	/* Encode a presence bitmap */
 	for(i = 0; i < specs->roms_count; i++) {
@@ -1434,16 +1422,15 @@
 	/*
 	 * Encode the sequence ROOT elements.
 	 */
-	ASN_DEBUG("ext_after = %d, ec = %d, eb = %d", specs->ext_after, td->elements_count, specs->ext_before);
-	for(edx = 0; edx < ((specs->ext_after < 0)
-		? td->elements_count : (size_t)specs->ext_before - 1); edx++) {
-
+    ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
+              td->elements_count);
+	for(edx = 0;
+		edx < ((specs->first_extension < 0) ? td->elements_count
+                                            : (size_t)specs->first_extension);
+		edx++) {
 		asn_TYPE_member_t *elm = &td->elements[edx];
-        const void *memb_ptr;         /* Pointer to the member */
-        const void *const *memb_ptr2; /* Pointer to that pointer */
-
-        if(IN_EXTENSION_GROUP(specs, edx))
-			continue;
+		const void *memb_ptr;         /* Pointer to the member */
+		const void *const *memb_ptr2; /* Pointer to that pointer */
 
 		ASN_DEBUG("About to encode %s", elm->type->name);
 
@@ -1468,17 +1455,17 @@
 		if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
 			continue;
 
-		ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
-		er = elm->type->op->uper_encoder(elm->type, elm->encoding_constraints.per_constraints,
-			*memb_ptr2, po);
-		if(er.encoded == -1)
-			return er;
-	}
+        ASN_DEBUG("Encoding %s->%s:%s", td->name, elm->name, elm->type->name);
+        er = elm->type->op->uper_encoder(
+            elm->type, elm->encoding_constraints.per_constraints, *memb_ptr2,
+            po);
+        if(er.encoded == -1) return er;
+    }
 
 	/* No extensions to encode */
 	if(!n_extensions) ASN__ENCODED_OK(er);
 
-	ASN_DEBUG("Length of %d bit-map", n_extensions);
+	ASN_DEBUG("Length of extensions %d bit-map", n_extensions);
 	/* #18.8. Write down the presence bit-map length. */
 	if(uper_put_nslength(po, n_extensions))
 		ASN__ENCODE_FAILED;