class JsonParserSequence extends JsonParserDelegate
{
    /**
     * Parsers other than the first one (which is initially assigned
     * as delegate)
     */
    protected final JsonParser[] _parsers;

    /**
     * Configuration that determines whether state of parsers is first verified
     * to see if parser already points to a token (that is,
     * {@link JsonParser#hasCurrentToken()} returns <code>true</code>), and if so
     * that token is first return before {@link JsonParser#nextToken} is called.
     * If enabled, this check is made; if disabled, no check is made and
     * {@link JsonParser#nextToken} is always called for all parsers.
     *<p>
     * Default setting is <code>false</code> (for backwards-compatibility)
     * so that possible existing token is not considered for parsers.
     *
     * @since 2.8
     */
    protected final boolean _checkForExistingToken;

    /**
     * Index of the next parser in {@link #_parsers}.
     */
    protected int _nextParserIndex;

    /**
     * Flag used to indicate that `JsonParser.nextToken()` should not be called,
     * due to parser already pointing to a token.
     *
     * @since 2.8
     */
    protected boolean _hasToken;

    /*
     *******************************************************
     * Construction
     *******************************************************
     */

    @Deprecated // since 2.8
    protected JsonParserSequence(JsonParser[] parsers) {
        this(false, parsers);
    }

    // @since 2.8
    protected JsonParserSequence(boolean checkForExistingToken, JsonParser[] parsers)
    {
        super(parsers[0]);
        _checkForExistingToken = checkForExistingToken;
        _hasToken = checkForExistingToken && delegate.hasCurrentToken();
        _parsers = parsers;
        _nextParserIndex = 1;
    }

    /**
     * Method that will construct a sequence (possibly a sequence) that
     * contains all given sub-parsers.
     * All parsers given are checked to see if they are sequences: and
     * if so, they will be "flattened", that is, contained parsers are
     * directly added in a new sequence instead of adding sequences
     * within sequences. This is done to minimize delegation depth,
     * ideally only having just a single level of delegation.
     *
     * @param checkForExistingToken Flag passed to be assigned as
     *   {@link #_checkForExistingToken} for resulting sequence
     * @param first First parser to traverse
     * @param second Second parser to traverse
     *
     * @return Sequence instance constructed
     */
    public static JsonParserSequence createFlattened(boolean checkForExistingToken,
            JsonParser first, JsonParser second)
    {
        if (!(first instanceof JsonParserSequence || second instanceof JsonParserSequence)) {
            return new JsonParserSequence(checkForExistingToken,
                    new JsonParser[] { first, second });
        }
        ArrayList<JsonParser> p = new ArrayList<>();
        if (first instanceof JsonParserSequence) {
            ((JsonParserSequence) first).addFlattenedActiveParsers(p);
        } else {
            p.add(first);
        }
        if (second instanceof JsonParserSequence) {
            ((JsonParserSequence) second).addFlattenedActiveParsers(p);
        } else {
            p.add(second);
        }
        return new JsonParserSequence(checkForExistingToken,
                p.toArray(new JsonParser[p.size()]));
    }

    @Deprecated // since 2.8
    public static JsonParserSequence createFlattened(JsonParser first, JsonParser second) {
        return createFlattened(false, first, second);
    }

    @SuppressWarnings("resource")
    protected void addFlattenedActiveParsers(List<JsonParser> listToAddIn)
    {
        for (int i = _nextParserIndex-1, len = _parsers.length; i < len; ++i) {
            JsonParser p = _parsers[i];
            if (p instanceof JsonParserSequence) {
                ((JsonParserSequence) p).addFlattenedActiveParsers(listToAddIn);
            } else {
                listToAddIn.add(p);
            }
        }
    }

    /*
    /*******************************************************
    /* Overridden methods, needed: cases where default
    /* delegation does not work
    /*******************************************************
     */

    @Override
    public void close() throws IOException {
        do { delegate.close(); } while (switchToNext());
    }

    @Override
    public JsonToken nextToken() throws IOException
    {<FILL_FUNCTION_BODY>}

