backporting changes from master to the JSON_P-1.0 branch

fixes: #21
txs to jgallimore for the patch!
Applied with slight changes.

This includes the following tickets, and likely a few more:
JOHNZON-156
JOHNZON-142
JOHNZON-135
JOHNZON-133
JOHNZON-123

For more history please analyse the master branch for the original changes.


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/76fe13de
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/76fe13de
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/76fe13de

Branch: refs/heads/maintenance_1.0.x
Commit: 76fe13de8c50783613fb33ddaaa2838cdff77fc7
Parents: d344cbc
Author: Mark Struberg <[email protected]>
Authored: Fri May 4 21:33:18 2018 +0200
Committer: Mark Struberg <[email protected]>
Committed: Fri May 4 21:33:18 2018 +0200

----------------------------------------------------------------------
 KEYS                                            |  46 +++
 NOTICE                                          |   2 +-
 johnzon-core/pom.xml                            |  17 +-
 .../johnzon/core/AbstractJsonFactory.java       |   4 +-
 .../core/CommentsJsonStreamParserImpl.java      |  15 +-
 .../apache/johnzon/core/JohnzonJsonParser.java  |  97 +++++
 .../johnzon/core/JohnzonJsonParserImpl.java     |  31 ++
 .../johnzon/core/JsonArrayBuilderImpl.java      |  15 +-
 .../org/apache/johnzon/core/JsonArrayImpl.java  |   3 +-
 .../johnzon/core/JsonBuilderFactoryImpl.java    |   2 +
 .../org/apache/johnzon/core/JsonDoubleImpl.java |  19 +-
 .../apache/johnzon/core/JsonGeneratorImpl.java  |  36 +-
 .../apache/johnzon/core/JsonInMemoryParser.java |  28 +-
 .../org/apache/johnzon/core/JsonLongImpl.java   |  11 +-
 .../org/apache/johnzon/core/JsonNumberImpl.java |  16 +-
 .../johnzon/core/JsonObjectBuilderImpl.java     |  20 +-
 .../org/apache/johnzon/core/JsonObjectImpl.java |  12 +-
 .../johnzon/core/JsonParserFactoryImpl.java     |  42 ++-
 .../apache/johnzon/core/JsonPointerUtil.java    |  49 +++
 .../apache/johnzon/core/JsonProviderImpl.java   |   4 +-
 .../org/apache/johnzon/core/JsonReaderImpl.java | 110 ++++--
 .../johnzon/core/JsonStreamParserImpl.java      | 123 +++++--
 .../org/apache/johnzon/core/JsonWriterImpl.java |  36 +-
 .../core/RFC4627AwareInputStreamReader.java     |  36 +-
 .../org/apache/johnzon/core/SimpleStack.java    |   4 +-
 .../apache/johnzon/core/BrokenDefaultTest.java  | 107 ++++++
 .../johnzon/core/JsonArrayBuilderImplTest.java  |   1 +
 .../apache/johnzon/core/JsonArrayImplTest.java  |   8 +
 .../johnzon/core/JsonBuilderFactoryTest.java    |  44 +++
 .../johnzon/core/JsonGeneratorImplTest.java     |  14 +
 .../org/apache/johnzon/core/JsonNumberTest.java |  55 ++-
 .../johnzon/core/JsonObjectBuilderImplTest.java |  18 +-
 .../apache/johnzon/core/JsonObjectImplTest.java |  17 +
 .../org/apache/johnzon/core/JsonParserTest.java |   9 +-
 .../apache/johnzon/core/JsonReaderImplTest.java |  32 +-
 .../org/apache/johnzon/core/OverflowTest.java   |  88 +++++
 .../test/resources/json/jsonPointerTest.json    |  15 +
 johnzon-distribution/pom.xml                    |   7 +-
 .../jaxrs/ConfigurableJohnzonProvider.java      |  35 ++
 .../johnzon/jaxrs/JohnzonMessageBodyReader.java |   6 +-
 .../johnzon/jaxrs/JohnzonMessageBodyWriter.java |  12 +-
 .../WildcardConfigurableJohnzonProvider.java    |  39 +-
 .../johnzon/jaxrs/JohnzonProviderTest.java      |  82 +++--
 johnzon-jsonb/pom.xml                           |  40 +-
 .../jaxrs/jsonb/jaxrs/JsonbJaxrsProvider.java   | 157 ++++++--
 .../org/apache/johnzon/jsonb/JohnsonJsonb.java  | 368 -------------------
 .../apache/johnzon/jsonb/JohnzonBuilder.java    | 282 ++++++++++----
 .../org/apache/johnzon/jsonb/JohnzonJsonb.java  | 368 +++++++++++++++++++
 .../apache/johnzon/jsonb/JsonbAccessMode.java   | 111 ++++--
 .../java/org/apache/johnzon/jsonb/cdi/CDIs.java |  10 +-
 .../johnzon/jsonb/cdi/JohnzonCdiExtension.java  |   8 +-
 .../jsonb/converter/JohnzonJsonbAdapter.java    |  14 +-
 .../org/apache/johnzon/jsonb/AdapterTest.java   |  20 +-
 .../johnzon/jsonb/AnnotationOrderTest.java      |  77 ++++
 .../apache/johnzon/jsonb/CdiAdapterTest.java    |   4 +-
 .../johnzon/jsonb/ClassConverterTest.java       |   2 +-
 .../jsonb/CustomParameterizedTypeTest.java      | 104 ++++++
 .../johnzon/jsonb/DefaultMappingTest.java       |   6 +-
 .../jsonb/DynamicBufferResizingTest.java        |  93 +++++
 .../jsonb/FailOnUnknownPropertiesTest.java      |  56 +++
 .../jsonb/JohnzonConverterInJsonbTest.java      | 134 +++++++
 .../johnzon/jsonb/JohnzonIgnoreNestedTest.java  |  65 ++++
 .../org/apache/johnzon/jsonb/JsonbReadTest.java |  81 ++++
 .../apache/johnzon/jsonb/JsonbTypesTest.java    | 134 ++++++-
 .../apache/johnzon/jsonb/JsonbWriteTest.java    |  45 +++
 .../johnzon/jsonb/ObjectSerializationTest.java  |  77 ++++
 .../apache/johnzon/jsonb/SerializerTest.java    |  24 +-
 .../johnzon/jsonb/jaxrs/JsonbJaxRsTest.java     |  41 ++-
 johnzon-mapper/pom.xml                          |  14 +
 .../mapper/JohnzonDeduplicateObjects.java       |  39 ++
 .../johnzon/mapper/JohnzonIgnoreNested.java     |  39 ++
 .../java/org/apache/johnzon/mapper/Mapper.java  | 135 +++++--
 .../apache/johnzon/mapper/MapperBuilder.java    |  68 +++-
 .../org/apache/johnzon/mapper/MapperConfig.java |  42 ++-
 .../johnzon/mapper/MappingGeneratorImpl.java    | 155 +++++---
 .../johnzon/mapper/MappingParserImpl.java       | 220 +++++++----
 .../org/apache/johnzon/mapper/Mappings.java     |  86 +++--
 .../johnzon/mapper/SerializeValueFilter.java    |  28 ++
 .../johnzon/mapper/access/AccessMode.java       |   1 +
 .../johnzon/mapper/access/BaseAccessMode.java   | 106 +-----
 .../johnzon/mapper/access/FieldAccessMode.java  |  25 +-
 .../johnzon/mapper/access/MethodAccessMode.java |  18 +-
 .../mapper/internal/JsonPointerTracker.java     |  71 ++++
 .../johnzon/mapper/reflection/Generics.java     |  97 +++++
 .../apache/johnzon/core/TestBufferProvider.java |   2 +-
 .../johnzon/mapper/CircularObjectsTest.java     | 298 +++++++++++++++
 .../johnzon/mapper/CustomEnumCodecTest.java     |  67 ++++
 .../org/apache/johnzon/mapper/EnumTest.java     |  30 +-
 .../org/apache/johnzon/mapper/GenericsTest.java |  52 +++
 .../johnzon/mapper/JohnzonIgnoreNestedTest.java |  67 ++++
 .../org/apache/johnzon/mapper/LiteralTest.java  |  10 +
 .../apache/johnzon/mapper/MapperConfigTest.java |   2 +-
 .../org/apache/johnzon/mapper/MapperTest.java   |  29 +-
 .../org/apache/johnzon/mapper/NullTest.java     |  71 ++++
 .../ObjectConverterWithAnnotationTest.java      |  33 ++
 .../johnzon/mapper/ObjectSerializationTest.java |  74 ++++
 .../apache/johnzon/mapper/ObjectTypeTest.java   |  47 ++-
 .../mapper/SerializeValueFilterTest.java        |  52 +++
 .../mapper/internal/JsonPointerTrackerTest.java |  39 ++
 .../java/org/superbiz/ExtendMappingTest.java    |   2 +-
 .../src/test/java/org/superbiz/Model.java       |  29 ++
 .../src/test/java/org/superbiz/ModelBase.java   |  34 ++
 .../test/java/org/superbiz/ModelSuperBase.java  |  53 +++
 .../java/org/superbiz/ModelSuperSuperBase.java  |  48 +++
 johnzon-maven-plugin/pom.xml                    |   2 +-
 johnzon-websocket/pom.xml                       |  46 ++-
 .../src/test/resources/arquillian.xml           |   6 +
 jsonb-api/pom.xml                               |  36 --
 jsonb-api/run_sigtest.sh                        |  18 -
 .../src/main/java/javax/json/bind/Jsonb.java    |  51 ---
 .../main/java/javax/json/bind/JsonbBuilder.java |  50 ---
 .../main/java/javax/json/bind/JsonbConfig.java  | 117 ------
 .../java/javax/json/bind/JsonbException.java    |  31 --
 .../javax/json/bind/adapter/JsonbAdapter.java   |  24 --
 .../json/bind/annotation/JsonbAnnotation.java   |  26 --
 .../json/bind/annotation/JsonbCreator.java      |  30 --
 .../json/bind/annotation/JsonbDateFormat.java   |  40 --
 .../json/bind/annotation/JsonbNillable.java     |  31 --
 .../json/bind/annotation/JsonbNumberFormat.java |  40 --
 .../json/bind/annotation/JsonbProperty.java     |  35 --
 .../bind/annotation/JsonbPropertyOrder.java     |  31 --
 .../json/bind/annotation/JsonbTransient.java    |  32 --
 .../json/bind/annotation/JsonbTypeAdapter.java  |  32 --
 .../bind/annotation/JsonbTypeDeserializer.java  |  36 --
 .../bind/annotation/JsonbTypeSerializer.java    |  36 --
 .../json/bind/annotation/JsonbVisibility.java   |  34 --
 .../json/bind/config/BinaryDataStrategy.java    |  29 --
 .../bind/config/PropertyNamingStrategy.java     |  30 --
 .../json/bind/config/PropertyOrderStrategy.java |  29 --
 .../bind/config/PropertyVisibilityStrategy.java |  27 --
 .../bind/serializer/DeserializationContext.java |  31 --
 .../json/bind/serializer/JsonbDeserializer.java |  30 --
 .../json/bind/serializer/JsonbSerializer.java   |  25 --
 .../bind/serializer/SerializationContext.java   |  27 --
 .../java/javax/json/bind/spi/JsonbProvider.java |  59 ---
 pom.xml                                         | 217 +++++------
 src/site/markdown/download.md                   |  93 +++++
 src/site/markdown/index.md                      |  21 +-
 src/site/site.xml                               |   2 +-
 139 files changed, 5051 insertions(+), 2224 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/KEYS
