fix a minor regression wrt DataInput-backed parser, eof detection
diff --git a/src/main/java/com/fasterxml/jackson/core/json/UTF8DataInputJsonParser.java b/src/main/java/com/fasterxml/jackson/core/json/UTF8DataInputJsonParser.java
index 6afe1d8..66f96e5 100644
--- a/src/main/java/com/fasterxml/jackson/core/json/UTF8DataInputJsonParser.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/UTF8DataInputJsonParser.java
@@ -2215,7 +2215,7 @@
             try {
                 i = _inputData.readUnsignedByte();
             } catch (EOFException e) {
-                return -1;
+                return _eofAsNextChar();
             }
         } else {
             _nextByte = -1;
@@ -2236,7 +2236,7 @@
             try {
                 i = _inputData.readUnsignedByte();
             } catch (EOFException e) {
-                return -1;
+                return _eofAsNextChar();
             }
         }
     }
diff --git a/src/main/java/com/fasterxml/jackson/core/util/JsonGeneratorDelegate.java b/src/main/java/com/fasterxml/jackson/core/util/JsonGeneratorDelegate.java
index 6641151..f5ee928 100644
--- a/src/main/java/com/fasterxml/jackson/core/util/JsonGeneratorDelegate.java
+++ b/src/main/java/com/fasterxml/jackson/core/util/JsonGeneratorDelegate.java
@@ -364,17 +364,17 @@
      */
     
     @Override
