int index = 0;  try { ASN1Header header = new ASN1Header(istream);  header.validate( tag, Form.CONSTRUCTED );   long remainingContent = header.getContentLength();  boolean repeatableElement=false; SEQUENCE seq = new SEQUENCE(); ASN1Header lookAhead=null;   for( index = 0; index < size(); index++ ) {   if( remainingContent == 0 ) { lookAhead = null; } else {   lookAhead = ASN1Header.lookAhead(istream); }    Element e = (Element) elements.elementAt(index); if( (lookAhead == null) || lookAhead.isEOC() || ! e.tagMatch( lookAhead.getTag() ) ) { if( e.isRepeatable() ) { repeatableElement = true; } else if( e.isOptional() ) {  SEQUENCE.Element se = new SEQUENCE.Element(null, null ); seq.addElement( null ); } else if( e.getDefault() != null ) {  seq.addElement( e.getDefault() ); } else { throw new InvalidBERException("Missing item #" + index + ": expecting " + lookAhead.getTag() + ", found" + e.getImplicitTag() ); } continue; }   ASN1Template t = e.getTemplate(); ASN1Value val; CountingStream countstream = new CountingStream(istream); if( e.getImplicitTag() == null ) { val = t.decode(countstream); } else { val = t.decode(e.getImplicitTag(), countstream); }   long len = countstream.getNumRead(); if( remainingContent != -1 ) { if( remainingContent < len ) {  throw new InvalidBERException("Item went "+ (len-remainingContent)+" bytes past the end of"+ " the SEQUENCE"); } remainingContent -= len; }   if(  e.getImplicitTag() == null ) {  seq.addElement( val ); } else {  seq.addElement( e.getImplicitTag(), val ); }   if( e.isRepeatable() ) { repeatableElement = true; index--; } }  if( remainingContent > 0 ) { throw new InvalidBERException("SEQUENCE is " + remainingContent + " bytes longer than expected"); } Assert._assert( remainingContent == 0 || remainingContent == -1 );   if( remainingContent == -1 ) { lookAhead = new ASN1Header(istream); if( ! lookAhead.isEOC() ) { throw new InvalidBERException("No end-of-contents marker"); } }   if( ! repeatableElement ) { Assert._assert(index == seq.size()); }  return seq;  } catch(InvalidBERException e) { throw new InvalidBERException(e, "SEQUENCE(item #"+index+")"); }
return decode(getTag(), istream);
    public ASN1Value decode(Tag tag, InputStream istream)        throws IOException, InvalidBERException    {      int index = 0;      try {        ASN1Header header = new ASN1Header(istream);        header.validate( tag, Form.CONSTRUCTED );        // will be -1 for indefinite encoding        long remainingContent = header.getContentLength();        boolean repeatableElement=false;        SEQUENCE seq = new SEQUENCE();        ASN1Header lookAhead=null;        // go through the whole template        for( index = 0; index < size(); index++ ) {            // find out about the next item            if( remainingContent == 0 ) {                lookAhead = null;            } else {                // remainingContent > 0 or remainingContent == -1, which means                // indefinite encoding.                lookAhead = ASN1Header.lookAhead(istream);            }            // skip over items that don't match.  Hopefully they are            // optional or have a default.  Otherwise, it's an error.            Element e = (Element) elements.elementAt(index);            if( (lookAhead == null) || lookAhead.isEOC() ||                    ! e.tagMatch( lookAhead.getTag() ) )            {                if( e.isRepeatable() ) {                    repeatableElement = true;                } else if( e.isOptional() ) {                    // put an empty entry into the SEQUENCE                    SEQUENCE.Element se = new SEQUENCE.Element(null, null );                    seq.addElement( null );                } else if( e.getDefault() != null ) {                    // use the default                    seq.addElement( e.getDefault() );                } else {                    throw new InvalidBERException("Missing item #" + index +                        ": expecting " + lookAhead.getTag() + ", found"                        + e.getImplicitTag() );                }                continue;            }            // Decode this element            ASN1Template t = e.getTemplate();            ASN1Value val;            CountingStream countstream = new CountingStream(istream);            if( e.getImplicitTag() == null ) {                val = t.decode(countstream);            } else {                val = t.decode(e.getImplicitTag(), countstream);            }            // Decrement remaining count            long len = countstream.getNumRead();            if( remainingContent != -1 ) {                if( remainingContent < len ) {                    // this item went past the end of the SEQUENCE                    throw new InvalidBERException("Item went "+                        (len-remainingContent)+" bytes past the end of"+                        " the SEQUENCE");                }                remainingContent -= len;            }            // Store this element in the SEQUENCE            if(  e.getImplicitTag() == null ) {                // no implicit tag                seq.addElement( val );            } else {                // there is an implicit tag                seq.addElement( e.getImplicitTag(), val );            }            // If this element is repeatable, don't go on to the next element            if( e.isRepeatable() ) {                repeatableElement = true;                index--;            }        }        if( remainingContent > 0 ) {            throw new InvalidBERException("SEQUENCE is " + remainingContent +                " bytes longer than expected");        }        Assert._assert( remainingContent == 0 || remainingContent == -1 );        // If this was indefinite-length encoding, consume the end-of-contents        if( remainingContent == -1 ) {            lookAhead = new ASN1Header(istream);            if( ! lookAhead.isEOC() ) {                throw new InvalidBERException("No end-of-contents marker");            }        }        // Make sure we stayed in sync        if( ! repeatableElement ) {            Assert._assert(index == seq.size());        }        return seq;      } catch(InvalidBERException e) {        throw new InvalidBERException(e, "SEQUENCE(item #"+index+")");      }    }