----------------------------------------------------------------------
diff --git a/KEYS b/KEYS
index 1624147..3a40b1c 100644
--- a/KEYS
+++ b/KEYS
@@ -552,3 +552,49 @@ zxrmkygs1IMB6Q==
 =8P8F
 -----END PGP PUBLIC KEY BLOCK-----
 
+pub   2048D/2678363C 2016-09-22
+uid                  Romain Manni-Bucau <[email protected]>
+sig 3        2678363C 2016-09-22  Romain Manni-Bucau <[email protected]>
+sub   2048g/25FC7483 2016-09-22
+sig          2678363C 2016-09-22  Romain Manni-Bucau <[email protected]>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mQMuBFfj3GARCACZnUOt5zI4juSDnIAkh7JvRsEZ2MkmhcxsUXHvruTxxJmdecV1
+YZdN6pdSl7LUCNhPv+I4v+Hl6fRtRcGmiRWV489PjyDKFbBL+C/DU2NtpGfmrP1t
++GKR6G/YQjTaJUJNKPMR2aRzB9Bi92y1LdSrF6+mFZ8w6s/XF2hfrLMR7HM3XDi2
+voH0KCmlCIsgKJjWt23t5c+zTH+FUH5jOeOhFw3QqUlTViVErp08/imlNWW0Hg8Y
+tabQRGHiGMFvhdg+JPeMAOzeMPAglo297z8dNI/LKuFN/YbsDp2Aiu0/Tyj9Wp/Q
+RfWa507UP+fsdAlkHBcQ6ko8Q5Kp7DITt2/zAQDDPfNwCDp3K9KHKh/47y1TEnEp
+P5vqGf85BLRKI9uAywf9GQUyQsYobZKgz7tAPz8TAx4j4BJ9D9YmyOcSHnpP5mEf
+t9T3lpYdskk/5ijmRiQUWhQek0Qw+KftCqYotEKmaigk1TDbjdO6aqw2OXsvpidZ
+E7VSKHT7Kc7Ktn7IVX0N0/ssv8gAiWF7metc5xCkhWiM0KwdlhOeKs5DxeRTyvfs
+TKLvEFPl1gs3LHMzHVjjUTkp0eJ/w7OFfNl1mFc+xc9J3w+8RC8bI33IxN1ZxU2L
+dEvFEVkCNl+R2dl6WVUrSRkYMr2ENROaA62kN4DsPFBtx408vbB5+yX7P/iDe4Fx
+b32h0fdz7OOEvco8AljcvJryCOP8yMM+nXQQkwOkTQf9HjUJ3oKnbm7IFxq6cYJg
+3UT1EYcThWYCeMQxp58RuA1ZxXPWhLea4I58U+W9JTyb38AnEFG/0MKK7YpEteu1
+VXrIJJ6+rEBntj5f0yVRdJVKkZDm9FOy6dO6TJmd5wg3F/HadLDtXn5aR3rMudeg
+BOg9/EFYyJLEXvvSsMdk5V7Z07BuG0gsBIRuh9QH0oG/i56tXPNFznylvXhL4K/v
+uNEZhccQlfCzYlGA7kGe6iVNStyApvsUcItrACj2xnlCJS+KNZ/HQvfFkrH8gc1W
+XoNtWNRL290XG82QVIisubMENcluHrXHFOXE64aTzpaxi/x5/81limcETRh8GnrM
+2rQrUm9tYWluIE1hbm5pLUJ1Y2F1IDxybWFubmlidWNhdUBhcGFjaGUub3JnPoh6
+BBMRCAAiBQJX49xgAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRBnwSJ6
+Jng2PADeAQCOQBnAYrM3sVFrfOSLHbpUl9cs+2ZJQR93n04wi16dHQD/eX9IAzix
+YPq6moB4d2pXMxZGvX2KjCTK3LMuDqJH3Xi5Ag0EV+PcYBAIAIeYsSFzYkaIhSE0
+x+UXN3O3hCjp8408ZhAd6N/aeTtSOnyuCMXYQJzFxC+HzGehzG/GB+Gzep78IydM
+TELyyjGWXd/fJ1zEY1VpKEsMStzWQccO0nHMIqIg4w7caJdWpB69Gnmo4vjSvhDw
+d13HKCSf4ypR50YU4qQPumACl/qcBtgiV4hJGasp+93Ua8CP0Yv5h4Llc/Rdd090
+GXbV5kDK2+gryNR1P5BQstmpgIf0AY1LwHQ5+CvjDhn0RZW7EdbAMx6yl9cpTm54
+s68wRp/8Xz4/YahFnfMQoq23DDF3T3ia2VnkLHEudg92RvSw4I0XiSJlrGTjml4w
+aVosMjcAAwUH/RBWGZr7prNHjDd5udf+SUzSa7JG53000z04swi8wWpe/aBYpip5
+GHemgOsJC7P+MFcXYlMUCnJ4/hIzPhYmzy2D1tXgkr/o6EquZCsHl+vtyBXZvAfv
+spVbRDePDe9CvVRQB4PaQz3cNG6yncp2du0E/2EojctdD62vMHhPf1S+2H/BPHXG
+8fWI9dphvaU5g4l1Ah5/cPDptvY/UAC/w7hh7+Fl8Is0xVP5opdeIacvWGUHfcKa
+SvohQwzB9kYJyS5Dru1nTiMNo0RYZ6ANLeWiF+gJHmIqdHE3xPSXOQ+tMFdywRf0
++qVKAsJUd/9f7X8h6o75OyPCl9uFlFY012OIYQQYEQgACQUCV+PcYAIbDAAKCRBn
+wSJ6Jng2POYtAQC5jGmB/Lt2D4Gfp0E6kjWj2U8uXeZCkFCO+uY5ZzKflgEAhrmM
+mfoA5aIoZWJRK1AzuuJ3BKl8ViTAgrhazZ1B+9w=
+=s6vt
+-----END PGP PUBLIC KEY BLOCK-----
+

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
index f44f3b6..cb43ecb 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,5 @@
 Apache Johnzon
-Copyright 2014-2017 The Apache Software Foundation
+Copyright 2014-2018 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-core/pom.xml b/johnzon-core/pom.xml
index 9d0183b..f0a593a 100644
--- a/johnzon-core/pom.xml
+++ b/johnzon-core/pom.xml
@@ -27,9 +27,24 @@
 
   <artifactId>johnzon-core</artifactId>
   <name>Johnzon :: Core</name>
+  <packaging>bundle</packaging>
 
   <properties>
     
<staging.directory>${project.parent.reporting.outputDirectory}</staging.directory>
   </properties>
-  <packaging>bundle</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            
<Require-Capability>osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)"</Require-Capability>
+            
<Provide-Capability>osgi.serviceloader;osgi.serviceloader=javax.json.spi.JsonProvider</Provide-Capability>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/AbstractJsonFactory.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/AbstractJsonFactory.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/AbstractJsonFactory.java
index 4ab42d5..3629293 100644
--- 
a/johnzon-core/src/main/java/org/apache/johnzon/core/AbstractJsonFactory.java
+++ 
b/johnzon-core/src/main/java/org/apache/johnzon/core/AbstractJsonFactory.java
@@ -26,12 +26,12 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.logging.Logger;
 