    /**
     * Need to override, re-implement similar to how method defined in
     * {@link com.fasterxml.jackson.core.base.ParserMinimalBase}, to keep
     * state correct here.
     */
    @Override
    public JsonParser skipChildren() throws IOException
    {
        if ((delegate.currentToken() != JsonToken.START_OBJECT)
            && (delegate.currentToken() != JsonToken.START_ARRAY)) {
            return this;
        }
        int open = 1;

        // Since proper matching of start/end markers is handled
        // by nextToken(), we'll just count nesting levels here
        while (true) {
            JsonToken t = nextToken();
            if (t == null) { // not ideal but for now, just return
                return this;
            }
            if (t.isStructStart()) {
                ++open;
            } else if (t.isStructEnd()) {
                if (--open == 0) {
                    return this;
                }
            }
        }
    }

    /*
    /*******************************************************
    /* Additional extended API
    /*******************************************************
     */

    /**
     * Method that is most useful for debugging or testing;
     * returns actual number of underlying parsers sequence
     * was constructed with (nor just ones remaining active)
     *
     * @return Number of actual underlying parsers this sequence has
     */
    public int containedParsersCount() {
        return _parsers.length;
    }

    /*
    /*******************************************************
    /* Helper methods
    /*******************************************************
     */

    /**
     * Method that will switch active delegate parser from the current one
     * to the next parser in sequence, if there is another parser left:
     * if so, the next parser will become the active delegate parser.
     *
     * @return True if switch succeeded; false otherwise
     *
     * @since 2.8
     */
    protected boolean switchToNext()
    {
        if (_nextParserIndex < _parsers.length) {
            delegate = _parsers[_nextParserIndex++];
            return true;
        }
        return false;
    }

    protected JsonToken switchAndReturnNext() throws IOException
    {
        while (_nextParserIndex < _parsers.length) {
            delegate = _parsers[_nextParserIndex++];
            if (_checkForExistingToken && delegate.hasCurrentToken()) {
                return delegate.getCurrentToken();
            }
            JsonToken t = delegate.nextToken();
            if (t != null) {
                return t;
            }
        }
        return null;
    }
}

        if (delegate == null) {
            return null;
        }
        if (_hasToken) {
            _hasToken = false;
           return delegate.currentToken();
        }
        JsonToken t = delegate.nextToken();
        if (t == null) {
            return switchAndReturnNext();
        }
        return t;
    
