Misc additions, unit tests, starting to add JsonParser.peekNextToken()

diff --git a/src/java/org/codehaus/jackson/JsonParser.java b/src/java/org/codehaus/jackson/JsonParser.java
index 626724a..6d4f4f9 100644
--- a/src/java/org/codehaus/jackson/JsonParser.java
+++ b/src/java/org/codehaus/jackson/JsonParser.java
@@ -222,9 +222,9 @@
     };
 
     /*
-    /***************************************************
+    /**********************************************************
     /* Minimal configuration state
-    /***************************************************
+    /**********************************************************
      */
 
     /**
@@ -235,9 +235,9 @@
     protected int _features;
 
     /*
-    /***************************************************
+    /**********************************************************
     /* Minimal generic state
-    /***************************************************
+    /**********************************************************
      */
 
     /**
@@ -255,9 +255,9 @@
     protected JsonToken _lastClearedToken;
 
     /*
-    /***************************************************
+    /**********************************************************
     /* Construction, init
-    /***************************************************
+    /**********************************************************
      */
 
     protected JsonParser() { }
@@ -281,9 +281,9 @@
     public abstract void setCodec(ObjectCodec c);
 
     /*
-    /***************************************************
+    /**********************************************************
     /* Closeable implementation
-    /***************************************************
+    /**********************************************************
      */
 
     /**
@@ -377,9 +377,9 @@
 
 
     /*
-    /***************************************************
+    /**********************************************************
     /* Public API, traversal
-    /***************************************************
+    /**********************************************************
      */
 
     /**
@@ -454,10 +454,34 @@
      */
     public abstract boolean isClosed();
 
+    /**
+     * Method that may be optionally implemented by parser; and if
+     * so, allows determining type of token following current token,
+     * but without losing information about current token.
+     * If method is not supported, will return
+     * {@link JsonToken#NOT_AVAILABLE}; otherwise either type of
+     * next token, or null to indicate end-of-document.
+     *<p>
+     * Note: for incremental/lazy parsers this method will force
+     * loading of all data for the current token.
+     *
+     * @return Type of token following current token if peeking
+     *   is possible; {@link JsonToken#NOT_AVAILABLE} if not (or
+     *   parser does not implement this method); or null if
+     *   peek indicates end of document.
+     *   
+     * @since 1.6
+     */
+    public JsonToken peekNextToken()
+        throws IOException, JsonParseException
+    {
+        return JsonToken.NOT_AVAILABLE;
+    }
+    
     /*
-    /***************************************************
+    /**********************************************************
     /* Public API, token accessors
-    /***************************************************
+    /**********************************************************
      */
 
     /**
@@ -557,9 +581,9 @@
     }
 
     /*
-    /***************************************************
+    /**********************************************************
     /* Public API, access to token information, text
-    /***************************************************
+    /**********************************************************
      */
 
     /**
@@ -622,9 +646,9 @@
         throws IOException, JsonParseException;
 
     /*
-    /***************************************************
+    /**********************************************************
     /* Public API, access to token information, numeric
-    /***************************************************
+    /**********************************************************
      */
 
     /**
@@ -816,9 +840,9 @@
     }
 
     /*
-    /***************************************************
+    /**********************************************************
     /* Public API, access to token information, binary
-    /***************************************************
+    /**********************************************************
      */
 
     /**
@@ -856,9 +880,9 @@
     }
 
     /*
-    /***************************************************
+    /**********************************************************
     /* Public API, optional data binding functionality
-    /***************************************************
+    /**********************************************************
      */
 
     /**
@@ -925,9 +949,9 @@
     }
 
     /**
-     * Method to deserialize Json content into equivalent "tree model",
+     * Method to deserialize JSON content into equivalent "tree model",
      * represented by root {@link JsonNode} of resulting model.
-     * For Json Arrays it will an array node (with child nodes),
+     * For JSON Arrays it will an array node (with child nodes),
      * for objects object node (with child nodes), and for other types
      * matching leaf node type
      */