-    public void writeObject(Object pojo) throws IOException,JsonProcessingException {
+    public void writeObject(Object pojo) throws IOException {
         if (delegateCopyMethods) {
             delegate.writeObject(pojo);
             return;
         }
-        // NOTE: copied from 
         if (pojo == null) {
             writeNull();
         } else {
-            if (getCodec() != null) {
-                getCodec().writeValue(this, pojo);
+            ObjectCodec c = getCodec();
+            if (c != null) {
+                c.writeValue(this, pojo);
                 return;
             }
             _writeSimpleObject(pojo);
@@ -382,19 +382,20 @@
     }
     
     @Override
-    public void writeTree(TreeNode rootNode) throws IOException {
+    public void writeTree(TreeNode tree) throws IOException {
         if (delegateCopyMethods) {
-            delegate.writeTree(rootNode);
+            delegate.writeTree(tree);
             return;
         }
         // As with 'writeObject()', we are not check if write would work
-        if (rootNode == null) {
+        if (tree == null) {
             writeNull();
         } else {
-            if (getCodec() == null) {
+            ObjectCodec c = getCodec();
+            if (c == null) {
                 throw new IllegalStateException("No ObjectCodec defined");
             }
-            getCodec().writeValue(this, rootNode);
+            c.writeTree(this, tree);
         }
     }
 
@@ -413,15 +414,15 @@
      */
 
     @Override
-    public void copyCurrentEvent(JsonParser jp) throws IOException {
-        if (delegateCopyMethods) delegate.copyCurrentEvent(jp);
-        else super.copyCurrentEvent(jp);
+    public void copyCurrentEvent(JsonParser p) throws IOException {
+        if (delegateCopyMethods) delegate.copyCurrentEvent(p);
+        else super.copyCurrentEvent(p);
     }
 
     @Override
-    public void copyCurrentStructure(JsonParser jp) throws IOException {
-        if (delegateCopyMethods) delegate.copyCurrentStructure(jp);
-        else super.copyCurrentStructure(jp);
+    public void copyCurrentStructure(JsonParser p) throws IOException {
+        if (delegateCopyMethods) delegate.copyCurrentStructure(p);
+        else super.copyCurrentStructure(p);
     }
 
     /*
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 85363f4..955d3d5 100644
--- a/src/test/java/com/fasterxml/jackson/core/json/ParserSequenceTest.java
+++ b/src/test/java/com/fasterxml/jackson/core/json/ParserSequenceTest.java
@@ -46,6 +46,31 @@
         seq.close();
     }
 
+    public void testMultiLevel() throws Exception
+    {
+        JsonParser p1 = JSON_FACTORY.createParser("[ 1 ] ");
+        JsonParser p2 = JSON_FACTORY.createParser(" 5");
+        JsonParser p3 = JSON_FACTORY.createParser(" { } ");
+        JsonParserSequence seq1 = JsonParserSequence.createFlattened(true, p1, p2);
+        JsonParserSequence seq = JsonParserSequence.createFlattened(false, seq1, p3);
+        assertEquals(3, seq.containedParsersCount());
+
+        assertToken(JsonToken.START_ARRAY, seq.nextToken());
+        assertToken(JsonToken.VALUE_NUMBER_INT, seq.nextToken());
+        assertToken(JsonToken.END_ARRAY, seq.nextToken());
+
+        assertToken(JsonToken.VALUE_NUMBER_INT, seq.nextToken());
+        
+        assertToken(JsonToken.START_OBJECT, seq.nextToken());
+        assertToken(JsonToken.END_OBJECT, seq.nextToken());
+
+        assertNull(seq.nextToken());
+        assertTrue(p1.isClosed());
+        assertTrue(p2.isClosed());
+        assertTrue(p3.isClosed());
+        assertTrue(seq.isClosed());
+    }
+    
     // for [jackson-core#296]
     public void testInitializationDisabled() throws Exception
     {
diff --git a/src/test/java/com/fasterxml/jackson/core/read/ParserScopeMatchingTest.java b/src/test/java/com/fasterxml/jackson/core/read/ParserScopeMatchingTest.java
index 55c261c..fbe42fc 100644
--- a/src/test/java/com/fasterxml/jackson/core/read/ParserScopeMatchingTest.java
+++ b/src/test/java/com/fasterxml/jackson/core/read/ParserScopeMatchingTest.java
@@ -25,20 +25,14 @@
         assertToken(JsonToken.START_ARRAY, p.nextToken());
         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
         assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
+        assertEquals(2, p.getIntValue());
 
         try {
             p.nextToken();
+            fail("Expected an exception for unclosed ARRAY (mode: "+mode+")");
         } catch (JsonParseException pe) {
             verifyException(pe, "expected close marker for ARRAY");
-            return;
-        } catch (IOException ie) {
-            // DataInput behaves bit differently
-            if (mode == MODE_DATA_INPUT) {
-                verifyException(ie, "end-of-input");
-                return;
-            }
         }
-        fail("Expected an exception for unclosed ARRAY");
     }
 
     public void testUnclosedObject() throws Exception
@@ -57,15 +51,9 @@
 
         try {
             p.nextToken();
-            fail("Expected an exception for unclosed OBJECT");
+            fail("Expected an exception for unclosed OBJECT (mode: "+mode+")");
         } catch (JsonParseException pe) {
             verifyException(pe, "expected close marker for OBJECT");
-        } catch (IOException ie) {
-            // DataInput behaves bit differently
-            if (mode == MODE_DATA_INPUT) {
-                verifyException(ie, "end-of-input");
-                return;
-            }
         }
     }
 
diff --git a/src/test/java/com/fasterxml/jackson/core/type/TypeReferenceTest.java b/src/test/java/com/fasterxml/jackson/core/type/TypeReferenceTest.java
index 1bf326b..4dd70d0 100644
--- a/src/test/java/com/fasterxml/jackson/core/type/TypeReferenceTest.java
+++ b/src/test/java/com/fasterxml/jackson/core/type/TypeReferenceTest.java
@@ -7,6 +7,122 @@
 // Not much to test, but exercise to prevent code coverage tool from showing all red for package
 public class TypeReferenceTest extends BaseTest
 {
+    static class BogusResolvedType extends ResolvedType {
+        private final boolean _refType;
+
+        public BogusResolvedType(boolean isRefType) {
+            _refType = isRefType;
+        }
+
+        @Override
+        public Class<?> getRawClass() {
+            return null;
+        }
+
+        @Override
+        public boolean hasRawClass(Class<?> clz) {
+            return false;
+        }
+
+        @Override
+        public boolean isAbstract() {
+            return false;
+        }
+
+        @Override
+        public boolean isConcrete() {
+            return false;
+        }
+
+        @Override
+        public boolean isThrowable() {
+            return false;
+        }
+
+        @Override
+        public boolean isArrayType() {
+            return false;
+        }
+
+        @Override
+        public boolean isEnumType() {
+            return false;
+        }
+
+        @Override
+        public boolean isInterface() {
+            return false;
+        }
+
+        @Override
+        public boolean isPrimitive() {
+            return false;
+        }
+
+        @Override
+        public boolean isFinal() {
+            return false;
+        }
+
+        @Override
+        public boolean isContainerType() {
+            return false;
+        }
+
+        @Override
+        public boolean isCollectionLikeType() {
+            return false;
+        }
+
+        @Override
+        public boolean isMapLikeType() {
+            return false;
+        }
+
+        @Override
+        public boolean hasGenericTypes() {
+            return false;
+        }
+
+        @Override
+        public ResolvedType getKeyType() {
+            return null;
+        }
+
+        @Override
+        public ResolvedType getContentType() {
+            return null;
+        }
+
+        @Override
+        public ResolvedType getReferencedType() {
+            if (_refType) {
+                return this;
+            }
+            return null;
+        }
+
+        @Override
+        public int containedTypeCount() {
+            return 0;
+        }
+
+        @Override
+        public ResolvedType containedType(int index) {
+            return null;
+        }
+
+        @Override
+        public String containedTypeName(int index) {
+            return null;
+        }
+
+        @Override
+        public String toCanonical() {
+            return null;
+        }
+    }
+    
     public void testSimple()
     {
         TypeReference<?> ref = new TypeReference<List<String>>() { };
@@ -24,4 +140,11 @@
             verifyException(e, "without actual type information");
         }
     }
+
+    public void testResolvedType() {
+        ResolvedType type1 = new BogusResolvedType(false);
+        assertFalse(type1.isReferenceType());
+        ResolvedType type2 = new BogusResolvedType(true);
+        assertTrue(type2.isReferenceType());
+    }
 }
diff --git a/src/test/java/com/fasterxml/jackson/core/util/TestDelegates.java b/src/test/java/com/fasterxml/jackson/core/util/TestDelegates.java
index 8fe7db3..e74d715 100644
--- a/src/test/java/com/fasterxml/jackson/core/util/TestDelegates.java
+++ b/src/test/java/com/fasterxml/jackson/core/util/TestDelegates.java
@@ -1,13 +1,177 @@
 package com.fasterxml.jackson.core.util;
 
 import java.io.*;
+import java.util.Iterator;
 
 import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.core.JsonParser.NumberType;
+import com.fasterxml.jackson.core.type.ResolvedType;
+import com.fasterxml.jackson.core.type.TypeReference;
 
 public class TestDelegates extends com.fasterxml.jackson.core.BaseTest
 {
+    static class POJO {
+        public int x = 3;
+    }
+
+    static class BogusCodec extends ObjectCodec
+    {
+        public Object pojoWritten;
+        public TreeNode treeWritten;
+
+        @Override
+        public Version version() {
+            return Version.unknownVersion();
+        }
+
+        @Override
+        public <T> T readValue(JsonParser p, Class<T> valueType) {
+            return null;
+        }
+        @Override
+        public <T> T readValue(JsonParser p, TypeReference<?> valueTypeRef) {
+            return null;
+        }
+        @Override
+        public <T> T readValue(JsonParser p, ResolvedType valueType) {
+            return null;
+        }
+        @Override
+        public <T> Iterator<T> readValues(JsonParser p, Class<T> valueType) {
+            return null;
+        }
+        @Override
+        public <T> Iterator<T> readValues(JsonParser p,
+                TypeReference<?> valueTypeRef) throws IOException {
+            return null;
+        }
+        @Override
+        public <T> Iterator<T> readValues(JsonParser p, ResolvedType valueType) {
+            return null;
+        }
+        @Override
+        public void writeValue(JsonGenerator gen, Object value) throws IOException {
+            gen.writeString("pojo");
+            pojoWritten = value;
+        }
+
+        @Override
+        public <T extends TreeNode> T readTree(JsonParser p) {
+            return null;
+        }
+        @Override
+        public void writeTree(JsonGenerator gen, TreeNode tree) throws IOException {
+            gen.writeString("tree");
+            treeWritten = tree;
+        }
+
+        @Override
+        public TreeNode createObjectNode() {
+            return null;
+        }
+        @Override
+        public TreeNode createArrayNode() {
+            return null;
+        }
+        @Override
+        public JsonParser treeAsTokens(TreeNode n) {
+            return null;
+        }
+        @Override
+        public <T> T treeToValue(TreeNode n, Class<T> valueType) {
+            return null;
+        } 
+    }
+
+    static class BogusTree implements TreeNode {
+        @Override
+        public JsonToken asToken() {
+            return null;
+        }
+
+        @Override
+        public NumberType numberType() {
+            return null;
+        }
+
+        @Override
+        public int size() {
+            return 0;
+        }
+
+        @Override
+        public boolean isValueNode() {
+            return false;
+        }
+
+        @Override
+        public boolean isContainerNode() {
+            return false;
+        }
+
+        @Override
+        public boolean isMissingNode() {
+            return false;
+        }
+
+        @Override
+        public boolean isArray() {
+            return false;
+        }
+
+        @Override
+        public boolean isObject() {
+            return false;
+        }
+
+        @Override
+        public TreeNode get(String fieldName) {
+            return null;
+        }
+
+        @Override
+        public TreeNode get(int index) {
+            return null;
+        }
+
+        @Override
+        public TreeNode path(String fieldName) {
+            return null;
+        }
+
+        @Override
+        public TreeNode path(int index) {
+            return null;
+        }
+
+        @Override
+        public Iterator<String> fieldNames() {
+            return null;
+        }
+
+        @Override
+        public TreeNode at(JsonPointer ptr) {
+            return null;
+        }
+
+        @Override
+        public TreeNode at(String jsonPointerExpression) {
+            return null;
+        }
+
+        @Override
+        public JsonParser traverse() {
+            return null;
+        }
+
+        @Override
+        public JsonParser traverse(ObjectCodec codec) {
+            return null;
+        }
+    }
+
     private final JsonFactory JSON_F = new JsonFactory();
-    
+
     /**
      * Test default, non-overridden parser delegate.
      */
@@ -94,7 +258,7 @@
         StringWriter sw = new StringWriter();
         JsonGenerator jg = new JsonGeneratorDelegate(JSON_F.createGenerator(sw), false) {
             @Override
-            public void writeFieldName(String name) throws IOException, JsonGenerationException {
+            public void writeFieldName(String name) throws IOException {
                 super.writeFieldName(name+"-test");
                 super.writeBoolean(true);
                 super.writeFieldName(name);
@@ -107,4 +271,26 @@
         jp.close();
         jg.close();
     }
+
+    @SuppressWarnings("resource")
+    public void testGeneratorWithCodec() throws IOException
+    {
+        BogusCodec codec = new BogusCodec();
+        StringWriter sw = new StringWriter();
+        JsonGenerator g0 = JSON_F.createGenerator(sw);
+        g0.setCodec(codec);
+        JsonGeneratorDelegate del = new JsonGeneratorDelegate(g0, false);
+        del.writeStartArray();
+        POJO pojo = new POJO();
+        del.writeObject(pojo);
+        TreeNode tree = new BogusTree();
+        del.writeTree(tree);
+        del.writeEndArray();
+        del.close();
+
+        assertEquals("[\"pojo\",\"tree\"]", sw.toString());
+
+        assertSame(tree, codec.treeWritten);
+        assertSame(pojo, codec.pojoWritten);
+    }
 }
diff --git a/src/test/java/com/fasterxml/jackson/core/util/TestTextBuffer.java b/src/test/java/com/fasterxml/jackson/core/util/TestTextBuffer.java
index ab1d23a..997a7cb 100644
--- a/src/test/java/com/fasterxml/jackson/core/util/TestTextBuffer.java
+++ b/src/test/java/com/fasterxml/jackson/core/util/TestTextBuffer.java
@@ -13,6 +13,9 @@
         tb.append('a');
         tb.append(new char[] { 'X', 'b' }, 1, 1);
         tb.append("c", 0, 1);
+        // all fits within one buffer so it is efficient...
+        assertTrue(tb.hasTextAsCharacters());
+
         assertEquals(3, tb.contentsAsArray().length);
         assertEquals("abc", tb.toString());
 
@@ -21,7 +24,7 @@
 
     public void testLonger()
     {
-        TextBuffer tb = new TextBuffer(new BufferRecycler());
+        TextBuffer tb = new TextBuffer(null);
         for (int i = 0; i < 2000; ++i) {
             tb.append("abc", 0, 3);
         }
@@ -31,51 +34,54 @@
 
         tb.resetWithShared(new char[] { 'a' }, 0, 1);
         assertEquals(1, tb.toString().length());
+        assertTrue(tb.hasTextAsCharacters());
     }
 
-      public void testLongAppend()
-      {
-          final int len = TextBuffer.MAX_SEGMENT_LEN * 3 / 2;
-          StringBuilder sb = new StringBuilder(len);
-          for (int i = 0; i < len; ++i) {
-              sb.append('x');
-          }
-         final String STR = sb.toString();
-         final String EXP = "a" + STR + "c";
+    public void testLongAppend()
+    {
+        final int len = TextBuffer.MAX_SEGMENT_LEN * 3 / 2;
+        StringBuilder sb = new StringBuilder(len);
+        for (int i = 0; i < len; ++i) {
+            sb.append('x');
+        }
+        final String STR = sb.toString();
+        final String EXP = "a" + STR + "c";
  
-         // ok: first test with String:
-         TextBuffer tb = new TextBuffer(new BufferRecycler());
-         tb.append('a');
-         tb.append(STR, 0, len);
-         tb.append('c');
-         assertEquals(len+2, tb.size());
-         assertEquals(EXP, tb.contentsAsString());
+        // ok: first test with String:
+        TextBuffer tb = new TextBuffer(new BufferRecycler());
+        tb.append('a');
+        tb.append(STR, 0, len);
+        tb.append('c');
+        assertEquals(len+2, tb.size());
+        assertEquals(EXP, tb.contentsAsString());
  
-         // then char[]
-         tb = new TextBuffer(new BufferRecycler());
-         tb.append('a');
-         tb.append(STR.toCharArray(), 0, len);
-         tb.append('c');
-         assertEquals(len+2, tb.size());
-         assertEquals(EXP, tb.contentsAsString());
-      }
+        // then char[]
+        tb = new TextBuffer(new BufferRecycler());
+        tb.append('a');
+        tb.append(STR.toCharArray(), 0, len);
+        tb.append('c');
+        assertEquals(len+2, tb.size());
+        assertEquals(EXP, tb.contentsAsString());
+    }
 
-      // [Core#152]
-      public void testExpand()
-      {
-          TextBuffer tb = new TextBuffer(new BufferRecycler());
-          char[] buf = tb.getCurrentSegment();
+    // [core#152]
+    public void testExpand()
+    {
+        TextBuffer tb = new TextBuffer(new BufferRecycler());
+        char[] buf = tb.getCurrentSegment();
 
-          while (buf.length < 500 * 1000) {
-              char[] old = buf;
-              buf = tb.expandCurrentSegment();
-              if (old.length >= buf.length) {
-                  fail("Expected buffer of "+old.length+" to expand, did not, length now "+buf.length);
-              }
-          }
-      }
+        while (buf.length < 500 * 1000) {
+            char[] old = buf;
+            buf = tb.expandCurrentSegment();
+            if (old.length >= buf.length) {
+                fail("Expected buffer of "+old.length+" to expand, did not, length now "+buf.length);
+            }
+        }
+        tb.resetWithString("Foobar");
+        assertEquals("Foobar", tb.contentsAsString());
+    }
 
-    // [Core#182]
+    // [core#182]
     public void testEmpty() {
         TextBuffer tb = new TextBuffer(new BufferRecycler());
         tb.resetWithEmpty();