You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2016/02/19 17:18:59 UTC

[50/50] [abbrv] ignite git commit: ignite-961 JSON API implemented

ignite-961 JSON API implemented


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/2560c885
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/2560c885
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/2560c885

Branch: refs/heads/ignite-961
Commit: 2560c8852b4b2bc9d36691f49d216fcafccca32e
Parents: 1367eb9
Author: agura <ag...@gridgain.com>
Authored: Fri Feb 19 19:01:16 2016 +0300
Committer: agura <ag...@gridgain.com>
Committed: Fri Feb 19 19:01:16 2016 +0300

----------------------------------------------------------------------
 .../ignite/internal/IgniteComponentType.java    |   3 +-
 .../binary/builder/BinaryObjectBuilderImpl.java |   7 +
 .../binary/builder/BinaryValueWithType.java     |  26 +
 .../processors/cache/CacheObjectContext.java    |   5 +-
 .../json/IgniteJsonNoopProcessor.java           |   5 +
 .../processors/json/IgniteJsonProcessor.java    |   5 +
 .../processors/query/GridQueryProcessor.java    |  66 +-
 .../processors/rest/GridRestProcessor.java      |  13 +-
 .../processors/json/IgniteJsonArray.java        | 374 ++++++++-
 .../processors/json/IgniteJsonArrayBuilder.java |  88 +-
 .../processors/json/IgniteJsonGenerator.java    |   3 +-
 .../processors/json/IgniteJsonLocation.java     |   2 +-
 .../json/IgniteJsonMessageFactory.java          |  37 -
 .../processors/json/IgniteJsonNumber.java       |   2 +-
 .../processors/json/IgniteJsonObject.java       | 208 ++++-
 .../json/IgniteJsonObjectBuilder.java           |  92 ++-
 .../json/IgniteJsonProcessorImpl.java           |  40 +-
 .../processors/json/IgniteJsonProvider.java     |  13 +-
 .../processors/json/IgniteJsonString.java       |   2 +-
 .../processors/json/IgniteJsonUtils.java        |  58 ++
 .../processors/json/JsonCacheObject.java        | 127 ---
 .../java/org/apache/ignite/json/IgniteJson.java |   3 +-
 .../json/IgniteJsonArrayBuilderSelfTest.java    | 145 ++++
 .../json/IgniteJsonArraySelfTest.java           | 807 +++++++++++++++++++
 .../processors/json/IgniteJsonCacheTest.java    |  62 +-
 .../json/IgniteJsonObjectBuilderSelfTest.java   | 147 ++++
 .../json/IgniteJsonObjectSelfTest.java          | 637 +++++++++++++++
 .../ignite/testsuites/IgniteJsonTestSuite.java  |  48 ++
 .../ignite/internal/NodeJsComputeSelfTest.java  |   2 +-
 .../ignite/internal/NodeJsSqlQuerySelfTest.java |   2 +-
 modules/nodejs/src/test/js/test-compute.js      |   3 -
 31 files changed, 2686 insertions(+), 346 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java