@@ -942,9 +966,9 @@
     }
 
     /*
-    /***************************************************
+    /**********************************************************
     /* Internal methods
-    /***************************************************
+    /**********************************************************
      */
 
     /**
diff --git a/src/mapper/java/org/codehaus/jackson/map/deser/BeanDeserializer.java b/src/mapper/java/org/codehaus/jackson/map/deser/BeanDeserializer.java
index b7f06fd..ec1a24c 100644
--- a/src/mapper/java/org/codehaus/jackson/map/deser/BeanDeserializer.java
+++ b/src/mapper/java/org/codehaus/jackson/map/deser/BeanDeserializer.java
@@ -448,7 +448,11 @@
     	        return _delegatingCreator.deserialize(jp, ctxt);
     	    }
     	    // should only occur for abstract types...
-            throw JsonMappingException.from(jp, "No default constructor found for type "+_beanType+": can not instantiate from JSON object (need to add/enable type information?)");
+    	    if (_beanType.isAbstract()) {
+                throw JsonMappingException.from(jp, "Can not instantiate abstract type "+_beanType
+                        +" (need to add/enable type information?)");
+    	    }
+            throw JsonMappingException.from(jp, "No suitable constructor found for type "+_beanType+": can not instantiate from JSON object (need to add/enable type information?)");
         }
 
         Object bean;
diff --git a/src/perf/TestJsonPerf.java b/src/perf/TestJsonPerf.java
index 772660e..f119e90 100644
--- a/src/perf/TestJsonPerf.java
+++ b/src/perf/TestJsonPerf.java
@@ -23,6 +23,8 @@
     
     final ObjectMapper _mapper;
 
+    final ObjectMapper _smileMapper;
+    
     final SmileFactory _smileFactory;
     
     final byte[] _jsonData;
@@ -36,6 +38,7 @@
         _jsonFactory = new JsonFactory();
         _mapper = new ObjectMapper(_jsonFactory);
         _smileFactory = new SmileFactory();
+        _smileMapper = new ObjectMapper(_smileFactory);
         _jsonData = readData(f);
         _smileData = convertToSmile(_jsonData);
 
@@ -55,7 +58,7 @@
         while (true) {
             try {  Thread.sleep(100L); } catch (InterruptedException ie) { }
             // Use 9 to test all...
-            int round = (i++ % 2);
+            int round = (i++ % 1);
 
             long curr = System.currentTimeMillis();
             String msg;
@@ -64,6 +67,17 @@
             switch (round) {
 
             case 0:
+                msg = "Smile/data-bind";
+                sum += testJacksonDatabind(_smileMapper, _smileData, REPS);
+                break;
+
+            case 1:
+                msg = "Jackson/data-bind";
+                sum += testJacksonDatabind(_mapper, _jsonData, REPS);
+                break;
+                
+            /*
+            case 0:
                 msg = "Jackson/smile, stream";
                 sum += testJacksonStream(REPS, _smileFactory, _smileData, true);
                 break;
@@ -78,7 +92,7 @@
 
             case 3:
                 msg = "Jackson, Java types";
-                sum += testJacksonJavaTypes(_mapper, REPS);
+                sum += testJacksonDatabind(_mapper, REPS);
                 break;
 
             case 4:
@@ -103,6 +117,7 @@
                 msg = "JSONTools (berlios.de)";
                 sum += testJsonTools(REPS);
                 break;
+                */
             default:
                 throw new Error("Internal error");
             }
@@ -291,23 +306,23 @@
         return sum;
     }
 
-    private int testJacksonJavaTypes(ObjectMapper mapper, int reps)
+    private int testJacksonDatabind(ObjectMapper mapper, byte[] data, int reps)
         throws Exception
     {
         Object ob = null;
         for (int i = 0; i < reps; ++i) {
             // This is "untyped"... Maps, Lists etc
-            ob = mapper.readValue(_jsonData, 0, _jsonData.length, Object.class);
+            ob = mapper.readValue(data, 0, data.length, Object.class);
         }
         return ob.hashCode(); // just to get some non-optimizable number
     }
 