<methods>public void <init>(com.fasterxml.jackson.core.JsonParser) ,public void assignCurrentValue(java.lang.Object) ,public boolean canParseAsync() ,public boolean canReadObjectId() ,public boolean canReadTypeId() ,public boolean canUseSchema(com.fasterxml.jackson.core.FormatSchema) ,public void clearCurrentToken() ,public void close() throws java.io.IOException,public com.fasterxml.jackson.core.JsonLocation currentLocation() ,public java.lang.String currentName() throws java.io.IOException,public com.fasterxml.jackson.core.JsonToken currentToken() ,public int currentTokenId() ,public com.fasterxml.jackson.core.JsonLocation currentTokenLocation() ,public java.lang.Object currentValue() ,public com.fasterxml.jackson.core.JsonParser delegate() ,public com.fasterxml.jackson.core.JsonParser disable(com.fasterxml.jackson.core.JsonParser.Feature) ,public com.fasterxml.jackson.core.JsonParser enable(com.fasterxml.jackson.core.JsonParser.Feature) ,public void finishToken() throws java.io.IOException,public java.math.BigInteger getBigIntegerValue() throws java.io.IOException,public byte[] getBinaryValue(com.fasterxml.jackson.core.Base64Variant) throws java.io.IOException,public boolean getBooleanValue() throws java.io.IOException,public byte getByteValue() throws java.io.IOException,public com.fasterxml.jackson.core.ObjectCodec getCodec() ,public com.fasterxml.jackson.core.JsonLocation getCurrentLocation() ,public java.lang.String getCurrentName() throws java.io.IOException,public com.fasterxml.jackson.core.JsonToken getCurrentToken() ,public int getCurrentTokenId() ,public java.lang.Object getCurrentValue() ,public java.math.BigDecimal getDecimalValue() throws java.io.IOException,public double getDoubleValue() throws java.io.IOException,public java.lang.Object getEmbeddedObject() throws java.io.IOException,public int getFeatureMask() ,public float getFloatValue() throws java.io.IOException,public java.lang.Object getInputSource() ,public int getIntValue() throws java.io.IOException,public com.fasterxml.jackson.core.JsonToken getLastClearedToken() ,public long getLongValue() throws java.io.IOException,public com.fasterxml.jackson.core.async.NonBlockingInputFeeder getNonBlockingInputFeeder() ,public com.fasterxml.jackson.core.JsonParser.NumberType getNumberType() throws java.io.IOException,public com.fasterxml.jackson.core.JsonParser.NumberTypeFP getNumberTypeFP() throws java.io.IOException,public java.lang.Number getNumberValue() throws java.io.IOException,public java.lang.Object getNumberValueDeferred() throws java.io.IOException,public java.lang.Number getNumberValueExact() throws java.io.IOException,public java.lang.Object getObjectId() throws java.io.IOException,public com.fasterxml.jackson.core.JsonStreamContext getParsingContext() ,public JacksonFeatureSet<com.fasterxml.jackson.core.StreamReadCapability> getReadCapabilities() ,public com.fasterxml.jackson.core.FormatSchema getSchema() ,public short getShortValue() throws java.io.IOException,public java.lang.String getText() throws java.io.IOException,public int getText(java.io.Writer) throws java.io.IOException, java.lang.UnsupportedOperationException,public char[] getTextCharacters() throws java.io.IOException,public int getTextLength() throws java.io.IOException,public int getTextOffset() throws java.io.IOException,public com.fasterxml.jackson.core.JsonLocation getTokenLocation() ,public java.lang.Object getTypeId() throws java.io.IOException,public boolean getValueAsBoolean() throws java.io.IOException,public boolean getValueAsBoolean(boolean) throws java.io.IOException,public double getValueAsDouble() throws java.io.IOException,public double getValueAsDouble(double) throws java.io.IOException,public int getValueAsInt() throws java.io.IOException,public int getValueAsInt(int) throws java.io.IOException,public long getValueAsLong() throws java.io.IOException,public long getValueAsLong(long) throws java.io.IOException,public java.lang.String getValueAsString() throws java.io.IOException,public java.lang.String getValueAsString(java.lang.String) throws java.io.IOException,public boolean hasCurrentToken() ,public boolean hasTextCharacters() ,public boolean hasToken(com.fasterxml.jackson.core.JsonToken) ,public boolean hasTokenId(int) ,public boolean isClosed() ,public boolean isEnabled(com.fasterxml.jackson.core.JsonParser.Feature) ,public boolean isExpectedNumberIntToken() ,public boolean isExpectedStartArrayToken() ,public boolean isExpectedStartObjectToken() ,public boolean isNaN() throws java.io.IOException,public com.fasterxml.jackson.core.JsonToken nextToken() throws java.io.IOException,public com.fasterxml.jackson.core.JsonToken nextValue() throws java.io.IOException,public void overrideCurrentName(java.lang.String) ,public com.fasterxml.jackson.core.JsonParser overrideFormatFeatures(int, int) ,public com.fasterxml.jackson.core.JsonParser overrideStdFeatures(int, int) ,public int readBinaryValue(com.fasterxml.jackson.core.Base64Variant, java.io.OutputStream) throws java.io.IOException,public boolean requiresCustomCodec() ,public void setCodec(com.fasterxml.jackson.core.ObjectCodec) ,public void setCurrentValue(java.lang.Object) ,public com.fasterxml.jackson.core.JsonParser setFeatureMask(int) ,public void setSchema(com.fasterxml.jackson.core.FormatSchema) ,public com.fasterxml.jackson.core.JsonParser skipChildren() throws java.io.IOException,public com.fasterxml.jackson.core.StreamReadConstraints streamReadConstraints() ,public com.fasterxml.jackson.core.Version version() <variables>protected com.fasterxml.jackson.core.JsonParser delegate