index d15a2b2..8c750f4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteComponentType.java
@@ -88,8 +88,7 @@ public enum IgniteComponentType {
     JSON(
         "org.apache.ignite.internal.processors.json.IgniteJsonNoopProcessor",
         "org.apache.ignite.internal.processors.json.IgniteJsonProcessorImpl",
-        "ignite-json",
-        "org.apache.ignite.internal.processors.json.IgniteJsonMessageFactory"
+        "ignite-json"
     );
 
     /** No-op class name. */

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
index 9043a8b..512fcc0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
@@ -394,6 +394,13 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder {
     }
 
     /**
+     * @return Map of assigned values.
+     */
+    public Map<String, Object> assignedVals() {
+        return assignedVals;
+    }
+
+    /**
      * Get field position and length.
      *
      * @param footerPos Field position inside the footer (absolute).

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryValueWithType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryValueWithType.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryValueWithType.java
index c5a3e0a..b32954d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryValueWithType.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryValueWithType.java
@@ -71,6 +71,32 @@ class BinaryValueWithType implements BinaryLazyValue {
     }
 
     /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        BinaryValueWithType that = (BinaryValueWithType)o;
+
+        if (type != that.type)
+            return false;
+
+        return val != null ? val.equals(that.val) : that.val == null;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = (int)type;
+
+        res = 31 * res + (val != null ? val.hashCode() : 0);
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(BinaryValueWithType.class, this);
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
index 6e56942..51da04b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
@@ -231,8 +231,6 @@ import org.apache.ignite.internal.util.typedef.F;
      * @return Unwrapped object.
      */
     private Object unwrapBinary(Object o, boolean keepBinary, boolean cpy) {
-        if (kernalCtx.json().jsonObject(o))
-            return ((CacheObject)o).value(this, cpy);
         if (o instanceof Map.Entry) {
             Map.Entry entry = (Map.Entry)o;
 
@@ -255,6 +253,9 @@ import org.apache.ignite.internal.util.typedef.F;
         else if (o instanceof CacheObject) {
             CacheObject co = (CacheObject)o;
 
+            if (kernalCtx.json().jsonObject(co))
+                return kernalCtx.json().value(co);
+
             if (!keepBinary || co.isPlatformType())
                 return unwrapBinary(co.value(this, cpy), keepBinary, cpy);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNoopProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNoopProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNoopProcessor.java
index ff1762d..9bd81c4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNoopProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNoopProcessor.java
@@ -64,4 +64,9 @@ public class IgniteJsonNoopProcessor extends GridProcessorAdapter implements Ign
     @Override public Object field(Object obj, String fieldName) {
         return null;
     }
+
+    /** {@inheritDoc} */
+    @Override public Object value(Object obj) {
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessor.java
index 0c36307..59985f3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessor.java
@@ -68,4 +68,9 @@ public interface IgniteJsonProcessor extends GridProcessor {
      * @return Field value.
      */
     public Object field(Object obj, String fieldName);
+
+    /**
+     * @param obj Object.
+     */
+    public Object value(Object obj);
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index b75b132..91ad01d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -144,10 +144,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
     /** */
     private final GridQueryIndexing idx;
 
-    /** */
-    // TODO IGNITE-961
-    private TypeId jsonTypeId;
-
     /**
      * @param ctx Kernal context.
      */
@@ -279,14 +275,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
                         if (valCls != null)
                             altTypeId = new TypeId(ccfg.getName(), valCls);
                     }
-                    else if (ctx.json().jsonType(desc.keyClass()) || ctx.json().jsonType(desc.valueClass())) {
-                        // TODO IGNITE-961
-                        // processJsonMeta(meta, desc);
-
-                        typeId = new TypeId(ccfg.getName(), valCls);
-
-                        jsonTypeId = typeId;
-                    }
                     else {
                         processClassMeta(qryEntity, desc, coCtx);
 
@@ -676,47 +664,39 @@ public class GridQueryProcessor extends GridProcessorAdapter {
 
             TypeDescriptor desc;
 
-            // TODO IGNITE-961
-            if (ctx.json().jsonObject(val) && jsonTypeId != null) {
-                desc = types.get(jsonTypeId);
-
-                assert desc != null && desc.registered() : desc;
-            }
-            else {
-                Class<?> valCls = null;
+            Class<?> valCls = null;
 
-                TypeId id;
+            TypeId id;
 
-                boolean binaryVal = ctx.cacheObjects().isBinaryObject(val);
+            boolean binaryVal = ctx.cacheObjects().isBinaryObject(val);
 
-                if (binaryVal) {
-                    int typeId = ctx.cacheObjects().typeId(val);
+            if (binaryVal) {
+                int typeId = ctx.cacheObjects().typeId(val);
 
-                    id = new TypeId(space, typeId);
-                }
-                else {
-                    valCls = val.value(coctx, false).getClass();
+                id = new TypeId(space, typeId);
+            }
+            else {
+                valCls = val.value(coctx, false).getClass();
 
-                    id = new TypeId(space, valCls);
-                }
+                id = new TypeId(space, valCls);
+            }
 
-                desc = types.get(id);
+            desc = types.get(id);
 
-                if (desc == null || !desc.registered())
-                    return;
+            if (desc == null || !desc.registered())
+                return;
 
-                if (!binaryVal && !desc.valueClass().isAssignableFrom(valCls))
-                    throw new IgniteCheckedException("Failed to update index due to class name conflict" +
-                        "(multiple classes with same simple name are stored in the same cache) " +
-                        "[expCls=" + desc.valueClass().getName() + ", actualCls=" + valCls.getName() + ']');
+            if (!binaryVal && !desc.valueClass().isAssignableFrom(valCls))
+                throw new IgniteCheckedException("Failed to update index due to class name conflict" +
+                    "(multiple classes with same simple name are stored in the same cache) " +
+                    "[expCls=" + desc.valueClass().getName() + ", actualCls=" + valCls.getName() + ']');
 
-                if (!ctx.cacheObjects().isBinaryObject(key)) {
-                    Class<?> keyCls = key.value(coctx, false).getClass();
+            if (!ctx.cacheObjects().isBinaryObject(key)) {
+                Class<?> keyCls = key.value(coctx, false).getClass();
 
-                    if (!desc.keyClass().isAssignableFrom(keyCls))
-                        throw new IgniteCheckedException("Failed to update index, incorrect key class [expCls=" +
-                            desc.keyClass().getName() + ", actualCls=" + keyCls.getName() + "]");
-                }
+                if (!desc.keyClass().isAssignableFrom(keyCls))
+                    throw new IgniteCheckedException("Failed to update index, incorrect key class [expCls=" +
+                        desc.keyClass().getName() + ", actualCls=" + keyCls.getName() + "]");
             }
 
             idx.store(space, desc, key, val, ver, expirationTime);

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
index 0e5d078..e85ce9f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
@@ -445,6 +445,7 @@ public class GridRestProcessor extends GridProcessorAdapter {
             addHandler(new DataStructuresCommandHandler(ctx));
             addHandler(new QueryCommandHandler(ctx));
             addHandler(new GridLogCommandHandler(ctx));
+            addHandler(new IgniteScriptingCommandHandler(ctx));
 
             // Start protocols.
             startTcpProtocol();
@@ -469,7 +470,10 @@ public class GridRestProcessor extends GridProcessorAdapter {
                 }
             }
         }
+    }
 
+    /** {@inheritDoc} */
+    @Override public void onKernalStart() throws IgniteCheckedException {
         if (isRestEnabled()) {
             for (GridRestProtocol proto : protos)
                 proto.onKernalStart();
@@ -482,15 +486,6 @@ public class GridRestProcessor extends GridProcessorAdapter {
 
             if (log.isDebugEnabled())
                 log.debug("REST processor started.");
-
-            // Register handlers.
-            addHandler(new GridCacheCommandHandler(ctx));
-            addHandler(new GridTaskCommandHandler(ctx));
-            addHandler(new GridTopologyCommandHandler(ctx));
-            addHandler(new GridVersionNameCommandHandler(ctx));
-            addHandler(new DataStructuresCommandHandler(ctx));
-            addHandler(new QueryCommandHandler(ctx));
-            addHandler(new IgniteScriptingCommandHandler(ctx));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArray.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArray.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArray.java
index 2f568ec..420c472 100644
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArray.java
+++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArray.java
@@ -18,31 +18,44 @@
 package org.apache.ignite.internal.processors.json;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
 import javax.json.JsonArray;
 import javax.json.JsonNumber;
+import javax.json.JsonObject;
 import javax.json.JsonString;
 import javax.json.JsonValue;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.jetbrains.annotations.NotNull;
+
+import static org.apache.ignite.internal.processors.json.IgniteJsonUtils.toJsonValue;
 
 /**
  * Implementation of JsonArray
  */
-public class IgniteJsonArray extends ArrayList<JsonValue> implements JsonArray, Serializable {
+public class IgniteJsonArray implements JsonArray, Serializable {
+    /** Empty array. */
+    private static final Object[] EMPTY_ARR = new Object[0];
+
     /** Values for getValueAs. */
-    private List<JsonValue> val;
+    private List<Object> list;
 
     /**
      * @param val List json values.
      */
-    public IgniteJsonArray(List<JsonValue> val) {
-        super(val);
+    public IgniteJsonArray(List<Object> val) {
+        this.list = Collections.unmodifiableList(val);
     }
 
     /** {@inheritDoc} */
-    @Override public IgniteJsonObject getJsonObject(int idx) {
-        return (IgniteJsonObject)get(idx);
+    @Override public JsonObject getJsonObject(int idx) {
+        return (JsonObject)get(idx);
     }
 
     /** {@inheritDoc} */
@@ -63,15 +76,7 @@ public class IgniteJsonArray extends ArrayList<JsonValue> implements JsonArray,
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Override public <T extends JsonValue> List<T> getValuesAs(Class<T> clazz) {
-        if (val == null) {
-            val = new ArrayList(this.size());
-
-            for (int i = 0; i < size(); ++i)
-                val.add(get(i));
-
-            val = Collections.unmodifiableList(val);
-        }
-        return (List<T>) val;
+        return toJsonValueList(list);
     }
 
     /** {@inheritDoc} */
@@ -107,10 +112,10 @@ public class IgniteJsonArray extends ArrayList<JsonValue> implements JsonArray,
     @Override public boolean getBoolean(int idx) {
         JsonValue val = get(idx);
 
-        if (val.equals(JsonValue.TRUE))
+        if (val == JsonValue.TRUE)
             return true;
 
-        if (val.equals(JsonValue.FALSE))
+        if (val == JsonValue.FALSE)
             return false;
 
         throw new ClassCastException();
@@ -118,20 +123,345 @@ public class IgniteJsonArray extends ArrayList<JsonValue> implements JsonArray,
 
     /** {@inheritDoc} */
     @Override public boolean getBoolean(int idx, boolean dfltVal) {
-        try {
-            return getBoolean(idx);
-        } catch (Exception e) {
+        if (idx >= list.size())
             return dfltVal;
-        }
+
+        JsonValue val = get(idx);
+
+        if (val == JsonValue.TRUE)
+            return true;
+
+        if (val == JsonValue.FALSE)
+            return false;
+
+        return dfltVal;
     }
 
     /** {@inheritDoc} */
     @Override public boolean isNull(int idx) {
-        return get(idx).equals(JsonValue.NULL);
+        return get(idx) == JsonValue.NULL;
     }
 
     /** {@inheritDoc} */
     @Override public ValueType getValueType() {
         return ValueType.ARRAY;
     }
+
+    /** {@inheritDoc} */
+    @Override public int size() {
+        return list.size();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isEmpty() {
+        return list.isEmpty();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean contains(Object obj) {
+        return indexOf(obj) > -1;
+    }
+
+    /**
+     * @param val {@code JsonNumber} instance.
+     */
+    private int indexOf(JsonNumber val, boolean last) {
+        for (int i = last ? list.size() - 1 : 0;
+            (last && i > 0) || i < list.size(); i += last ? -1 : 1) {
+            Object obj = list.get(i);
+
+            if (obj instanceof Number &&
+                (obj instanceof Integer && obj.equals(val.intValue()) ||
+                    obj instanceof Long && obj.equals(val.longValue()) ||
+                    obj instanceof Double && obj.equals(val.doubleValue()) ||
+                    obj instanceof BigInteger && obj.equals(val.bigIntegerValue()) ||
+                    obj instanceof BigDecimal && obj.equals(val.bigDecimalValue())))
+                return i;
+        }
+
+        return -1;
+    }
+
+    /** {@inheritDoc} */
+    @NotNull @Override public Iterator<JsonValue> iterator() {
+        return new ImmutableIterator();
+    }
+
+    /** {@inheritDoc} */
+    @NotNull @Override public Object[] toArray() {
+        return toArray(EMPTY_ARR);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @NotNull @Override public <T> T[] toArray(T[] arr) {
+        arr = (T[])new Object[list.size()];
+
+        for (int i = 0; i < list.size(); i++)
+            arr[i] = (T)toJsonValue(list.get(i));
+
+        return arr;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean add(JsonValue val) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean remove(Object o) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean containsAll(Collection<?> col) {
+        for (Object e : col) {
+            if (!contains(e))
+                return false;
+        }
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean addAll(Collection<? extends JsonValue> c) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean addAll(int idx, Collection<? extends JsonValue> c) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean removeAll(Collection<?> c) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean retainAll(Collection<?> c) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public JsonValue get(int idx) {
+        Object val = list.get(idx);
+
+        return val == null ? JsonValue.NULL : toJsonValue(val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public JsonValue set(int idx, JsonValue element) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void add(int idx, JsonValue element) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public JsonValue remove(int idx) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int indexOf(Object obj) {
+        A.notNull(obj, "obj");
+
+        JsonValue val = (JsonValue)obj;
+
+        JsonValue.ValueType valType = val.getValueType();
+
+        switch (valType) {
+            case ARRAY:
+                return list.indexOf(((IgniteJsonArray)val).list());
+
+            case OBJECT:
+                return list.indexOf(((IgniteJsonObject)val).binaryObject());
+
+            case STRING:
+                return list.indexOf(((JsonString)val).getString());
+
+            case NUMBER:
+                return indexOf((JsonNumber)val, false);
+
+            case TRUE:
+                return list.indexOf(Boolean.TRUE);
+
+            case FALSE:
+                return list.indexOf(Boolean.FALSE);
+
+            case NULL:
+                return list.indexOf(null);
+
+            default:
+                throw new IllegalArgumentException("Unknown value type " + valType);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public int lastIndexOf(Object obj) {
+        A.notNull(obj, "obj");
+
+        JsonValue val = (JsonValue)obj;
+
+        JsonValue.ValueType valType = val.getValueType();
+
+        switch (valType) {
+            case ARRAY:
+                return list.lastIndexOf(((IgniteJsonArray)val).list());
+
+            case OBJECT:
+                return list.lastIndexOf(((IgniteJsonObject)val).binaryObject());
+
+            case STRING:
+                return list.lastIndexOf(((JsonString)val).getString());
+
+            case NUMBER:
+                return indexOf((JsonNumber)val, true);
+
+            case TRUE:
+                return list.lastIndexOf(Boolean.TRUE);
+
+            case FALSE:
+                return list.lastIndexOf(Boolean.FALSE);
+
+            case NULL:
+                return list.lastIndexOf(null);
+
+            default:
+                throw new IllegalArgumentException("Unknown value type " + valType);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @NotNull @Override public ListIterator<JsonValue> listIterator() {
+        return new ImmutableIterator();
+    }
+
+    /** {@inheritDoc} */
+    @NotNull @Override public ListIterator<JsonValue> listIterator(int idx) {
+        return new ImmutableIterator(idx);
+    }
+
+    /** {@inheritDoc} */
+    @NotNull @Override public List<JsonValue> subList(int fromIdx, int toIdx) {
+        return toJsonValueList(list.subList(fromIdx, toIdx));
+    }
+
+    /**
+     * Returns backing list.
+     *
+     * @return Backing list.
+     */
+    List<Object> list() {
+        return list;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        IgniteJsonArray arr = (IgniteJsonArray)o;
+
+        return list.equals(arr.list);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        return list.hashCode();
+    }
+
+    /**
+     * @param l Object list.
+     */
+    @SuppressWarnings("unchecked")
+    private static <T> List<T> toJsonValueList(List<Object> l) {
+        if (l.isEmpty())
+            return Collections.emptyList();
+
+        List<T> res = new ArrayList<>();
+
+        for (Object val : l)
+            res.add((T)toJsonValue(val));
+
+        return Collections.unmodifiableList(res);
+    }
+
+    /**
+     * Immutable list iterator.
+     */
+    private class ImmutableIterator implements ListIterator<JsonValue> {
+        /** Backing list iterator. */
+        final ListIterator<Object> it;
+
+        /**
+         * Default constructor.
+         */
+        public ImmutableIterator() {
+            this(0);
+        }
+
+        /**
+         * @param idx Index.
+         */
+        public ImmutableIterator(int idx) {
+            it = list.listIterator(idx);
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean hasNext() {
+            return it.hasNext();
+        }
+
+        /** {@inheritDoc} */
+        @Override public JsonValue next() {
+            return toJsonValue(it.next());
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean hasPrevious() {
+            return it.hasPrevious();
+        }
+
+        /** {@inheritDoc} */
+        @Override public JsonValue previous() {
+            return toJsonValue(it.previous());
+        }
+
+        /** {@inheritDoc} */
+        @Override public int nextIndex() {
+            return it.nextIndex();
+        }
+
+        /** {@inheritDoc} */
+        @Override public int previousIndex() {
+            return it.previousIndex();
+        }
+
+        /** {@inheritDoc} */
+        @Override public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        /** {@inheritDoc} */
+        @Override public void set(JsonValue val) {
+            throw new UnsupportedOperationException();
+        }
+
+        /** {@inheritDoc} */
+        @Override public void add(JsonValue val) {
+            throw new UnsupportedOperationException();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilder.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilder.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilder.java
index 8da9da2..772bb65 100644
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilder.java
+++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilder.java
@@ -23,7 +23,9 @@ import java.util.ArrayList;
 import java.util.List;
 import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
+import javax.json.JsonNumber;
 import javax.json.JsonObjectBuilder;
+import javax.json.JsonString;
 import javax.json.JsonValue;
 import org.apache.ignite.internal.util.typedef.internal.A;
 
@@ -31,104 +33,144 @@ import org.apache.ignite.internal.util.typedef.internal.A;
  * Json array builder.
  */
 public class IgniteJsonArrayBuilder implements JsonArrayBuilder {
-    /** Json array list. */
-    private List<JsonValue> jsonList = new ArrayList<>();
+    /** Values list. */
+    private List<Object> list = new ArrayList<>();
 
     /** {@inheritDoc} */
     @Override public JsonArrayBuilder add(JsonValue val) {
         A.notNull(val, "value");
 
-        jsonList.add(val);
+        JsonValue.ValueType valType = val.getValueType();
+
+        switch (valType) {
+            case ARRAY:
+                list.add(((IgniteJsonArray)val).list());
+
+                break;
+
+            case OBJECT:
+                list.add(((IgniteJsonObject)val).binaryObject());
+
+                break;
+            case STRING:
+                list.add(((JsonString)val).getString());
+
+                break;
+            case NUMBER:
+                //TODO: Optimize for value
+                list.add(((JsonNumber)val).bigDecimalValue());
+
+                break;
+            case TRUE:
+                list.add(true);
+
+                break;
+            case FALSE:
+                list.add(false);
+
+                break;
+            case NULL:
+                list.add(null);
+
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown value type " + valType);
+        }
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public JsonArrayBuilder add(String val) {
-        A.notNull(val, "value");
+        A.notNull(val, "val");
 
-        jsonList.add(new IgniteJsonString(val));
+        list.add(val);
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public JsonArrayBuilder add(BigDecimal val) {
-        A.notNull(val, "value");
+        A.notNull(val, "val");
 
-        jsonList.add(new IgniteJsonNumber(val));
+        list.add(val);
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public JsonArrayBuilder add(BigInteger val) {
-        A.notNull(val, "value");
+        A.notNull(val, "val");
 
-        //TODO: optimize for value
-        jsonList.add(new IgniteJsonNumber(new BigDecimal(val)));
+        list.add(val);
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public JsonArrayBuilder add(int val) {
-        //TODO: optimize for value
-        jsonList.add(new IgniteJsonNumber(new BigDecimal(val)));
+        list.add(val);
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public JsonArrayBuilder add(long val) {
-        //TODO: optimize for value
-        jsonList.add(new IgniteJsonNumber(new BigDecimal(val)));
+        list.add(val);
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public JsonArrayBuilder add(double val) {
-        //TODO: optimize for value
-        jsonList.add(new IgniteJsonNumber(new BigDecimal(val)));
+        list.add(val);
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public JsonArrayBuilder add(boolean val) {
-        jsonList.add(val ? JsonValue.TRUE : JsonValue.FALSE);
+        list.add(val);
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public JsonArrayBuilder addNull() {
-        jsonList.add(JsonValue.NULL);
+        list.add(null);
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public JsonArrayBuilder add(JsonObjectBuilder bld) {
-        A.notNull(bld, "value");
+        A.notNull(bld, "bld");
 
-        jsonList.add(bld.build());
+        list.add(((IgniteJsonObject)bld.build()).binaryObject());
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public JsonArrayBuilder add(JsonArrayBuilder bld) {
-        A.notNull(bld, "value");
+        A.notNull(bld, "bld");
 
-        jsonList.add(bld.build());
+        list.add(((IgniteJsonArrayBuilder)bld).list());
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public JsonArray build() {
-        return new IgniteJsonArray(jsonList);
+          return new IgniteJsonArray(list);
+    }
+
+    /**
+     * Returns backing objects list.
+     *
+     * @return backing objects list.
+     */
+    List<Object> list() {
+        return list;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonGenerator.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonGenerator.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonGenerator.java
index f432887..4298fe4 100644
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonGenerator.java
+++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonGenerator.java
@@ -39,7 +39,8 @@ public class IgniteJsonGenerator implements JsonGenerator {
     /** Writer. */
     private final BufferedWriter writer;
 
-    private LinkedList<Element> ctx = new LinkedList();
+    /** Context. */
+    private LinkedList<Element> ctx = new LinkedList<>();
 
     /**
      * @param writer Writer.

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonLocation.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonLocation.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonLocation.java
index 791aa91..fa364e8 100644
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonLocation.java
+++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonLocation.java
@@ -20,7 +20,7 @@ package org.apache.ignite.internal.processors.json;
 import javax.json.stream.JsonLocation;
 
 /**
- * Json location implementation.
+ * JSON location implementation.
  */
 public class IgniteJsonLocation implements JsonLocation {
     /** Column number. */

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonMessageFactory.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonMessageFactory.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonMessageFactory.java
deleted file mode 100644
index 0186064..0000000
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonMessageFactory.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.ignite.internal.processors.json;
-
-import org.apache.ignite.plugin.extensions.communication.Message;
-import org.apache.ignite.plugin.extensions.communication.MessageFactory;
-import org.jetbrains.annotations.Nullable;
-
-/**
- *
- */
-public class IgniteJsonMessageFactory implements MessageFactory {
-    /** {@inheritDoc} */
-    @Nullable @Override public Message create(byte type) {
-        switch (type) {
-            case -23:
-                return new JsonCacheObject();
-        }
-
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNumber.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNumber.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNumber.java
index 566d4a8..b12001c 100644
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNumber.java
+++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonNumber.java
@@ -23,7 +23,7 @@ import java.math.BigInteger;
 import javax.json.JsonNumber;
 
 /**
- * Json number implementation.
+ * JSON number implementation.
  *
  * TODO IGNITE-962: optimize for int, long, double.
  */

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObject.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObject.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObject.java
index b14e346..39b4a7c 100644
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObject.java
+++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObject.java
@@ -18,22 +18,49 @@
 package org.apache.ignite.internal.processors.json;
 
 import java.io.Serializable;
-import java.util.HashMap;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import javax.json.JsonArray;
 import javax.json.JsonNumber;
+import javax.json.JsonObject;
 import javax.json.JsonString;
 import javax.json.JsonValue;
+import org.apache.ignite.binary.BinaryObject;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.jetbrains.annotations.NotNull;
+
+import static org.apache.ignite.internal.processors.json.IgniteJsonUtils.toJsonValue;
 
 /**
  * IgniteJsonObject implementation.
  */
-public class IgniteJsonObject extends HashMap<String, JsonValue> implements javax.json.JsonObject, Serializable {
+public class IgniteJsonObject implements javax.json.JsonObject, Serializable {
+    /** Bin object. */
+    private final BinaryObject binObj;
+
+    /** Size. */
+    private int size;
+
     /**
-     * @param val Map to store.
+     * @param binObj Binary object.
      */
-    public IgniteJsonObject(Map<String, JsonValue> val) {
-        super(val);
+    public IgniteJsonObject(BinaryObject binObj) {
+        this(binObj, -1);
+    }
+
+    /**
+     * @param binObj Binary object.
+     * @param size Size.
+     */
+    public IgniteJsonObject(BinaryObject binObj, int size) {
+        this.binObj = binObj;
+        this.size = size;
     }
 
     /** {@inheritDoc} */
@@ -43,7 +70,7 @@ public class IgniteJsonObject extends HashMap<String, JsonValue> implements java
 
     /** {@inheritDoc} */
     @Override public javax.json.JsonObject getJsonObject(String name) {
-        return (javax.json.JsonObject)get(name);
+        return (JsonObject)get(name);
     }
 
     /** {@inheritDoc} */
@@ -90,10 +117,13 @@ public class IgniteJsonObject extends HashMap<String, JsonValue> implements java
     @Override public boolean getBoolean(String name) {
         JsonValue val = get(name);
 
-        if (val.equals(JsonValue.TRUE))
+        if (val == null)
+            throw new NullPointerException();
+
+        if (val == JsonValue.TRUE)
             return true;
 
-        if (val.equals(JsonValue.FALSE))
+        if (val == JsonValue.FALSE)
             return false;
 
         throw new ClassCastException();
@@ -101,17 +131,25 @@ public class IgniteJsonObject extends HashMap<String, JsonValue> implements java
 
     /** {@inheritDoc} */
     @Override public boolean getBoolean(String name, boolean dfltVal) {
-        try {
-            return getBoolean(name);
-        }
-        catch (Exception e) {
-            return dfltVal;
-        }
+        JsonValue val = get(name);
+
+        if (val == JsonValue.TRUE)
+            return true;
+
+        if (val == JsonValue.FALSE)
+            return false;
+
+        return dfltVal;
     }
 
     /** {@inheritDoc} */
     @Override public boolean isNull(String name) {
-        return get(name).equals(JsonValue.NULL);
+        JsonValue val = get(name);
+
+        if (val == null)
+            throw new NullPointerException();
+
+        return val == JsonValue.NULL;
     }
 
     /** {@inheritDoc} */
@@ -119,16 +157,148 @@ public class IgniteJsonObject extends HashMap<String, JsonValue> implements java
         return ValueType.OBJECT;
     }
 
-    /** {@inheritDoc}*/
+    /** {@inheritDoc} */
+    @Override public int size() {
+        if (size == -1) {
+            for (String field : binObj.type().fieldNames()) {
+                if (binObj.hasField(field))
+                    size++;
+            }
+
+            size++;
+        }
+
+        return size;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean containsKey(Object key) {
+        A.notNull(key, "key");
+
+        return binObj.hasField((String)key);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean containsValue(Object val) {
+        A.notNull(val, "val");
+
+        JsonValue val0 = (JsonValue)val;
+
+        for (String key : binObj.type().fieldNames()) {
+            Object field = binObj.field(key);
+
+            if (field == null && val0 == JsonValue.NULL && binObj.hasField(key) ||
+                field != null && toJsonValue(field).equals(val))
+                return true;
+        }
+
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public JsonValue get(Object key) {
+        A.notNull(key, "key");
+
+        Object val = binObj.field((String)key);
+
+        if (val == null)
+            return binObj.hasField((String)key) ? JsonValue.NULL : null;
+
+        return toJsonValue(val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public JsonValue put(String key, JsonValue val) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public JsonValue remove(Object key) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void putAll(Map<? extends String, ? extends JsonValue> m) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    //TODO: Preserve iteration order. See JsonObject#keySet javadoc.
+    @NotNull @Override public Set<String> keySet() {
+        if (isEmpty())
+            return Collections.emptySet();
+
+        Set<String> keys = new HashSet<>();
+
+        for (String name : binObj.type().fieldNames()) {
+            if (binObj.hasField(name))
+                keys.add(name);
+        }
+
+        return Collections.unmodifiableSet(keys);
+    }
+
+    /** {@inheritDoc} */
+    //TODO: Preserve iteration order. See JsonObject#values javadoc.
+    @NotNull @Override public Collection<JsonValue> values() {
+        if (isEmpty())
+            return Collections.emptyList();
+
+        List<JsonValue> vals = new ArrayList<>();
+
+        for (String name : binObj.type().fieldNames()) {
+            if (binObj.hasField(name))
+                vals.add(toJsonValue(binObj.field(name)));
+        }
+
+        return Collections.unmodifiableList(vals);
+    }
+
+    /** {@inheritDoc} */
+    //TODO: Preserve iteration order. See JsonObject#entrySet javadoc.
+    @NotNull @Override public Set<Entry<String, JsonValue>> entrySet() {
+        if (isEmpty())
+            return Collections.emptySet();
+
+        Set<Entry<String, JsonValue>> entries = new HashSet<>();
+
+        for (String name : binObj.type().fieldNames()) {
+            if (binObj.hasField(name))
+                entries.add(new AbstractMap.SimpleImmutableEntry<>(name, toJsonValue(binObj.field(name))));
+        }
+
+        return Collections.unmodifiableSet(entries);
+    }
+
+    /**
+     * Returns backing {@link BinaryObject} instance.
+     *
+     * @return Backing {@link BinaryObject} instance.
+     */
+    BinaryObject binaryObject() {
+        return binObj;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean equals(Object o) {
         if (o == null || !(o instanceof IgniteJsonObject))
             return false;
 
-        return super.equals(o);
+        return binObj.equals(((IgniteJsonObject)o).binObj);
     }
 
-    /** {@inheritDoc}*/
+    /** {@inheritDoc} */
     @Override public int hashCode() {
-        return super.hashCode();
+        return binObj.hashCode();
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObjectBuilder.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObjectBuilder.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObjectBuilder.java
index 784b291..f6fa26a 100644
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObjectBuilder.java
+++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonObjectBuilder.java
@@ -19,25 +19,70 @@ package org.apache.ignite.internal.processors.json;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.util.HashMap;
 import java.util.Map;
 import javax.json.JsonArrayBuilder;
+import javax.json.JsonNumber;
+import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
+import javax.json.JsonString;
 import javax.json.JsonValue;
+import org.apache.ignite.binary.BinaryObjectBuilder;
+import org.apache.ignite.internal.IgniteKernal;
+import org.apache.ignite.internal.binary.builder.BinaryObjectBuilderImpl;
 import org.apache.ignite.internal.util.typedef.internal.A;
 
 /**
  * JSON object builder implementation.
  */
 public class IgniteJsonObjectBuilder implements JsonObjectBuilder {
-    /** JSON object map. */
-    private Map<String, JsonValue> jsonMap = new HashMap<>();
+    /** Binary object builder. */
+    private final BinaryObjectBuilder binObjBuilder;
+
+    /**
+     * @param kernal Kernal.
+     */
+    public IgniteJsonObjectBuilder(IgniteKernal kernal) {
+        this.binObjBuilder = kernal.binary().builder(JsonObject.class.getName());
+    }
 
     /** {@inheritDoc} */
     @Override public JsonObjectBuilder add(String name, JsonValue val) {
         A.notNull(name, "name", val, "val");
 
-        jsonMap.put(name, val);
+        JsonValue.ValueType valType = val.getValueType();
+
+        switch (valType) {
+            case ARRAY:
+                binObjBuilder.setField(name, ((IgniteJsonArray)val).list(), Object.class);
+
+                break;
+            case OBJECT:
+                binObjBuilder.setField(name, ((IgniteJsonObject)val).binaryObject(), Object.class);
+
+                break;
+            case STRING:
+                add(name, ((JsonString)val).getString());
+
+                break;
+            case NUMBER:
+                add(name, ((JsonNumber)val).bigDecimalValue());
+
+                break;
+            case TRUE:
+                add(name, true);
+
+                break;
+            case FALSE:
+                add(name, false);
+
+                break;
+            case NULL:
+                addNull(name);
+
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown value type " + valType);
+        }
 
         return this;
     }
@@ -46,7 +91,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder {
     @Override public JsonObjectBuilder add(String name, String val) {
         A.notNull(name, "name", val, "val");
 
-        jsonMap.put(name, new IgniteJsonString(val));
+        binObjBuilder.setField(name, val, Object.class);
 
         return this;
     }
@@ -55,8 +100,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder {
     @Override public JsonObjectBuilder add(String name, BigInteger val) {
         A.notNull(name, "name", val, "val");
 
-        //TODO: optimize for value
-        jsonMap.put(name, new IgniteJsonNumber(new BigDecimal(val)));
+        binObjBuilder.setField(name, val, Object.class);
 
         return this;
     }
@@ -65,8 +109,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder {
     @Override public JsonObjectBuilder add(String name, BigDecimal val) {
         A.notNull(name, "name", val, "val");
 
-        //TODO: optimize for value
-        jsonMap.put(name, new IgniteJsonNumber(val));
+        binObjBuilder.setField(name, val, Object.class);
 
         return this;
     }
@@ -75,8 +118,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder {
     @Override public JsonObjectBuilder add(String name, int val) {
         A.notNull(name, "name");
 
-        //TODO: optimize for value
-        jsonMap.put(name, new IgniteJsonNumber(new BigDecimal(val)));
+        binObjBuilder.setField(name, val, Object.class);
 
         return this;
     }
@@ -85,8 +127,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder {
     @Override public JsonObjectBuilder add(String name, long val) {
         A.notNull(name, "name");
 
-        //TODO: optimize for value
-        jsonMap.put(name, new IgniteJsonNumber(new BigDecimal(val)));
+        binObjBuilder.setField(name, val, Object.class);
 
         return this;
     }
@@ -95,8 +136,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder {
     @Override public JsonObjectBuilder add(String name, double val) {
         A.notNull(name, "name");
 
-        //TODO: optimize for value
-        jsonMap.put(name, new IgniteJsonNumber(new BigDecimal(val)));
+        binObjBuilder.setField(name, val, Object.class);
 
         return this;
     }
@@ -105,7 +145,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder {
     @Override public JsonObjectBuilder add(String name, boolean val) {
         A.notNull(name, "name");
 
-        jsonMap.put(name, val ? JsonValue.TRUE : JsonValue.FALSE);
+        binObjBuilder.setField(name, val, Object.class);
 
         return this;
     }
@@ -114,7 +154,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder {
     @Override public JsonObjectBuilder addNull(String name) {
         A.notNull(name, "name");
 
-        jsonMap.put(name, JsonValue.NULL);
+        binObjBuilder.setField(name, null, Object.class);
 
         return this;
     }
@@ -123,7 +163,7 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder {
     @Override public JsonObjectBuilder add(String name, JsonObjectBuilder builder) {
         A.notNull(name, "name", builder, "builder");
 
-        jsonMap.put(name, builder.build());
+        binObjBuilder.setField(name, ((IgniteJsonObject)builder.build()).binaryObject(), Object.class);
 
         return this;
     }
@@ -132,13 +172,25 @@ public class IgniteJsonObjectBuilder implements JsonObjectBuilder {
     @Override public JsonObjectBuilder add(String name, JsonArrayBuilder builder) {
         A.notNull(name, "name", builder, "builder");
 
-        jsonMap.put(name, builder.build());
+        binObjBuilder.setField(name, ((IgniteJsonArrayBuilder)builder).list(), Object.class);
 
         return this;
     }
 
     /** {@inheritDoc} */
     @Override public javax.json.JsonObject build() {
-        return new IgniteJsonObject(jsonMap);
+        //TODO: user defined hashCode()
+        int h = 0;
+
+        Map<String, Object> assignedVals = ((BinaryObjectBuilderImpl)binObjBuilder).assignedVals();
+
+        if (assignedVals != null) {
+            for (Map.Entry<String, Object> e : assignedVals.entrySet())
+                h += e.getKey().hashCode() ^ e.getValue().hashCode();
+        }
+
+        binObjBuilder.hashCode(h);
+
+        return new IgniteJsonObject(binObjBuilder.build(), assignedVals == null ? 0 : assignedVals.size());
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessorImpl.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessorImpl.java
index 1f599bb..292b648 100644
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessorImpl.java
+++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProcessorImpl.java
@@ -22,6 +22,7 @@ import javax.json.JsonObject;
 import javax.json.JsonString;
 import javax.json.JsonValue;
 import org.apache.ignite.IgniteException;
+import org.apache.ignite.binary.BinaryObject;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
 import org.apache.ignite.internal.processors.cache.CacheObject;
@@ -30,7 +31,7 @@ import org.apache.ignite.internal.processors.cache.KeyCacheObject;
 import org.jetbrains.annotations.Nullable;
 
 /**
- *
+ * Ignite JSON objects processor.
  */
 public class IgniteJsonProcessorImpl extends GridProcessorAdapter implements IgniteJsonProcessor {
     /**
@@ -42,8 +43,13 @@ public class IgniteJsonProcessorImpl extends GridProcessorAdapter implements Ign
 
     /** {@inheritDoc} */
     @Override public KeyCacheObject toCacheKeyObject(CacheObjectContext ctx, Object obj, boolean userObj) {
-        if (obj instanceof JsonObject)
-            return new JsonCacheObject((JsonObject)obj);
+        if (obj instanceof JsonObject) {
+            IgniteJsonObject jsonObj = (IgniteJsonObject)obj;
+
+            BinaryObject binObj = jsonObj.binaryObject();
+
+            return ctx.processor().toCacheKeyObject(ctx, binObj, userObj);
+        }
 
         return null;
     }
@@ -52,8 +58,13 @@ public class IgniteJsonProcessorImpl extends GridProcessorAdapter implements Ign
     @Nullable @Override public CacheObject toCacheObject(CacheObjectContext ctx,
         @Nullable Object obj,
         boolean userObj) {
-        if (obj instanceof JsonObject)
-            return new JsonCacheObject((JsonObject)obj);
+        if (obj instanceof JsonObject) {
+            IgniteJsonObject jsonObj = (IgniteJsonObject)obj;
+
+            BinaryObject binObj = jsonObj.binaryObject();
+
+            return ctx.processor().toCacheObject(ctx, binObj, userObj);
+        }
 
         return null;
     }
@@ -65,23 +76,26 @@ public class IgniteJsonProcessorImpl extends GridProcessorAdapter implements Ign
 
     /** {@inheritDoc} */
     @Override public boolean jsonObject(Object obj) {
-        return obj instanceof JsonCacheObject || obj instanceof JsonObject;
+        return obj instanceof JsonObject || obj instanceof BinaryObject &&
+            ((BinaryObject)obj).type().typeName().equals(JsonObject.class.getName());
     }
 
     /** {@inheritDoc} */
     @Override public boolean hasField(Object obj, String fieldName) {
-        if (obj instanceof JsonObject)
-            return ((JsonObject)obj).containsKey(fieldName);
-
-        return ((JsonCacheObject)obj).hasField(fieldName);
+        return ((JsonObject)obj).containsKey(fieldName);
     }
 
     /** {@inheritDoc} */
     @Override public Object field(Object obj, String fieldName) {
-        if (obj instanceof JsonObject)
-            return value((JsonObject) obj, fieldName);
+        return value((JsonObject) obj, fieldName);
+    }
 
-        return ((JsonCacheObject)obj).field(fieldName);
+    /** {@inheritDoc} */
+    @Override public Object value(Object obj) {
+        if (obj instanceof BinaryObject)
+            return new IgniteJsonObject((BinaryObject)obj);
+
+        return null;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProvider.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProvider.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProvider.java
index 8734ec3..f022628 100644
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProvider.java
+++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonProvider.java
@@ -34,11 +34,22 @@ import javax.json.stream.JsonGenerator;
 import javax.json.stream.JsonGeneratorFactory;
 import javax.json.stream.JsonParser;
 import javax.json.stream.JsonParserFactory;
+import org.apache.ignite.internal.IgniteKernal;
 
 /**
  * JSON provider implementation.
  */
 public class IgniteJsonProvider extends JsonProvider {
+    /** Kernal. */
+    private final IgniteKernal kernal;
+
+    /**
+     * @param kernal Kernal.
+     */
+    public IgniteJsonProvider(IgniteKernal kernal) {
+        this.kernal = kernal;
+    }
+
     /** {@inheritDoc} */
     @Override public JsonParser createParser(Reader reader) {
         return null;
@@ -101,7 +112,7 @@ public class IgniteJsonProvider extends JsonProvider {
 
     /** {@inheritDoc} */
     @Override public JsonObjectBuilder createObjectBuilder() {
-        return new IgniteJsonObjectBuilder();
+        return new IgniteJsonObjectBuilder(kernal);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonString.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonString.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonString.java
index 96744d5..657ab4e 100644
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonString.java
+++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonString.java
@@ -21,7 +21,7 @@ import java.io.Serializable;
 import javax.json.JsonString;
 
 /**
- * Json string implementation.
+ * JSON string implementation.
  */
 public class IgniteJsonString implements JsonString, Serializable {
     /** Value. */

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonUtils.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonUtils.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonUtils.java
new file mode 100644
index 0000000..cf6d84a
--- /dev/null
+++ b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/IgniteJsonUtils.java
@@ -0,0 +1,58 @@
+/*
+ * 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.ignite.internal.processors.json;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.List;
+import javax.json.JsonValue;
+import org.apache.ignite.binary.BinaryObject;
+
+/**
+ * JSON related utils.
+ */
+public class IgniteJsonUtils {
+    /**
+     * @param val Value.
+     */
+    public static JsonValue toJsonValue(Object val) {
+        if (val == null)
+            return JsonValue.NULL;
+        else if (val instanceof Integer)
+            return new IgniteJsonNumber(new BigDecimal((Integer)val));
+        else if (val instanceof Long)
+            return new IgniteJsonNumber(new BigDecimal((Long)val));
+        else if (val instanceof Double)
+            return new IgniteJsonNumber(new BigDecimal((Double)val));
+        else if (val instanceof BigInteger)
+            return new IgniteJsonNumber(new BigDecimal((BigInteger)val));
+        else if (val instanceof BigDecimal)
+            return new IgniteJsonNumber((BigDecimal)val);
+        else if (val instanceof String)
+            return new IgniteJsonString((String)val);
+        else if (val instanceof Boolean)
+            return (Boolean)val ? JsonValue.TRUE : JsonValue.FALSE;
+        else if (val instanceof BinaryObject)
+            return new IgniteJsonObject((BinaryObject)val);
+        else if (val instanceof List)
+            return new IgniteJsonArray((List<Object>)val);
+        else
+            throw new IllegalArgumentException("Unknown value type: " + val.getClass().getName());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/internal/processors/json/JsonCacheObject.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/JsonCacheObject.java b/modules/json/src/main/java/org/apache/ignite/internal/processors/json/JsonCacheObject.java
deleted file mode 100644
index 977472e..0000000
--- a/modules/json/src/main/java/org/apache/ignite/internal/processors/json/JsonCacheObject.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.ignite.internal.processors.json;
-
-import javax.json.JsonObject;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.internal.processors.cache.CacheObject;
-import org.apache.ignite.internal.processors.cache.CacheObjectAdapter;
-import org.apache.ignite.internal.processors.cache.CacheObjectContext;
-import org.apache.ignite.internal.processors.cache.KeyCacheObject;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * TODO IGNITE-961
- */
-public class JsonCacheObject extends CacheObjectAdapter implements KeyCacheObject {
-    /**
-     *
-     */
-    public JsonCacheObject() {
-        // No-op.
-    }
-
-    /**
-     * @param obj Object.
-     */
-    public JsonCacheObject(JsonObject obj) {
-        this.val = obj;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean isPlatformType() {
-        // TODO IGNITE-961
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override public byte cacheObjectType() {
-        // TODO IGNITE-961
-        return 10;
-    }
-
-    /** {@inheritDoc} */
-    @Nullable @Override public <T> T value(CacheObjectContext ctx, boolean cpy) {
-        return (T)val;
-    }
-
-    /** {@inheritDoc} */
-    @Override public byte[] valueBytes(CacheObjectContext ctx) throws IgniteCheckedException {
-        return valBytes;
-    }
-
-    /** {@inheritDoc} */
-    @Override public CacheObject prepareForCache(CacheObjectContext ctx) {
-        return this;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void finishUnmarshal(CacheObjectContext ctx, ClassLoader ldr) throws IgniteCheckedException {
-        assert val != null || valBytes != null;
-
-        if (val == null)
-            val = ctx.processor().unmarshal(ctx, valBytes, ldr);
-    }
-
-    /** {@inheritDoc} */
-    @Override public void prepareMarshal(CacheObjectContext ctx) throws IgniteCheckedException {
-        if (valBytes == null)
-            valBytes = ctx.processor().marshal(ctx, val);
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean internal() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override public byte directType() {
-        return -23;
-    }
-
-    /**
-     * @param fieldName Field name.
-     * @return {@code True} if has field.
-     */
-    boolean hasField(String fieldName) {
-        return ((IgniteJsonObject)val).containsKey(fieldName);
-    }
-
-    /**
-     * @param fieldName Field name.
-     * @return Field value.
-     */
-    Object field(String fieldName) {
-        return IgniteJsonProcessorImpl.value((JsonObject)val, fieldName);
-    }
-
-    /** {@inheritDoc}*/
-    @Override public int hashCode() {
-        // TODO IGNITE-961
-        return val.hashCode();
-    }
-
-    /** {@inheritDoc}*/
-    @Override public boolean equals(Object obj) {
-        // TODO IGNITE-961
-        if (obj == null || !(obj instanceof JsonCacheObject))
-            return false;
-
-        return val.equals(((JsonCacheObject)obj).val);
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/main/java/org/apache/ignite/json/IgniteJson.java
----------------------------------------------------------------------
diff --git a/modules/json/src/main/java/org/apache/ignite/json/IgniteJson.java b/modules/json/src/main/java/org/apache/ignite/json/IgniteJson.java
index 983dc44..0515da6 100644
--- a/modules/json/src/main/java/org/apache/ignite/json/IgniteJson.java
+++ b/modules/json/src/main/java/org/apache/ignite/json/IgniteJson.java
@@ -19,6 +19,7 @@ package org.apache.ignite.json;
 
 import javax.json.spi.JsonProvider;
 import org.apache.ignite.Ignite;
+import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.processors.json.IgniteJsonProvider;
 
 /**
@@ -30,6 +31,6 @@ public class IgniteJson {
      * @return Ignite JSON API provider.
      */
     public static JsonProvider jsonProvider(Ignite ignite) {
-        return new IgniteJsonProvider();
+        return new IgniteJsonProvider((IgniteKernal)ignite);
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/2560c885/modules/json/src/test/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilderSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/json/src/test/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilderSelfTest.java b/modules/json/src/test/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilderSelfTest.java
new file mode 100644
index 0000000..4cbb839
--- /dev/null
+++ b/modules/json/src/test/java/org/apache/ignite/internal/processors/json/IgniteJsonArrayBuilderSelfTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.ignite.internal.processors.json;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.List;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonValue;
+import javax.json.spi.JsonProvider;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.json.IgniteJson;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Tests for {@link IgniteJsonArrayBuilder} implementation.
+ */
+public class IgniteJsonArrayBuilderSelfTest extends GridCommonAbstractTest {
+    /** JSON provider. */
+    private static JsonProvider json;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        super.beforeTestsStarted();
+
+        json = IgniteJson.jsonProvider(startGrid());
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        super.afterTestsStopped();
+
+        stopAllGrids();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAddJavaObjects() throws Exception {
+        JsonArray arr = json.createArrayBuilder()
+            .add(true)
+            .add(false)
+            .add(1)
+            .add(1L)
+            .add(1.0)
+            .add(new BigInteger("1"))
+            .add(new BigDecimal(1))
+            .add("string")
+            .build();
+
+        List<Object> list = ((IgniteJsonArray)arr).list();
+
+        assertEquals(JsonValue.TRUE, arr.get(0));
+        assertEquals(Boolean.TRUE, list.get(0));
+
+        assertEquals(JsonValue.FALSE, arr.get(1));
+        assertEquals(Boolean.FALSE, list.get(1));
+
+        assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(2));
+        assertEquals(1, list.get(2));
+
+        assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(3));
+        assertEquals(1L, list.get(3));
+
+        assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(4));
+        assertEquals(1.0, (Double)list.get(4), 0);
+
+        assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(5));
+        assertEquals(new BigInteger("1"), list.get(5));
+
+        assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(6));
+        assertEquals(new BigDecimal(1), list.get(6));
+
+        assertEquals(new IgniteJsonString("string"), arr.get(7));
+        assertEquals("string", list.get(7));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAddJsonObjects() throws Exception {
+        JsonArray arr = json.createArrayBuilder()
+            .addNull()
+            .add(JsonValue.NULL)
+            .add(JsonValue.TRUE)
+            .add(JsonValue.FALSE)
+            .add(new IgniteJsonNumber(new BigDecimal(1)))
+            .add(new IgniteJsonString("string"))
+            .add(json.createArrayBuilder().add(1).add(2).build())
+            .add(json.createArrayBuilder().add(1).add(2))
+            .add(json.createObjectBuilder().add("k1", 1).add("k2", 2).build())
+            .add(json.createObjectBuilder().add("k1", 1).add("k2", 2))
+            .build();
+
+        List<Object> list = ((IgniteJsonArray)arr).list();
+
+        assertEquals(JsonValue.NULL, arr.get(0));
+        assertNull(list.get(0));
+
+        assertEquals(JsonValue.NULL, arr.get(1));
+        assertNull(list.get(1));
+
+        assertEquals(JsonValue.TRUE, arr.get(2));
+        assertEquals(Boolean.TRUE, list.get(2));
+
+        assertEquals(JsonValue.FALSE, arr.get(3));
+        assertEquals(Boolean.FALSE, list.get(3));
+
+        assertEquals(new IgniteJsonNumber(new BigDecimal(1)), arr.get(4));
+        assertEquals(new BigDecimal(1), list.get(4));
+
+        assertEquals(new IgniteJsonString("string"), arr.get(5));
+        assertEquals("string", list.get(5));
+
+        assertEquals(json.createArrayBuilder().add(1).add(2).build(), arr.get(6));
+        assertEqualsCollections(F.asList(1, 2), (List)list.get(6));
+
+        assertEquals(json.createArrayBuilder().add(1).add(2).build(), arr.get(7));
+        assertEqualsCollections(F.asList(1, 2), (List)list.get(7));
+
+        JsonObject obj0 = json.createObjectBuilder().add("k1", 1).add("k2", 2).build();
+        assertEquals(obj0, arr.get(8));
+        assertEquals(((IgniteJsonObject)obj0).binaryObject(), list.get(8));
+
+        JsonObject obj1 = json.createObjectBuilder().add("k1", 1).add("k2", 2).build();
+        assertEquals(obj1, arr.get(9));
+        assertEquals(((IgniteJsonObject)obj1).binaryObject(), list.get(9));
+    }
+}
\ No newline at end of file