-    private int testJacksonJsonTypes(ObjectMapper mapper, int reps)
+    private int testJacksonTree(ObjectMapper mapper, byte[] data, int reps)
         throws Exception
     {
         Object ob = null;
         for (int i = 0; i < reps; ++i) {
-            ob = mapper.readValue(_jsonData, 0, _jsonData.length, JsonNode.class);
+            ob = mapper.readValue(data, 0, data.length, JsonNode.class);
         }
         return ob.hashCode(); // just to get some non-optimizable number
     }
diff --git a/src/smile/test/org/codehaus/jackson/smile/TestSmileParser.java b/src/smile/test/org/codehaus/jackson/smile/TestSmileParser.java
index 709f6cc..2f7d5e8 100644
--- a/src/smile/test/org/codehaus/jackson/smile/TestSmileParser.java
+++ b/src/smile/test/org/codehaus/jackson/smile/TestSmileParser.java
@@ -240,6 +240,30 @@
         assertToken(JsonToken.END_ARRAY, p.nextToken());
         assertNull(p.nextToken());
         p.close();
+
+        // and then let's create longer text segment as well
+        StringBuilder sb = new StringBuilder();
+        while (sb.length() < 200) {
+            sb.append(uc);
+        }
+        final String longer = sb.toString();
+        data = _smileDoc("["+quote(longer)+"]");
+
+        // Ok once again, first skipping, then accessing
+        p = _parser(data);
+        assertToken(JsonToken.START_ARRAY, p.nextToken());
+        assertToken(JsonToken.VALUE_STRING, p.nextToken());
+        assertToken(JsonToken.END_ARRAY, p.nextToken());
+        assertNull(p.nextToken());
+        p.close();
+
+        p = _parser(data);
+        assertToken(JsonToken.START_ARRAY, p.nextToken());
+        assertToken(JsonToken.VALUE_STRING, p.nextToken());
+        assertEquals(longer, p.getText());
+        assertToken(JsonToken.END_ARRAY, p.nextToken());
+        assertNull(p.nextToken());
+        p.close();
     }
 
     public void testUnicodePropertyNames() throws IOException
diff --git a/src/test/org/codehaus/jackson/map/deser/TestMapDeserialization.java b/src/test/org/codehaus/jackson/map/deser/TestMapDeserialization.java
index f10733f..5113cc8 100644
--- a/src/test/org/codehaus/jackson/map/deser/TestMapDeserialization.java
+++ b/src/test/org/codehaus/jackson/map/deser/TestMapDeserialization.java
@@ -13,9 +13,9 @@
     extends BaseMapTest
 {
     /*
-    ***************************************************
-    * Test classes, enums
-    ***************************************************
+    /**********************************************************
+    /* Test classes, enums
+    /**********************************************************
      */
 
     enum Key {
@@ -48,9 +48,9 @@
     }
     
     /*
-    ***************************************************
-    * Test methods, untyped (Object valued) maps
-    ***************************************************
+    /**********************************************************
+    /* Test methods, untyped (Object valued) maps
+    /**********************************************************
      */
 
     public void testUntypedMap() throws Exception
@@ -158,9 +158,9 @@
     }
 
     /*
-    ***************************************************
-    * Test methods, typed maps
-    ***************************************************
+    /**********************************************************
+    /* Test methods, typed maps
+    /**********************************************************
      */
 
     public void testExactStringIntMap() throws Exception
@@ -246,9 +246,9 @@
     }
 
     /*
-    ***************************************************
-    * Test methods, maps with enums
-    ***************************************************
+    /**********************************************************
+    /* Test methods, maps with enums
+    /**********************************************************
      */
 
     public void testEnumMap() throws Exception
@@ -293,9 +293,9 @@
     }
 
     /*
-    ***************************************************
-    * Test methods, annotated Maps
-    ***************************************************
+    /**********************************************************
+    /* Test methods, annotated Maps
+    /**********************************************************
      */
 
     /**
@@ -311,9 +311,9 @@
     }
 
     /*
-    ////////////////////////////////////////////////////////////
-    // Error tests
-    ////////////////////////////////////////////////////////////
+    /**********************************************************
+    /* Error tests
+    /**********************************************************
      */
 
     public void testMapError() throws Exception