Index: trunk/src/org/glassfish/json/JsonObjectBuilderImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonObjectBuilderImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonObjectBuilderImpl.java	(revision 13231)
@@ -2,5 +2,5 @@
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved.
  *
  * The contents of this file are subject to the terms of either the GNU
@@ -9,10 +9,10 @@
  * may not use this file except in compliance with the License.  You can
  * obtain a copy of the License at
- * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
- * or packager/legal/LICENSE.txt.  See the License for the specific
+ * https://oss.oracle.com/licenses/CDDL+GPL-1.1
+ * or LICENSE.txt.  See the License for the specific
  * language governing permissions and limitations under the License.
  *
  * When distributing the software, include this License Header Notice in each
- * file and include the License file at packager/legal/LICENSE.txt.
+ * file and include the License file at LICENSE.txt.
  *
  * GPL Classpath Exception:
@@ -51,9 +51,11 @@
 
 /**
- * JsonObjectBuilder impl
+ * JsonObjectBuilder implementation
  *
  * @author Jitendra Kotamraju
+ * @author Kin-man Chung
  */
 class JsonObjectBuilderImpl implements JsonObjectBuilder {
+
     private Map<String, JsonValue> valueMap;
     private final BufferPool bufferPool;
@@ -63,4 +65,17 @@
     }
 
+    JsonObjectBuilderImpl(JsonObject object, BufferPool bufferPool) {
+        this.bufferPool = bufferPool;
+        valueMap = new LinkedHashMap<>();
+        valueMap.putAll(object);
+    }
+
+    JsonObjectBuilderImpl(Map<String, Object> map, BufferPool bufferPool) {
+        this.bufferPool = bufferPool;
+        valueMap = new LinkedHashMap<>();
+        populate(map);
+    }
+
+    @Override
     public JsonObjectBuilder add(String name, JsonValue value) {
         validateName(name);
@@ -70,4 +85,5 @@
     }
 
+    @Override
     public JsonObjectBuilder add(String name, String value) {
         validateName(name);
@@ -77,4 +93,5 @@
     }
 
+    @Override
     public JsonObjectBuilder add(String name, BigInteger value) {
         validateName(name);
@@ -84,4 +101,5 @@
     }
 
+    @Override
     public JsonObjectBuilder add(String name, BigDecimal value) {
         validateName(name);
@@ -91,4 +109,5 @@
     }
 
+    @Override
     public JsonObjectBuilder add(String name, int value) {
         validateName(name);
@@ -97,4 +116,5 @@
     }
 
+    @Override
     public JsonObjectBuilder add(String name, long value) {
         validateName(name);
@@ -103,4 +123,5 @@
     }
 
+    @Override
     public JsonObjectBuilder add(String name, double value) {
         validateName(name);
@@ -109,4 +130,5 @@
     }
 
+    @Override
     public JsonObjectBuilder add(String name, boolean value) {
         validateName(name);
@@ -115,4 +137,5 @@
     }
 
+    @Override
     public JsonObjectBuilder addNull(String name) {
         validateName(name);
@@ -121,4 +144,5 @@
     }
 
+    @Override
     public JsonObjectBuilder add(String name, JsonObjectBuilder builder) {
         validateName(name);
@@ -130,4 +154,5 @@
     }
 
+    @Override
     public JsonObjectBuilder add(String name, JsonArrayBuilder builder) {
         validateName(name);
@@ -139,4 +164,24 @@
     }
 
+    @Override
+    public JsonObjectBuilder addAll(JsonObjectBuilder builder) {
+        if (builder == null) {
+            throw new NullPointerException(JsonMessages.OBJBUILDER_OBJECT_BUILDER_NULL());
+        }
+        if (valueMap == null) {
+            this.valueMap = new LinkedHashMap<>();
+        }
+        this.valueMap.putAll(builder.build());
+        return this;
+    }
+
+    @Override
+    public JsonObjectBuilder remove(String name) {
+        validateName(name);
+        this.valueMap.remove(name);
+        return this;
+    }
+
+    @Override
     public JsonObject build() {
         Map<String, JsonValue> snapshot = (valueMap == null)
@@ -147,7 +192,20 @@
     }
 
+    private void populate(Map<String, Object> map) {
+        final Set<String> fields = map.keySet();
+        for (String field : fields) {
+            Object value = map.get(field);
+            if (value != null && value instanceof Optional) {
+                ((Optional<?>) value).ifPresent(v ->
+                        this.valueMap.put(field, MapUtil.handle(v, bufferPool)));
+            } else {
+                this.valueMap.put(field, MapUtil.handle(value, bufferPool));
+            }
+        }
+    }
+
     private void putValueMap(String name, JsonValue value) {
         if (valueMap == null) {
-            this.valueMap = new LinkedHashMap<String, JsonValue>();
+            this.valueMap = new LinkedHashMap<>();
         }
         valueMap.put(name, value);
@@ -264,9 +322,29 @@
         public String toString() {
             StringWriter sw = new StringWriter();
-            JsonWriter jw = new JsonWriterImpl(sw, bufferPool);
-            jw.write(this);
-            jw.close();
+            try (JsonWriter jw = new JsonWriterImpl(sw, bufferPool)) {
+                jw.write(this);
+            }
             return sw.toString();
         }
+
+        @Override
+        public JsonObject asJsonObject() {
+            return this;
+        }
+
+        @Override
+        public int size() {
+            return valueMap.size();
+        }
+
+        @Override
+        public JsonValue get(Object key) {
+            return valueMap.get(key);
+        }
+
+        @Override
+        public boolean containsKey(Object key) {
+            return valueMap.containsKey(key);
+        }
     }
 