-public abstract class AbstractJsonFactory implements Serializable{
+public abstract class AbstractJsonFactory implements Serializable {
 
     protected final Logger logger = 
Logger.getLogger(this.getClass().getName());
     
     public static final String BUFFER_STRATEGY = 
"org.apache.johnzon.buffer-strategy";
-    public static final BufferStrategy DEFAULT_BUFFER_STRATEGY = 
BufferStrategy.QUEUE;
+    public static final BufferStrategy DEFAULT_BUFFER_STRATEGY = 
BufferStrategy.valueOf(System.getProperty(BUFFER_STRATEGY, "QUEUE"));
     
     protected final Map<String, Object> internalConfig = new HashMap<String, 
Object>();
     

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/CommentsJsonStreamParserImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/CommentsJsonStreamParserImpl.java
 
b/johnzon-core/src/main/java/org/apache/johnzon/core/CommentsJsonStreamParserImpl.java
index 39e9f1c..f9d298e 100644
--- 
a/johnzon-core/src/main/java/org/apache/johnzon/core/CommentsJsonStreamParserImpl.java
+++ 
b/johnzon-core/src/main/java/org/apache/johnzon/core/CommentsJsonStreamParserImpl.java
@@ -26,23 +26,26 @@ public class CommentsJsonStreamParserImpl extends 
JsonStreamParserImpl {
     public CommentsJsonStreamParserImpl(final InputStream inputStream,
                                         final int maxStringLength,
                                         final 
BufferStrategy.BufferProvider<char[]> bufferProvider,
-                                        final 
BufferStrategy.BufferProvider<char[]> valueBuffer) {
-        super(inputStream, maxStringLength, bufferProvider, valueBuffer);
+                                        final 
BufferStrategy.BufferProvider<char[]> valueBuffer,
+                                        final boolean autoAdjust) {
+        super(inputStream, maxStringLength, bufferProvider, valueBuffer, 
autoAdjust);
     }
 
     public CommentsJsonStreamParserImpl(final InputStream inputStream,
                                         final Charset encoding,
                                         final int maxStringLength,
                                         final 
BufferStrategy.BufferProvider<char[]> bufferProvider,
-                                        final 
BufferStrategy.BufferProvider<char[]> valueBuffer) {
-        super(inputStream, encoding, maxStringLength, bufferProvider, 
valueBuffer);
+                                        final 
BufferStrategy.BufferProvider<char[]> valueBuffer,
+                                        final boolean autoAdjust) {
+        super(inputStream, encoding, maxStringLength, bufferProvider, 
valueBuffer, autoAdjust);
     }
 
     public CommentsJsonStreamParserImpl(final Reader reader,
                                         final int maxStringLength,
                                         final 
BufferStrategy.BufferProvider<char[]> bufferProvider,
-                                        final 
BufferStrategy.BufferProvider<char[]> valueBuffer) {
-        super(reader, maxStringLength, bufferProvider, valueBuffer);
+                                        final 
BufferStrategy.BufferProvider<char[]> valueBuffer,
+                                        final boolean autoAdjust) {
+        super(reader, maxStringLength, bufferProvider, valueBuffer, 
autoAdjust);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParser.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParser.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParser.java
new file mode 100644
index 0000000..b2a55a0
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParser.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.johnzon.core;
+
+import java.math.BigDecimal;
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParser;
+
+/**
+ * JsonParser with extended functionality
+ */
+public interface JohnzonJsonParser extends JsonParser {
+
+    boolean isNotTooLong();
+
+    /**
+     * @return the _current_ Event. That's the one returned by the previous 
call to {@link #next()}
+     *          but without propagating the Event pointer to the next entry.
+     */
+    Event current();
+
+    public static class JohnzonJsonParserWrapper implements JohnzonJsonParser {
+        public Event current() {
+            throw new UnsupportedOperationException("getting the current 
JsonParser Event is not supported");
+        }
+
+        private final JsonParser jsonParser;
+
+        public JohnzonJsonParserWrapper(JsonParser jsonParser) {
+            this.jsonParser = jsonParser;
+        }
+
+        @Override
+        public boolean isNotTooLong() {
+            return true;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return jsonParser.hasNext();
+        }
+
+        @Override
+        public Event next() {
+            return jsonParser.next();
+        }
+
+        @Override
+        public String getString() {
+            return jsonParser.getString();
+        }
+
+        @Override
+        public boolean isIntegralNumber() {
+            return jsonParser.isIntegralNumber();
+        }
+
+        @Override
+        public int getInt() {
+            return jsonParser.getInt();
+        }
+
+        @Override
+        public long getLong() {
+            return jsonParser.getLong();
+        }
+
+        @Override
+        public BigDecimal getBigDecimal() {
+            return jsonParser.getBigDecimal();
+        }
+
+        @Override
+        public JsonLocation getLocation() {
+            return jsonParser.getLocation();
+        }
+
+        @Override
+        public void close() {
+            jsonParser.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java
new file mode 100644
index 0000000..356399b
--- /dev/null
+++ 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.johnzon.core;
+
+
+/**
+ * Base parser which handles higher level operations which are
+ * mixtures of Reader and Parsers like {@code getObject(), getValue(), 
getArray()}
+ */
+public abstract class JohnzonJsonParserImpl implements JohnzonJsonParser {
+
+    /**
+     * @return {@code true} if we are currently inside an array
+     */
+    protected abstract boolean isInArray();
+
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
index 913c22a..436a035 100644
--- 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
+++ 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
@@ -97,30 +97,25 @@ class JsonArrayBuilderImpl implements JsonArrayBuilder, 
Serializable {
         addValue(builder.build());
         return this;
     }
-    
-    private void addValue(JsonValue value){
+
+    private void addValue(JsonValue value) {
         if (value == null) {
             throw npe();
         }
-        
+
         if(tmpList==null){
             tmpList=new ArrayList<JsonValue>();
         }
-        
+
         tmpList.add(value);
     }
 
     @Override
     public JsonArray build() {
-        
         if(tmpList == null) {
             return new JsonArrayImpl(Collections.EMPTY_LIST);
-        } else {
-            List<JsonValue> dump = (Collections.unmodifiableList(tmpList));
-            tmpList=null;
-            return new JsonArrayImpl(dump);
         }
-        
+        return new JsonArrayImpl(Collections.unmodifiableList(tmpList));
     }
 
     private static NullPointerException npe() {

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java
index cfb563d..1d880c7 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java
@@ -179,8 +179,7 @@ class JsonArrayImpl extends AbstractList<JsonValue> 
implements JsonArray, Serial
 
     @Override
     public boolean equals(final Object obj) {
-        return JsonArrayImpl.class.isInstance(obj)
-                && 
unmodifieableBackingList.equals(JsonArrayImpl.class.cast(obj).unmodifieableBackingList);
+        return JsonArray.class.isInstance(obj) && super.equals(obj);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
index 121f18f..3d1ff1c 100644
--- 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
+++ 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
@@ -60,8 +60,10 @@ class JsonBuilderFactoryImpl implements JsonBuilderFactory {
         return new JsonArrayBuilderImpl();
     }
 
+
     @Override
     public Map<String, ?> getConfigInUse() {
         return Collections.unmodifiableMap(internalConfig);
     }
+
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonDoubleImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonDoubleImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonDoubleImpl.java
index cff63c0..bcce401 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonDoubleImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonDoubleImpl.java
@@ -26,6 +26,8 @@ import java.math.BigInteger;
 final class JsonDoubleImpl implements JsonNumber, Serializable {
     private final double value;
 
+    private Integer hashCode = null;
+
     JsonDoubleImpl(final double value) {
         
         if(Double.isInfinite(value) || Double.isNaN(value)) {
@@ -47,6 +49,7 @@ final class JsonDoubleImpl implements JsonNumber, 
Serializable {
 
     @Override
     public int intValueExact() {
+        checkFractionalPart();
         return intValue();
     }
 
@@ -57,6 +60,7 @@ final class JsonDoubleImpl implements JsonNumber, 
Serializable {
 
     @Override
     public long longValueExact() {
+        checkFractionalPart();
         return (long) value;
     }
 
@@ -92,11 +96,24 @@ final class JsonDoubleImpl implements JsonNumber, 
Serializable {
 
     @Override
     public int hashCode() {
-        return Double.valueOf(value).hashCode();
+        if (hashCode == null) {
+            hashCode = bigDecimalValue().hashCode();
+        }
+
+        return hashCode;
     }
 
     @Override
     public boolean equals(final Object obj) {
+        if (JsonDoubleImpl.class.isInstance(obj)) {
+            return JsonDoubleImpl.class.cast(obj).value == value;
+        }
         return JsonNumber.class.isInstance(obj) && 
JsonNumber.class.cast(obj).doubleValue() == value;
     }
+
+    private void checkFractionalPart() {
+        if ((value % 1) != 0) {
+            throw new ArithmeticException("Not an int/long, use other value 
readers");
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java
index e1371e5..5ef026a 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java
@@ -430,6 +430,23 @@ class JsonGeneratorImpl implements JsonGenerator, 
JsonChars, Serializable {
         return this;
     }
 
+    public JsonGenerator writeKey(final String key) {
+        final GeneratorState currentState = currentState();
+        if (!currentState.acceptsKey) {
+            throw new JsonGenerationException("state " + currentState + " does 
not accept a key");
+        }
+        if (currentState == GeneratorState.IN_OBJECT) {
+            justWrite(COMMA_CHAR);
+            writeEol();
+        }
+
+        writeIndent();
+
+        writeCachedKey(key);
+        state.push(GeneratorState.AFTER_KEY);
+        return this;
+    }
+
     @Override
     public void close() {
         try {
@@ -442,8 +459,9 @@ class JsonGeneratorImpl implements JsonGenerator, 
JsonChars, Serializable {
                 writer.close();
             } catch (final IOException e) {
                 throw new JsonException(e.getMessage(), e);
+            } finally {
+                bufferProvider.release(buffer);
             }
-            bufferProvider.release(buffer);
         }
     }
 
@@ -650,22 +668,6 @@ class JsonGeneratorImpl implements JsonGenerator, 
JsonChars, Serializable {
         return state.peek();
     }
 
-    private void writeKey(final String key) {
-        final GeneratorState currentState = currentState();
-        if (!currentState.acceptsKey) {
-            throw new IllegalStateException("state " + currentState + " does 
not accept a key");
-        }
-        if (currentState == GeneratorState.IN_OBJECT) {
-            justWrite(COMMA_CHAR);
-            writeEol();
-        }
-
-        writeIndent();
-
-        writeCachedKey(key);
-        state.push(GeneratorState.AFTER_KEY);
-    }
-
     private void writeValueAsJsonString(final String value) {
         prepareValue();
         final GeneratorState peek = state.peek();

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java
index 9137139..f94e437 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java
@@ -30,14 +30,14 @@ import javax.json.JsonString;
 import javax.json.JsonValue;
 import javax.json.JsonValue.ValueType;
 import javax.json.stream.JsonLocation;
-import javax.json.stream.JsonParser;
 
-class JsonInMemoryParser implements JsonParser {
+class JsonInMemoryParser extends JohnzonJsonParserImpl {
 
     private final SimpleStack<Iterator<Event>> stack = new 
SimpleStack<Iterator<Event>>();
 
     private Event currentEvent;
     private JsonValue currentValue;
+    private int arrayDepth = 0;
 
     private class ArrayIterator implements Iterator<Event> {
 
@@ -171,6 +171,19 @@ class JsonInMemoryParser implements JsonParser {
 
     }
 
+    @Override
+    public Event current() {
+        if (currentEvent == null && hasNext()) {
+            next();
+        }
+        return currentEvent;
+    }
+
+    @Override
+    protected boolean isInArray() {
+        return arrayDepth > 0;
+    }
+
     private static Event getEvent(final ValueType value) {
 
         switch (value) {
@@ -213,6 +226,12 @@ class JsonInMemoryParser implements JsonParser {
 
         currentEvent = stack.peek().next();
 
+        if (currentEvent == Event.START_ARRAY) {
+            arrayDepth++;
+        } else if (currentEvent == Event.END_ARRAY) {
+            arrayDepth--;
+        }
+
         return currentEvent;
     }
 
@@ -233,6 +252,11 @@ class JsonInMemoryParser implements JsonParser {
     }
 
     @Override
+    public boolean isNotTooLong() {
+        return true;
+    }
+
+    @Override
     public int getInt() {
         if (currentEvent != Event.VALUE_NUMBER) {
             throw new IllegalStateException("getInt is for numbers");

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonLongImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonLongImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonLongImpl.java
index 4068d9b..2a5f480 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonLongImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonLongImpl.java
@@ -25,6 +25,7 @@ import java.math.BigInteger;
 
 public final class JsonLongImpl implements JsonNumber, Serializable {
     private final long value;
+    private Integer hashCode = null;
 
     JsonLongImpl(final long value) {
         this.value = value;
@@ -87,11 +88,17 @@ public final class JsonLongImpl implements JsonNumber, 
Serializable {
 
     @Override
     public int hashCode() {
-        return (int) value;
+        if (hashCode == null) {
+            hashCode = bigDecimalValue().hashCode();
+        }
+        return hashCode;
     }
 
     @Override
     public boolean equals(final Object obj) {
-        return JsonNumber.class.isInstance(obj) && 
JsonNumber.class.cast(obj).longValue() == value;
+        if (JsonLongImpl.class.isInstance(obj)) {
+            return JsonLongImpl.class.cast(obj).value == value;
+        }
+        return JsonNumber.class.isInstance(obj) && 
JsonNumber.class.cast(obj).bigDecimalValue().equals(bigDecimalValue());
     }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java
index 9ad7752..e114263 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java
@@ -28,10 +28,10 @@ final class JsonNumberImpl implements JsonNumber, 
Serializable {
     private transient Integer hashCode = null;
 
     JsonNumberImpl(final BigDecimal decimal) {
-        if(decimal == null) {
+        if (decimal == null) {
             throw new NullPointerException("decimal must not be null");
         }
-        
+
         this.value = decimal;
     }
 
@@ -47,6 +47,7 @@ final class JsonNumberImpl implements JsonNumber, 
Serializable {
 
     @Override
     public int intValueExact() {
+        checkFractionalPart();
         return value.intValueExact();
     }
 
@@ -57,6 +58,7 @@ final class JsonNumberImpl implements JsonNumber, 
Serializable {
 
     @Override
     public long longValueExact() {
+        checkFractionalPart();
         return value.longValueExact();
     }
 
@@ -92,10 +94,10 @@ final class JsonNumberImpl implements JsonNumber, 
Serializable {
 
     @Override
     public int hashCode() {
-        Integer h=hashCode;
+        Integer h = hashCode;
         if (h == null) {
             h = value.hashCode();
-            hashCode=h;
+            hashCode = h;
         }
         return h;
     }
@@ -104,4 +106,10 @@ final class JsonNumberImpl implements JsonNumber, 
Serializable {
     public boolean equals(final Object obj) {
         return JsonNumber.class.isInstance(obj) && 
JsonNumber.class.cast(obj).bigDecimalValue().equals(value);
     }
+
+    private void checkFractionalPart() {
+        if (value.remainder(BigDecimal.ONE).doubleValue() != 0) {
+            throw new ArithmeticException("Not an int/long, use other value 
readers");
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
index d625383..c75d827 100644
--- 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
+++ 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
@@ -30,7 +30,7 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 
 class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable {
-    private Map<String, JsonValue> tmpMap;
+    private Map<String, JsonValue> attributeMap = new LinkedHashMap<String, 
JsonValue>();
 
     @Override
     public JsonObjectBuilder add(final String name, final JsonValue value) {
@@ -97,31 +97,23 @@ class JsonObjectBuilderImpl implements JsonObjectBuilder, 
Serializable {
         putValue(name, builder.build());
         return this;
     }
-    
+
     private void putValue(String name, JsonValue value){
         if(name == null || value == null) {
-            throw npe();
+            throw new NullPointerException("name or value/builder must not be 
null");
         }
         
-        if(tmpMap==null){
-            tmpMap=new LinkedHashMap<String, JsonValue>();
-        }
-        
-        tmpMap.put(name, value);
+        attributeMap.put(name, value);
     }
     
-    private static NullPointerException npe() {
-        return new NullPointerException("name or value/builder must not be 
null");
-    }
 
     @Override
     public JsonObject build() {
         
-        if(tmpMap==null) {
+        if(attributeMap == null || attributeMap.isEmpty()) {
             return new JsonObjectImpl(Collections.EMPTY_MAP);
         } else {
-            Map<String, JsonValue> dump = 
(Collections.unmodifiableMap(tmpMap));
-            tmpMap=null;
+            Map<String, JsonValue> dump = 
(Collections.unmodifiableMap(attributeMap));
             return new JsonObjectImpl(dump);
         }
         

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java
index 263f43e..bb3a5ae 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java
@@ -109,7 +109,14 @@ final class JsonObjectImpl extends AbstractMap<String, 
JsonValue> implements Jso
 
     @Override
     public boolean getBoolean(final String name) {
-        return JsonValue.TRUE.equals(valueOrExcpetion(name, JsonValue.class));
+        final JsonValue obj = valueOrExcpetion(name, JsonValue.class);
+        if (JsonValue.TRUE == obj) {
+            return true;
+        }
+        if (JsonValue.FALSE == obj) {
+            return false;
+        }
+        throw new ClassCastException("Wrong value for a boolean: " + obj);
     }
 
     @Override
@@ -117,9 +124,8 @@ final class JsonObjectImpl extends AbstractMap<String, 
JsonValue> implements Jso
         final Object v = value(name, JsonValue.class);
         if (v != null) {
             return JsonValue.TRUE.equals(v) || !JsonValue.FALSE.equals(v) && 
defaultValue;
-        } else {
-            return defaultValue;
         }
+        return defaultValue;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java
index c57f144..440b4cb 100644
--- 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java
+++ 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java
@@ -18,8 +18,10 @@
  */
 package org.apache.johnzon.core;
 
-import static java.util.Arrays.asList;
-
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParserFactory;
 import java.io.InputStream;
 import java.io.Reader;
 import java.nio.charset.Charset;
@@ -27,15 +29,13 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
 
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.json.stream.JsonParser;
-import javax.json.stream.JsonParserFactory;
+import static java.util.Arrays.asList;
 
 public class JsonParserFactoryImpl extends AbstractJsonFactory implements 
JsonParserFactory {
     public static final String MAX_STRING_LENGTH = 
"org.apache.johnzon.max-string-length";
-    public static final int DEFAULT_MAX_STRING_LENGTH = 
Integer.getInteger(MAX_STRING_LENGTH, 10 * 1024 * 1024); //10m
+    public static final int DEFAULT_MAX_STRING_LENGTH = 
Integer.getInteger(MAX_STRING_LENGTH, 256 * 1024); //256kB
     
+    public static final String AUTO_ADJUST_STRING_BUFFER = 
"org.apache.johnzon.auto-adjust-buffer";
     public static final String BUFFER_LENGTH = 
"org.apache.johnzon.default-char-buffer";
     public static final int DEFAULT_BUFFER_LENGTH = 
Integer.getInteger(BUFFER_LENGTH, 64 * 1024); //64k
     
@@ -43,13 +43,14 @@ public class JsonParserFactoryImpl extends 
AbstractJsonFactory implements JsonPa
     public static final boolean DEFAULT_SUPPORTS_COMMENT = 
Boolean.getBoolean(SUPPORTS_COMMENTS); //default is false;
 
     static final Collection<String> SUPPORTED_CONFIG_KEYS = asList(
-        BUFFER_STRATEGY, MAX_STRING_LENGTH, BUFFER_LENGTH, SUPPORTS_COMMENTS
+        BUFFER_STRATEGY, MAX_STRING_LENGTH, BUFFER_LENGTH, SUPPORTS_COMMENTS, 
AUTO_ADJUST_STRING_BUFFER
     );
       
     private final int maxSize;
     private final BufferStrategy.BufferProvider<char[]> bufferProvider;
     private final BufferStrategy.BufferProvider<char[]> valueBufferProvider;
     private final boolean supportsComments;
+    private final boolean autoAdjustBuffers;
 
     JsonParserFactoryImpl(final Map<String, ?> config) {
         super(config, SUPPORTED_CONFIG_KEYS, null);
@@ -63,30 +64,31 @@ public class JsonParserFactoryImpl extends 
AbstractJsonFactory implements JsonPa
         this.bufferProvider = getBufferProvider().newCharProvider(bufferSize);
         this.valueBufferProvider = 
getBufferProvider().newCharProvider(maxSize);
         this.supportsComments = getBool(SUPPORTS_COMMENTS, 
DEFAULT_SUPPORTS_COMMENT);
+        this.autoAdjustBuffers = getBool(AUTO_ADJUST_STRING_BUFFER, true);
     }
 
-    private JsonParser getDefaultJsonParserImpl(final InputStream in) {
+    private JsonStreamParserImpl getDefaultJsonParserImpl(final InputStream 
in) {
         if (supportsComments) {
-            return new CommentsJsonStreamParserImpl(in, maxSize, 
bufferProvider, valueBufferProvider);
+            return new CommentsJsonStreamParserImpl(in, maxSize, 
bufferProvider, valueBufferProvider, autoAdjustBuffers);
         }
         //UTF Auto detection RFC 4627
-        return new JsonStreamParserImpl(in, maxSize, bufferProvider, 
valueBufferProvider);
+        return new JsonStreamParserImpl(in, maxSize, bufferProvider, 
valueBufferProvider, autoAdjustBuffers);
     }
 
-    private JsonParser getDefaultJsonParserImpl(final InputStream in, final 
Charset charset) {
+    private JsonStreamParserImpl getDefaultJsonParserImpl(final InputStream 
in, final Charset charset) {
         if (supportsComments) {
-            return new CommentsJsonStreamParserImpl(in, charset, maxSize, 
bufferProvider, valueBufferProvider);
+            return new CommentsJsonStreamParserImpl(in, charset, maxSize, 
bufferProvider, valueBufferProvider, autoAdjustBuffers);
         }
         //use provided charset
-        return new JsonStreamParserImpl(in, charset, maxSize, bufferProvider, 
valueBufferProvider);
+        return new JsonStreamParserImpl(in, charset, maxSize, bufferProvider, 
valueBufferProvider, autoAdjustBuffers);
     }
 
-    private JsonParser getDefaultJsonParserImpl(final Reader in) {
+    private JsonStreamParserImpl getDefaultJsonParserImpl(final Reader in) {
         if (supportsComments) {
-            return new CommentsJsonStreamParserImpl(in, maxSize, 
bufferProvider, valueBufferProvider);
+            return new CommentsJsonStreamParserImpl(in, maxSize, 
bufferProvider, valueBufferProvider, autoAdjustBuffers);
         }
         //no charset necessary
-        return new JsonStreamParserImpl(in, maxSize, bufferProvider, 
valueBufferProvider);
+        return new JsonStreamParserImpl(in, maxSize, bufferProvider, 
valueBufferProvider, autoAdjustBuffers);
     }
 
     @Override
@@ -121,15 +123,15 @@ public class JsonParserFactoryImpl extends 
AbstractJsonFactory implements JsonPa
         return Collections.unmodifiableMap(internalConfig);
     }
 
-    public JsonParser createInternalParser(final InputStream in) {
+    public JsonStreamParserImpl createInternalParser(final InputStream in) {
         return getDefaultJsonParserImpl(in);
     }
     
-    public JsonParser createInternalParser(final InputStream in, final Charset 
charset) {
+    public JsonStreamParserImpl createInternalParser(final InputStream in, 
final Charset charset) {
         return getDefaultJsonParserImpl(in, charset);
     }
 
-    public JsonParser createInternalParser(final Reader reader) {
+    public JsonStreamParserImpl createInternalParser(final Reader reader) {
         return getDefaultJsonParserImpl(reader);
     }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java
new file mode 100644
index 0000000..91bc9c2
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.johnzon.core;
+
+public class JsonPointerUtil {
+
+    private JsonPointerUtil() {
+
+    }
+
+    /**
+     * Transforms "~" to "~0" and then "/" to "~1"
+     */
+    public static String encode(String s) {
+        if (s == null || s.length() == 0) {
+            return s;
+        }
+
+        return s.replace("~", "~0").replace("/", "~1");
+    }
+
+    /**
+     * Transforms "~1" to "/" and then "~0" to "~",
+     */
+    public static String decode(String s) {
+        if (s == null || s.length() == 0) {
+            return s;
+        }
+
+        return s.replace("~1", "/").replace("~0", "~");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
index d1bbec6..86828c0 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
@@ -115,13 +115,13 @@ public class JsonProviderImpl extends JsonProvider 
implements Serializable {
     public JsonBuilderFactory createBuilderFactory(final Map<String, ?> 
stringMap) {
         return DELEGATE.createBuilderFactory(stringMap);
     }
-
+    
     static class JsonProviderDelegate extends JsonProvider {
         private final JsonReaderFactory readerFactory = new 
JsonReaderFactoryImpl(null);
         private final JsonParserFactory parserFactory = new 
JsonParserFactoryImpl(null);
         private final JsonGeneratorFactory generatorFactory = new 
JsonGeneratorFactoryImpl(null);
         private final JsonWriterFactory writerFactory = new 
JsonWriterFactoryImpl(null);
-        private final JsonBuilderFactory builderFactory = new 
JsonBuilderFactoryImpl(null);
+        private final JsonBuilderFactoryImpl builderFactory = new 
JsonBuilderFactoryImpl(null);
 
         @Override
         public JsonParser createParser(final InputStream in) {

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java
index b0107ee..3e8a0fb 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java
@@ -18,6 +18,7 @@
  */
 package org.apache.johnzon.core;
 
+
 import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
 import javax.json.JsonNumber;
@@ -30,11 +31,29 @@ import javax.json.stream.JsonParser;
 import javax.json.stream.JsonParsingException;
 
 public class JsonReaderImpl implements JsonReader {
-    private final JsonParser parser;
+    private final JohnzonJsonParser parser;
     private boolean closed = false;
 
+    private boolean subStreamReader;
+
     public JsonReaderImpl(final JsonParser parser) {
-        this.parser = parser;
+        this(parser, false);
+    }
+
+    /**
+     *
+     * @param parser
+     * @param subStreamReader {@code true} if the Stream already got started 
and the first
+     *           operation should not be next() but {@link 
JohnzonJsonParser#current()} instead.
+     */
+    public JsonReaderImpl(final JsonParser parser, boolean subStreamReader) {
+        if (parser instanceof JohnzonJsonParser) {
+            this.parser = (JohnzonJsonParser) parser;
+        } else {
+            this.parser = new 
JohnzonJsonParser.JohnzonJsonParserWrapper(parser);
+        }
+
+        this.subStreamReader = subStreamReader;
     }
 
     @Override
@@ -42,62 +61,83 @@ public class JsonReaderImpl implements JsonReader {
         return JsonStructure.class.cast(readValue());
     }
 
-    //@Override
     public JsonValue readValue() {
         checkClosed();
 
         if (!parser.hasNext()) {
             throw new IllegalStateException("Nothing to read");
         }
-        final JsonParser.Event next = parser.next();
+
+
+        JsonParser.Event next;
+        if (subStreamReader) {
+            next = parser.current();
+        } else {
+            next = parser.next();
+        }
+
         switch (next) {
             case START_OBJECT:
                 final JsonObjectBuilder objectBuilder = new 
JsonObjectBuilderImpl();
                 parseObject(objectBuilder);
-                if (parser.hasNext()) {
-                    throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                if (!subStreamReader) {
+                    if (parser.hasNext()) {
+                        throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                    }
+                    close();
                 }
-                close();
                 return objectBuilder.build();
             case START_ARRAY:
                 final JsonArrayBuilder arrayBuilder = new 
JsonArrayBuilderImpl();
                 parseArray(arrayBuilder);
-                if (parser.hasNext()) {
-                    throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                if (!subStreamReader) {
+                    if (parser.hasNext()) {
+                        throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                    }
+                    close();
                 }
-                close();
                 return arrayBuilder.build();
             case VALUE_STRING:
-                if (parser.hasNext()) {
-                    throw new JsonParsingException("Expected end of file", 
parser.getLocation());
-                }
                 final JsonStringImpl string = new 
JsonStringImpl(parser.getString());
-                close();
+                if (!subStreamReader) {
+                    if (parser.hasNext()) {
+                        throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                    }
+                    close();
+                }
                 return string;
             case VALUE_FALSE:
-                if (parser.hasNext()) {
-                    throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                if (!subStreamReader) {
+                    if (parser.hasNext()) {
+                        throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                    }
+                    close();
                 }
-                close();
                 return JsonValue.FALSE;
             case VALUE_TRUE:
-                if (parser.hasNext()) {
-                    throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                if (!subStreamReader) {
+                    if (parser.hasNext()) {
+                        throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                    }
+                    close();
                 }
-                close();
                 return JsonValue.TRUE;
             case VALUE_NULL:
-                if (parser.hasNext()) {
-                    throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                if (!subStreamReader) {
+                    if (parser.hasNext()) {
+                        throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                    }
+                    close();
                 }
-                close();
                 return JsonValue.NULL;
             case VALUE_NUMBER:
-                if (parser.hasNext()) {
-                    throw new JsonParsingException("Expected end of file", 
parser.getLocation());
-                }
                 final JsonNumber number = new 
JsonNumberImpl(parser.getBigDecimal());
-                close();
+                if (!subStreamReader) {
+                    if (parser.hasNext()) {
+                        throw new JsonParsingException("Expected end of file", 
parser.getLocation());
+                    }
+                    close();
+                }
                 return number;
             default:
                 close();
@@ -107,12 +147,22 @@ public class JsonReaderImpl implements JsonReader {
 
     @Override
     public JsonObject readObject() {
-        return JsonObject.class.cast(read());
+        final JsonStructure read = read();
+        checkType(JsonObject.class, read);
+        return JsonObject.class.cast(read);
     }
 
     @Override
     public JsonArray readArray() {
-        return JsonArray.class.cast(read());
+        final JsonStructure read = read();
+        checkType(JsonArray.class, read);
+        return JsonArray.class.cast(read);
+    }
+
+    private void checkType(final Class<?> expected, final JsonStructure read) {
+        if (!expected.isInstance(read)) {
+            throw new JsonParsingException("Expecting " + expected + " but got 
" + read, parser.getLocation());
+        }
     }
 
     @Override
@@ -151,7 +201,7 @@ public class JsonReaderImpl implements JsonReader {
                     break;
 
                 case VALUE_NUMBER:
-                    if (parser.isIntegralNumber()) {
+                    if (parser.isIntegralNumber() && parser.isNotTooLong()) {
                         builder.add(key, new JsonLongImpl(parser.getLong()));
                     } else {
                         builder.add(key, new 
JsonNumberImpl(parser.getBigDecimal()));

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
index 876ec78..4d0571a 100644
--- 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
+++ 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
@@ -20,18 +20,17 @@ package org.apache.johnzon.core;
 
 import javax.json.JsonException;
 import javax.json.stream.JsonLocation;
-import javax.json.stream.JsonParser;
 import javax.json.stream.JsonParsingException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.io.Reader;
 import java.math.BigDecimal;
 import java.nio.charset.Charset;
 import java.util.NoSuchElementException;
 
 //This class represents either the Json tokenizer and the Json parser.
-public class JsonStreamParserImpl implements JsonChars, JsonParser{
+public class JsonStreamParserImpl extends JohnzonJsonParserImpl implements 
JsonChars {
+    private final boolean autoAdjust;
 
     //the main buffer where the stream will be buffered
     private final char[] buffer;
@@ -63,11 +62,12 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
     //we use a byte here, because comparing bytes
     //is more efficient than comparing enums
     //Additionally we handle internally two more event: COMMA_EVENT and 
KEY_SEPARATOR_EVENT
-    private byte previousEvent;
+    private byte previousEvent = -1;
 
     //this buffer is used to store current String or Number value in case that
     //within the value a buffer boundary is crossed or the string contains 
escaped characters
-    private final char[] fallBackCopyBuffer;
+    private char[] fallBackCopyBuffer;
+    private boolean releaseFallBackCopyBufferLength = true;
     private int fallBackCopyBufferLength;
 
     // location (line, column, offset)
@@ -93,6 +93,8 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
     //Stack can cause out of memory issues when the nesting depth of a Json 
stream is too deep.
     private StructureElement currentStructureElement = null;
 
+    private int arrayDepth = 0;
+
     //minimal stack implementation
     private static final class StructureElement {
         private final StructureElement previous;
@@ -107,27 +109,31 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
 
     //detect charset according to RFC 4627
     public JsonStreamParserImpl(final InputStream inputStream, final int 
maxStringLength,
-            final BufferStrategy.BufferProvider<char[]> bufferProvider, final 
BufferStrategy.BufferProvider<char[]> valueBuffer) {
+                                final BufferStrategy.BufferProvider<char[]> 
bufferProvider, final BufferStrategy.BufferProvider<char[]> valueBuffer,
+                                final boolean autoAdjust) {
 
-        this(inputStream, null, null, maxStringLength, bufferProvider, 
valueBuffer);
+        this(inputStream, null, null, maxStringLength, bufferProvider, 
valueBuffer, autoAdjust);
     }
 
     //use charset provided
     public JsonStreamParserImpl(final InputStream inputStream, final Charset 
encoding, final int maxStringLength,
-            final BufferStrategy.BufferProvider<char[]> bufferProvider, final 
BufferStrategy.BufferProvider<char[]> valueBuffer) {
+                                final BufferStrategy.BufferProvider<char[]> 
bufferProvider, final BufferStrategy.BufferProvider<char[]> valueBuffer,
+                                final boolean autoAdjust) {
 
-        this(inputStream, null, encoding, maxStringLength, bufferProvider, 
valueBuffer);
+        this(inputStream, null, encoding, maxStringLength, bufferProvider, 
valueBuffer, autoAdjust);
     }
 
     public JsonStreamParserImpl(final Reader reader, final int 
maxStringLength, final BufferStrategy.BufferProvider<char[]> bufferProvider,
-            final BufferStrategy.BufferProvider<char[]> valueBuffer) {
+                                final BufferStrategy.BufferProvider<char[]> 
valueBuffer, final boolean autoAdjust) {
 
-        this(null, reader, null, maxStringLength, bufferProvider, valueBuffer);
+        this(null, reader, null, maxStringLength, bufferProvider, valueBuffer, 
autoAdjust);
     }
 
     private JsonStreamParserImpl(final InputStream inputStream, final Reader 
reader, final Charset encoding, final int maxStringLength,
-            final BufferStrategy.BufferProvider<char[]> bufferProvider, final 
BufferStrategy.BufferProvider<char[]> valueBuffer) {
+                                 final BufferStrategy.BufferProvider<char[]> 
bufferProvider, final BufferStrategy.BufferProvider<char[]> valueBuffer,
+                                 final boolean autoAdjust) {
 
+        this.autoAdjust = autoAdjust;
         this.maxValueLength = maxStringLength <= 0 ? 8192 : maxStringLength;
         this.fallBackCopyBuffer = valueBuffer.newBuffer();
         this.buffer = bufferProvider.newBuffer();
@@ -140,11 +146,8 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
 
         if (reader != null) {
             this.in = reader;
-        } else if (encoding == null) {
-            this.in = new RFC4627AwareInputStreamReader(inputStream);
-
         } else {
-            this.in = new InputStreamReader(inputStream, 
encoding.newDecoder());
+            this.in = new RFC4627AwareInputStreamReader(inputStream, encoding);
         }
     }
 
@@ -155,29 +158,52 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
 
     //copy content between "start" and "end" from buffer to value buffer 
     private void copyCurrentValue() {
+        final int length = endOfValueInBuffer - startOfValueInBuffer;
+        if (length > 0) {
 
-        if ((endOfValueInBuffer - startOfValueInBuffer) > 0) {
-
-            if ((endOfValueInBuffer - startOfValueInBuffer) > maxValueLength) {
+            if (length > maxValueLength) {
                 throw tmc();
             }
 
-            System.arraycopy(buffer, startOfValueInBuffer, fallBackCopyBuffer, 
fallBackCopyBufferLength,
-                    (endOfValueInBuffer - startOfValueInBuffer));
-            fallBackCopyBufferLength += (endOfValueInBuffer - 
startOfValueInBuffer);
+            if (fallBackCopyBufferLength >= fallBackCopyBuffer.length - 
length) { // not good at runtime but handled
+                if (!autoAdjust) {
+                    throw new ArrayIndexOutOfBoundsException("Buffer too small 
for such a long string");
+                }
 
+                final char[] newArray = new char[fallBackCopyBuffer.length + 
Math.max(getBufferExtends(fallBackCopyBuffer.length), length)];
+                // TODO: log to adjust size once?
+                System.arraycopy(fallBackCopyBuffer, 0, newArray, 0, 
fallBackCopyBufferLength);
+                System.arraycopy(buffer, startOfValueInBuffer, newArray, 
fallBackCopyBufferLength, length);
+                if (releaseFallBackCopyBufferLength) {
+                    bufferProvider.release(fallBackCopyBuffer);
+                    releaseFallBackCopyBufferLength = false;
+                }
+                fallBackCopyBuffer = newArray;
+            } else {
+                System.arraycopy(buffer, startOfValueInBuffer, 
fallBackCopyBuffer, fallBackCopyBufferLength, length);
+            }
+            fallBackCopyBufferLength += length;
         }
 
         startOfValueInBuffer = endOfValueInBuffer = -1;
     }
 
+    /**
+     * @return the amount of bytes the current buffer should get extended with
+     */
+    protected int getBufferExtends(int currentLength) {
+        return currentLength / 4;
+    }
+
+
     @Override
     public final boolean hasNext() {
 
         if (currentStructureElement != null ||
-            (previousEvent != END_ARRAY && previousEvent != END_OBJECT &&
-                previousEvent != VALUE_STRING && previousEvent != VALUE_FALSE 
&& previousEvent != VALUE_TRUE && previousEvent != VALUE_NULL && previousEvent 
!= VALUE_NUMBER) ||
-            previousEvent == 0) {
+                (previousEvent != END_ARRAY && previousEvent != END_OBJECT &&
+                        previousEvent != VALUE_STRING && previousEvent != 
VALUE_FALSE && previousEvent != VALUE_TRUE &&
+                        previousEvent != VALUE_NULL && previousEvent != 
VALUE_NUMBER) ||
+                previousEvent == 0) {
 
             return true;
         }
@@ -317,6 +343,16 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
     }
 
     @Override
+    public Event current() {
+        if (previousEvent < 0 && hasNext()) {
+            next();
+        }
+        return previousEvent >= 0 && previousEvent < Event.values().length
+                ? Event.values()[previousEvent]
+                : null;
+    }
+
+    @Override
     public final Event next() {
         //main entry, make decision how to handle the current character in the 
stream
 
@@ -324,7 +360,7 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
             throw new NoSuchElementException();
         }
 
-        if (previousEvent != 0 && currentStructureElement == null) {
+        if (previousEvent > 0 && currentStructureElement == null) {
             throw uexc("Unexpected end of structure");
         }
 
@@ -415,6 +451,7 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
         }
     }
 
+
     protected Event defaultHandling(char c) {
         if (c == EOF) {
             throw uexc("End of file hit too early");
@@ -425,7 +462,7 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
     private Event handleStartObject() {
 
         //last event must one of the following-> : , [
-        if (previousEvent != 0 && previousEvent != KEY_SEPARATOR_EVENT && 
previousEvent != START_ARRAY && previousEvent != COMMA_EVENT) {
+        if (previousEvent > 0 && previousEvent != KEY_SEPARATOR_EVENT && 
previousEvent != START_ARRAY && previousEvent != COMMA_EVENT) {
             throw uexc("Expected : , [");
         }
 
@@ -433,7 +470,7 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
         if (currentStructureElement == null) {
             currentStructureElement = new StructureElement(null, false);
         } else {
-            if(!currentStructureElement.isArray && previousEvent != 
KEY_SEPARATOR_EVENT) {
+            if (!currentStructureElement.isArray && previousEvent != 
KEY_SEPARATOR_EVENT) {
                 throw uexc("Expected :");
             }
             final StructureElement localStructureElement = new 
StructureElement(currentStructureElement, false);
@@ -465,7 +502,7 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
     private Event handleStartArray() {
 
         //last event must one of the following-> : , [
-        if (previousEvent != 0 && previousEvent != KEY_SEPARATOR_EVENT && 
previousEvent != START_ARRAY && previousEvent != COMMA_EVENT) {
+        if (previousEvent > 0 && previousEvent != KEY_SEPARATOR_EVENT && 
previousEvent != START_ARRAY && previousEvent != COMMA_EVENT) {
             throw uexc("Expected : , [");
         }
 
@@ -473,13 +510,15 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
         if (currentStructureElement == null) {
             currentStructureElement = new StructureElement(null, true);
         } else {
-            if(!currentStructureElement.isArray && previousEvent != 
KEY_SEPARATOR_EVENT) {
+            if (!currentStructureElement.isArray && previousEvent != 
KEY_SEPARATOR_EVENT) {
                 throw uexc("Expected \"");
             }
             final StructureElement localStructureElement = new 
StructureElement(currentStructureElement, true);
             currentStructureElement = localStructureElement;
         }
 
+        arrayDepth++;
+
         return EVT_MAP[previousEvent = START_ARRAY];
     }
 
@@ -498,9 +537,16 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
         //pop from stack
         currentStructureElement = currentStructureElement.previous;
 
+        arrayDepth--;
+
         return EVT_MAP[previousEvent = END_ARRAY];
     }
 
+    @Override
+    protected boolean isInArray() {
+        return arrayDepth > 0;
+    }
+
     //read a string, gets called recursively
     //Handles escape/d characters
     //if string contains escape chars and/or cross buffer boundary then copy 
in the value buffer
@@ -577,7 +623,7 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
                 bufferPos--; //unread one char
 
             }
-        }  while (true);
+        } while (true);
 
         // before this do while(true) it was:
         //
@@ -630,8 +676,8 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
         //always the beginning quote of a key or value  
 
         //last event must one of the following-> : { [ ,
-        if (previousEvent != KEY_SEPARATOR_EVENT && previousEvent != 
START_OBJECT && previousEvent != START_ARRAY
-                && previousEvent != COMMA_EVENT) {
+        if (previousEvent != -1 && (previousEvent != KEY_SEPARATOR_EVENT && 
previousEvent != START_OBJECT && previousEvent != START_ARRAY
+                && previousEvent != COMMA_EVENT)) {
             throw uexc("Expected : { [ ,");
         }
         //starting quote already consumed
@@ -775,7 +821,7 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
     private Event handleLiteral() {
 
         //last event must one of the following-> : , [
-        if (previousEvent != KEY_SEPARATOR_EVENT && previousEvent != 
START_ARRAY && previousEvent != COMMA_EVENT) {
+        if (previousEvent != -1 && previousEvent != KEY_SEPARATOR_EVENT && 
previousEvent != START_ARRAY && previousEvent != COMMA_EVENT) {
             throw uexc("Expected : , [");
         }
 
@@ -839,6 +885,11 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
     }
 
     @Override
+    public boolean isNotTooLong() {
+        return (endOfValueInBuffer - startOfValueInBuffer) < 19;
+    }
+
+    @Override
     public int getInt() {
         if (previousEvent != VALUE_NUMBER) {
             throw new IllegalStateException(EVT_MAP[previousEvent] + " doesn't 
support getInt()");
@@ -914,7 +965,9 @@ public class JsonStreamParserImpl implements JsonChars, 
JsonParser{
     @Override
     public void close() {
         bufferProvider.release(buffer);
-        valueProvider.release(fallBackCopyBuffer);
+        if (releaseFallBackCopyBufferLength) {
+            valueProvider.release(fallBackCopyBuffer);
+        }
 
         try {
             in.close();

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/JsonWriterImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonWriterImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonWriterImpl.java
index e012ae1..845ca70 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonWriterImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonWriterImpl.java
@@ -18,15 +18,14 @@
  */
 package org.apache.johnzon.core;
 
-import java.io.Serializable;
-
 import javax.json.JsonArray;
 import javax.json.JsonObject;
 import javax.json.JsonStructure;
 import javax.json.JsonWriter;
 import javax.json.stream.JsonGenerator;
+import java.io.Serializable;
 
-class JsonWriterImpl implements JsonWriter, Serializable{
+class JsonWriterImpl implements JsonWriter, Serializable {
     private final JsonGenerator generator;
     private boolean closed = false;
 
@@ -37,37 +36,46 @@ class JsonWriterImpl implements JsonWriter, Serializable{
     @Override
     public void writeArray(final JsonArray array) {
         checkClosed();
-        generator.write(array);
-        close();
+        try {
+            generator.write(array);
+        } finally {
+            close();
+        }
     }
 
     @Override
     public void writeObject(final JsonObject object) {
         checkClosed();
-        generator.write(object);
-        close();
+        try {
+            generator.write(object);
+        } finally {
+            close();
+        }
     }
 
     @Override
     public void write(final JsonStructure value) {
         checkClosed();
-        generator.write(value);
-        close();
+        try {
+            generator.write(value);
+        } finally {
+            close();
+        }
     }
 
     @Override
     public void close() {
-        
-        if(!closed) {
+
+        if (!closed) {
             closed = true;
             generator.close();
         }
     }
-    
+
     private void checkClosed() {
-        if(closed) {
+        if (closed) {
             throw new IllegalStateException("writeArray(), writeObject(), 
write() or close() method was already called");
         }
-           
+
     }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/RFC4627AwareInputStreamReader.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/RFC4627AwareInputStreamReader.java
 
b/johnzon-core/src/main/java/org/apache/johnzon/core/RFC4627AwareInputStreamReader.java
index 645cf0e..aa09804 100644
--- 
a/johnzon-core/src/main/java/org/apache/johnzon/core/RFC4627AwareInputStreamReader.java
+++ 
b/johnzon-core/src/main/java/org/apache/johnzon/core/RFC4627AwareInputStreamReader.java
@@ -23,18 +23,21 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.PushbackInputStream;
 import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 
 import javax.json.JsonException;
 
 final class RFC4627AwareInputStreamReader extends InputStreamReader {
 
-    RFC4627AwareInputStreamReader(final InputStream in) {
-        this(new PushbackInputStream(in,4));
+    /**
+     * @param preferredCharset the Charset to use if no BOM is used. If {@code 
null} use UTF-8
+     */
+    RFC4627AwareInputStreamReader(final InputStream in, Charset 
preferredCharset) {
+        this(new PushbackInputStream(in,4), preferredCharset);
     }
-    
-    private RFC4627AwareInputStreamReader(final PushbackInputStream in) {
-        super(in, getCharset(in).newDecoder());
-       
+
+    private RFC4627AwareInputStreamReader(final PushbackInputStream in, 
Charset preferredCharset) {
+        super(in, getCharset(in, preferredCharset).newDecoder());
     }
 
     /**
@@ -44,10 +47,15 @@ final class RFC4627AwareInputStreamReader extends 
InputStreamReader {
      */
     private static byte[] readAllBytes(final PushbackInputStream inputStream) 
throws IOException {
         final int first = inputStream.read();
+        if(first == -1) {
+            return new byte[0];
+        }
+
         final int second = inputStream.read();
-        if(first == -1|| second == -1) {
-            throw new JsonException("Invalid Json. Valid Json has at least 2 
bytes");
+        if(second == -1) {
+            return new byte[] {(byte) first};
         }
+
         final int third = inputStream.read();
         final int fourth = inputStream.read();
         if(third == -1) {
@@ -78,11 +86,19 @@ final class RFC4627AwareInputStreamReader extends 
InputStreamReader {
 
         */
 
-    private static Charset getCharset(final PushbackInputStream inputStream) {
-        Charset charset = Charset.forName("UTF-8");
+    private static Charset getCharset(final PushbackInputStream inputStream, 
Charset preferredCharset) {
+        Charset charset = preferredCharset != null ? preferredCharset : 
Charset.forName("UTF-8");
         int bomLength=0;
         try {
             final byte[] utfBytes = readAllBytes(inputStream);
+            if (utfBytes.length == 0) {
+                return StandardCharsets.UTF_8; // empty file -> doesn't matter 
anyway
+            }
+            if (utfBytes.length == 1) {
+                inputStream.unread(utfBytes);
+                return StandardCharsets.UTF_8; // almost empty file -> doesn't 
matter neither
+            }
+
             int first = (utfBytes[0] & 0xFF);
             int second = (utfBytes[1] & 0xFF);
             if (first == 0x00) {

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/main/java/org/apache/johnzon/core/SimpleStack.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/SimpleStack.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/SimpleStack.java
index e72540c..74bd14f 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/SimpleStack.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/SimpleStack.java
@@ -53,8 +53,8 @@ class SimpleStack<T> {
 
         }
 
-        Element<T> previous;
-        T payload;
+        private Element<T> previous;
+        private T payload;
 
     }
 

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/test/java/org/apache/johnzon/core/BrokenDefaultTest.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/test/java/org/apache/johnzon/core/BrokenDefaultTest.java 
b/johnzon-core/src/test/java/org/apache/johnzon/core/BrokenDefaultTest.java
new file mode 100644
index 0000000..3ba336e
--- /dev/null
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/BrokenDefaultTest.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.johnzon.core;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Queue;
+
+import javax.json.Json;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParserFactory;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class BrokenDefaultTest {
+
+    @Test
+    @Ignore("buggy but pushing to share the use case")
+    public void run() throws NoSuchFieldException, IllegalAccessException, 
UnsupportedEncodingException { // shouldnt fail by default
+        final JsonParserFactory factory = 
Json.createParserFactory(Collections.EMPTY_MAP);
+        final int length = 1024 * 1024;
+        assertEquals(0, get(Queue.class, get(
+                BufferStrategy.BufferProvider.class, factory, 
"bufferProvider"), "queue").size());
+
+        final JsonParser parser = 
factory.createParser(newDynamicInput(length));
+
+        try {
+            int eventCount = 0;
+            while (parser.hasNext()) {
+                eventCount++;
+                final JsonParser.Event next = parser.next();
+                if (eventCount == 2 && next == JsonParser.Event.VALUE_STRING) {
+                    assertEquals(length, parser.getString().length());
+                }
+            }
+        } finally {
+            parser.close();
+        }
+
+        assertEquals(1, get(Queue.class, get(
+                BufferStrategy.BufferProvider.class, factory, 
"bufferProvider"), "queue").size());
+    }
+
+    private <T> T get(final Class<T> returnType, final Object instance, final 
String field)
+            throws NoSuchFieldException, IllegalAccessException {
+        Class<?> current = instance.getClass();
+        while (current != Object.class) {
+            try {
+                final Field declaredField = current.getDeclaredField(field);
+                if (!declaredField.isAccessible()) {
+                    declaredField.setAccessible(true);
+                }
+                return returnType.cast(declaredField.get(instance));
+            } catch (final NoSuchFieldException nsfe) {
+                current = current.getSuperclass();
+            }
+        }
+        throw new IllegalAccessError(instance + " field: " + field);
+    }
+
+    private InputStream newDynamicInput(final int size) throws 
UnsupportedEncodingException {
+        return new InputStream() {
+
+            private InputStream before = new 
ByteArrayInputStream("{\"key\":\"".getBytes("UTF-8"));
+
+            private InputStream after = new 
ByteArrayInputStream("\"}".getBytes("UTF-8"));
+
+            private int remaining = size;
+
+            @Override
+            public int read() throws IOException {
+                {
+                    final int val = before.read();
+                    if (val >= 0) {
+                        return val;
+                    }
+                }
+                if (remaining < 0) {
+                    return after.read();
+                }
+                remaining--;
+                return 'a';
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayBuilderImplTest.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayBuilderImplTest.java
 
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayBuilderImplTest.java
index df7a1af..9bfd2df 100644
--- 
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayBuilderImplTest.java
+++ 
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayBuilderImplTest.java
@@ -167,4 +167,5 @@ public class JsonArrayBuilderImplTest {
         final JsonArrayBuilder builder = Json.createArrayBuilder();
         builder.add((double) Double.NEGATIVE_INFINITY);
     }
+
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayImplTest.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayImplTest.java 
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayImplTest.java
index b0918b1..8b6dac7 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayImplTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayImplTest.java
@@ -58,4 +58,12 @@ public class JsonArrayImplTest {
         assertTrue(array.isEmpty());
         assertEquals("[]", array.toString());
     }
+
+    @Test
+    public void equals() {
+        
assertTrue(Json.createArrayBuilder().build().equals(Json.createArrayBuilder().build()));
+        
assertTrue(Json.createArrayBuilder().add(1).build().equals(Json.createArrayBuilder().add(1).build()));
+        
assertFalse(Json.createArrayBuilder().add(1).build().equals(Json.createArrayBuilder().add(2).build()));
+        
assertFalse(Json.createArrayBuilder().add(1).build().equals(Json.createArrayBuilder().build()));
+    }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/test/java/org/apache/johnzon/core/JsonBuilderFactoryTest.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonBuilderFactoryTest.java
 
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonBuilderFactoryTest.java
new file mode 100644
index 0000000..f897e70
--- /dev/null
+++ 
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonBuilderFactoryTest.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.johnzon.core;
+
+import java.util.Collections;
+
+import javax.json.Json;
+import javax.json.JsonBuilderFactory;
+import javax.json.JsonObject;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class JsonBuilderFactoryTest {
+
+    @Test
+    public void testCreateBuilderFactory() {
+        JsonBuilderFactory factory = 
Json.createBuilderFactory(Collections.EMPTY_MAP);
+        JsonObject jsonObject = factory.createObjectBuilder().
+                add("name", "home").
+                add("city", "Vienna")
+                .build();
+
+        //JsonObject
+        Assert.assertEquals("home", jsonObject.getString("name"));
+        Assert.assertEquals("Vienna", jsonObject.getString("city"));
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/76fe13de/johnzon-core/src/test/java/org/apache/johnzon/core/JsonGeneratorImplTest.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonGeneratorImplTest.java 
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonGeneratorImplTest.java
index 797cca5..83561c6 100644
--- 
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonGeneratorImplTest.java
+++ 
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonGeneratorImplTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.johnzon.core;
 
+import org.junit.Assert;
 import org.junit.Test;
 
 import javax.json.Json;
@@ -50,6 +51,19 @@ public class JsonGeneratorImplTest {
     }
 
     @Test
+    public void testCreateGenerator() {
+        StringWriter sw = new StringWriter();
+        JsonGenerator jsonGenerator = Json.createGenerator(sw);
+        jsonGenerator.writeStartObject()
+                .write("a", "b")
+                .write("c", "d")
+                .writeEnd();
+
+        jsonGenerator.close();
+
+        Assert.assertEquals("{\"a\":\"b\",\"c\":\"d\"}", sw.toString());
+    }
+    @Test
     public void emptyArray() {
         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
         final JsonGenerator generator = Json.createGenerator(baos);

Reply via email to