Rewrite of #296: require setting during construction to enable "check for existing current token"
diff --git a/src/main/java/com/fasterxml/jackson/core/util/JsonParserSequence.java b/src/main/java/com/fasterxml/jackson/core/util/JsonParserSequence.java
index 0c9c4eb..5b75047 100644
--- a/src/main/java/com/fasterxml/jackson/core/util/JsonParserSequence.java
+++ b/src/main/java/com/fasterxml/jackson/core/util/JsonParserSequence.java
@@ -20,11 +20,26 @@
      * 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 _nextParser;
+    protected int _nextParserIndex;
 
     /**
      * Flag used to indicate that `JsonParser.nextToken()` should not be called,
@@ -32,20 +47,29 @@
      *
      * @since 2.8
      */
-    protected boolean _suppressNextToken;
-    
+    protected boolean _hasToken;
+
     /*
      *******************************************************
      * Construction
      *******************************************************
      */
 
-    protected JsonParserSequence(JsonParser[] parsers)
+    @Deprecated // since 2.8
+    protected JsonParserSequence(JsonParser[] parsers) {
+        this(false, parsers);
+    }
+
+    /**
+     * @since 2.8
+     */
+    protected JsonParserSequence(boolean checkForExistingToken, JsonParser[] parsers)
     {
         super(parsers[0]);
-        _suppressNextToken = delegate.hasCurrentToken();
+        _checkForExistingToken = checkForExistingToken;
+        _hasToken = checkForExistingToken && delegate.hasCurrentToken();
         _parsers = parsers;
-        _nextParser = 1;
+        _nextParserIndex = 1;
     }
 
     /**
@@ -57,11 +81,12 @@
      * within sequences. This is done to minimize delegation depth,
      * ideally only having just a single level of delegation.
      */
-    public static JsonParserSequence createFlattened(JsonParser first, JsonParser second)
+    public static JsonParserSequence createFlattened(boolean checkForExistingToken,
+            JsonParser first, JsonParser second)
     {
         if (!(first instanceof JsonParserSequence || second instanceof JsonParserSequence)) {
-            // simple:
-            return new JsonParserSequence(new JsonParser[] { first, second });
+            return new JsonParserSequence(checkForExistingToken,
+                    new JsonParser[] { first, second });
         }
         ArrayList<JsonParser> p = new ArrayList<JsonParser>();
         if (first instanceof JsonParserSequence) {
@@ -74,29 +99,39 @@
         } else {
             p.add(second);
         }
-        return new JsonParserSequence(p.toArray(new JsonParser[p.size()]));
+        return new JsonParserSequence(checkForExistingToken,
+                p.toArray(new JsonParser[p.size()]));
     }
 
+    /**
+     * @deprecated Since 2.8 use {@link #createFlattened(boolean, JsonParser, JsonParser)}
+     *    instead
+     */
+    @Deprecated // since 2.8
+    public static JsonParserSequence createFlattened(JsonParser first, JsonParser second) {
+        return createFlattened(false, first, second);
+    }
+    
     @SuppressWarnings("resource")
-    protected void addFlattenedActiveParsers(List<JsonParser> result)
+    protected void addFlattenedActiveParsers(List<JsonParser> listToAddIn)
     {
-        for (int i = _nextParser-1, len = _parsers.length; i < len; ++i) {
+        for (int i = _nextParserIndex-1, len = _parsers.length; i < len; ++i) {
             JsonParser p = _parsers[i];
             if (p instanceof JsonParserSequence) {
-                ((JsonParserSequence) p).addFlattenedActiveParsers(result);
+                ((JsonParserSequence) p).addFlattenedActiveParsers(listToAddIn);
             } else {
-                result.add(p);
+                listToAddIn.add(p);
             }
         }
     }
-    
+
     /*
-     *******************************************************
-     * Overridden methods, needed: cases where default
-     * delegation does not work
-     *******************************************************
+    /*******************************************************
+    /* Overridden methods, needed: cases where default
+    /* delegation does not work
+    /*******************************************************
      */
-    
+
     @Override
     public void close() throws IOException {
         do { delegate.close(); } while (switchToNext());
@@ -108,14 +143,13 @@
         if (delegate == null) {
             return null;
         }
-        if (_suppressNextToken) {
-            _suppressNextToken = false;
-            return delegate.currentToken();
+        if (_hasToken) {
+            _hasToken = false;
+           return delegate.currentToken();
         }
         JsonToken t = delegate.nextToken();
-        while ((t == null) && switchToNext()) {
-            t = delegate.hasCurrentToken()
-                    ? delegate.currentToken() : delegate.nextToken();
+        if (t == null) {
+            return switchAndReturnNext();
         }
         return t;
     }
@@ -134,7 +168,7 @@
     public int containedParsersCount() {
         return _parsers.length;
     }
-    
+
     /*
     /*******************************************************
     /* Helper methods
@@ -142,19 +176,35 @@
      */
 
     /**
-     * Method that will switch active parser from the current one
-     * to next parser in sequence, if there is another parser left,
-     * making this the new delegate. Old delegate is returned if
-     * switch succeeds.
+     * 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 (_nextParser >= _parsers.length) {
-            return false;
+        if (_nextParserIndex < _parsers.length) {
+            delegate = _parsers[_nextParserIndex++];
+            return true;
         }
-        delegate = _parsers[_nextParser++];
-        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;
     }
 }
diff --git a/src/test/java/com/fasterxml/jackson/core/json/ParserSequenceTest.java b/src/test/java/com/fasterxml/jackson/core/json/ParserSequenceTest.java
index f555186..85363f4 100644
--- a/src/test/java/com/fasterxml/jackson/core/json/ParserSequenceTest.java
+++ b/src/test/java/com/fasterxml/jackson/core/json/ParserSequenceTest.java
@@ -11,7 +11,7 @@
     {
         JsonParser p1 = JSON_FACTORY.createParser("[ 1 ]");
         JsonParser p2 = JSON_FACTORY.createParser("[ 2 ]");
-        JsonParserSequence seq = JsonParserSequence.createFlattened(p1, p2);
+        JsonParserSequence seq = JsonParserSequence.createFlattened(false, p1, p2);
         assertEquals(2, seq.containedParsersCount());
 
         assertFalse(p1.isClosed());
@@ -47,19 +47,49 @@
     }
 
     // for [jackson-core#296]
-    public void testInitialized() throws Exception
+    public void testInitializationDisabled() throws Exception
     {
-        JsonParser p1 = JSON_FACTORY.createParser("1 2");
-        JsonParser p2 = JSON_FACTORY.createParser("3 false");
-        // consume '1', move to '2'
-        assertToken(JsonToken.VALUE_NUMBER_INT, p1.nextToken());
-        assertToken(JsonToken.VALUE_NUMBER_INT, p1.nextToken());
+        // // First, with old legacy settings
 
-        JsonParserSequence seq = JsonParserSequence.createFlattened(p1, p2);
+        JsonParser p1 = JSON_FACTORY.createParser("1 2");
+        JsonParser p2 = JSON_FACTORY.createParser("3 true");
+        assertToken(JsonToken.VALUE_NUMBER_INT, p1.nextToken());
+        assertEquals(1, p1.getIntValue());
+        assertToken(JsonToken.VALUE_NUMBER_INT, p2.nextToken());
+        assertEquals(3, p2.getIntValue());
+
+        // with legacy settings, will see neither '1' nor '3'
+        
+        JsonParserSequence seq = JsonParserSequence.createFlattened(false, p1, p2);
+        assertToken(JsonToken.VALUE_NUMBER_INT, seq.nextToken());
+        assertEquals(2, seq.getIntValue());
+        assertToken(JsonToken.VALUE_TRUE, seq.nextToken());
+        assertNull(seq.nextToken());
+        seq.close();
+    }
+
+    // for [jackson-core#296]
+    public void testInitializationEnabled() throws Exception
+    {
+        // // and then with new "check for current":
+        JsonParser p1 = JSON_FACTORY.createParser("1 2");
+        JsonParser p2 = JSON_FACTORY.createParser("3 true");
+        assertToken(JsonToken.VALUE_NUMBER_INT, p1.nextToken());
+        assertEquals(1, p1.getIntValue());
+        assertToken(JsonToken.VALUE_NUMBER_INT, p2.nextToken());
+        assertEquals(3, p2.getIntValue());
+
+        // with new settings, both '1' and '3' will be visible
+        
+        JsonParserSequence seq = JsonParserSequence.createFlattened(true, p1, p2);
+        assertToken(JsonToken.VALUE_NUMBER_INT, seq.nextToken());
+        assertEquals(1, seq.getIntValue());
         assertToken(JsonToken.VALUE_NUMBER_INT, seq.nextToken());
         assertEquals(2, seq.getIntValue());
         assertToken(JsonToken.VALUE_NUMBER_INT, seq.nextToken());
         assertEquals(3, seq.getIntValue());
+        assertToken(JsonToken.VALUE_TRUE, seq.nextToken());
+        assertNull(seq.nextToken());
         seq.close();
     }
 }