/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed 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.tapestry5.json;

import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.apache.tapestry5.json.exceptions.JSONTypeMismatchException;
import org.apache.tapestry5.json.exceptions.JSONValueNotFoundException;

// Note: this class was written without inspecting the non-free org.json sourcecode.

/**
 * A modifiable set of name/value mappings. Names are unique, non-null strings.
 * Values may be any mix of {@link JSONObject JSONObjects}, {@link JSONArray
 * JSONArrays}, Strings, Booleans, Integers, Longs, Doubles or {@link #NULL}.
 * Values may not be {@code null}, {@link Double#isNaN() NaNs}, {@link
 * Double#isInfinite() infinities}, or of any type not listed here.
 *
 * <p>This class can coerce values to another type when requested.
 * <ul>
 * <li>When the requested type is a boolean, strings will be coerced using a
 * case-insensitive comparison to "true" and "false".
 * <li>When the requested type is a double, other {@link Number} types will
 * be coerced using {@link Number#doubleValue() doubleValue}. Strings
 * that can be coerced using {@link Double#valueOf(String)} will be.
 * <li>When the requested type is an int, other {@link Number} types will
 * be coerced using {@link Number#intValue() intValue}. Strings
 * that can be coerced using {@link Double#valueOf(String)} will be,
 * and then cast to int.
 * <li><a name="lossy">When the requested type is a long, other {@link Number} types will
 * be coerced using {@link Number#longValue() longValue}. Strings
 * that can be coerced using {@link Double#valueOf(String)} will be,
 * and then cast to long. This two-step conversion is lossy for very
 * large values. For example, the string "9223372036854775806" yields the
 * long 9223372036854775807.</a>
 * <li>When the requested type is a String, other non-null values will be
 * coerced using {@link String#valueOf(Object)}. Although null cannot be
 * coerced, the sentinel value {@link JSONObject#NULL} is coerced to the
 * string "null".
 * </ul>
 *
 * <p>This class can look up both mandatory and optional values:
 * <ul>
 * <li>Use <code>get<i>Type</i>()</code> to retrieve a mandatory value. This
 * fails with a {@code RuntimeException} if the requested name has no value
 * or if the value cannot be coerced to the requested type.
 * <li>Use <code>opt()</code> to retrieve an optional value.
 * </ul>
 *
 * <p><strong>Warning:</strong> this class represents null in two incompatible
 * ways: the standard Java {@code null} reference, and the sentinel value {@link
 * JSONObject#NULL}. In particular, calling {@code put(name, null)} removes the
 * named entry from the object but {@code put(name, JSONObject.NULL)} stores an
 * entry whose value is {@code JSONObject.NULL}.
 *
 * <p>Instances of this class are not thread safe.
 */
public final class JSONObject extends JSONCollection implements Map<String, Object> {

    private static final long serialVersionUID = 1L;

    private static final Double NEGATIVE_ZERO = -0d;

    /**
     * A sentinel value used to explicitly define a name with no value. Unlike
     * {@code null}, names with this value:
     * <ul>
     * <li>show up in the {@link #names} array
     * <li>show up in the {@link #keys} iterator
     * <li>return {@code true} for {@link #has(String)}
     * <li>do not throw on {@link #get}
     * <li>are included in the encoded JSON string.
     * </ul>
     *
     * <p>This value violates the general contract of {@link Object#equals} by
     * returning true when compared to {@code null}. Its {@link #toString}
     * method returns "null".
     */
    public static final Object NULL = new Serializable() {

      private static final long serialVersionUID = 1L;

        @Override
        public boolean equals(Object o) {
            return o == this || o == null; // API specifies this broken equals implementation
        }

        // at least make the broken equals(null) consistent with Objects.hashCode(null).
        @Override
        public int hashCode() {
            return 0;
        }

        @Override
        public String toString() {
            return "null";
        }

        // Serialization magic: after de-serializing, it will be back to the singleton instance of NULL.
        private Object readResolve() throws ObjectStreamException
        {
            return NULL;
        }

    };

    private final LinkedHashMap<String, Object> nameValuePairs;

    /**
     * Creates a {@code JSONObject} with no name/value mappings.
     */
    public JSONObject() {
        nameValuePairs = new LinkedHashMap<String, Object>();
    }

    /**
     * Creates a new {@code JSONObject} with name/value mappings from the next
     * object in the tokener.
     *
     * @param readFrom a tokener whose nextValue() method will yield a
     *                 {@code JSONObject}.
     * @throws RuntimeException if the parse fails or doesn't yield a
     *                       {@code JSONObject}.
     */
    JSONObject(JSONTokener readFrom) {
        /*
         * Getting the parser to populate this could get tricky. Instead, just
         * parse to temporary JSONObject and then steal the data from that.
         */
        Object object = readFrom.nextValue(JSONObject.class);
        if (object instanceof JSONObject) {
            this.nameValuePairs = ((JSONObject) object).nameValuePairs;
        } else {
            throw JSONExceptionBuilder.tokenerTypeMismatch(object, JSONType.OBJECT);
        }
    }

    /**
     * Creates a new {@code JSONObject} with name/value mappings from the JSON
     * string.
     *
     * @param json a JSON-encoded string containing an object.
     * @throws RuntimeException if the parse fails or doesn't yield a {@code
     *                       JSONObject}.
     */
    public JSONObject(String json) {
        this(new JSONTokener(json));
    }

    /**
     * Creates a new {@code JSONObject} by copying mappings for the listed names
     * from the given object. Names that aren't present in {@code copyFrom} will
     * be skipped.
     *
     * @param copyFrom The source object.
     * @param names    The names of the fields to copy.
     * @throws RuntimeException On internal errors. Shouldn't happen.
     */
    public JSONObject(JSONObject copyFrom, String... names) {
        this();
        for (String name : names) {
            Object value = copyFrom.opt(name);
            if (value != null) {
                nameValuePairs.put(name, value);
            }
        }
    }


    /**
     * Returns a new JSONObject that is a shallow copy of this JSONObject.
     *
     * @since 5.4
     */
    public JSONObject copy()
    {
        JSONObject dupe = new JSONObject();
        dupe.nameValuePairs.putAll(nameValuePairs);

        return dupe;
    }

    /**
     * Constructs a new JSONObject using a series of String keys and object values.
     * Object values should be compatible with {@link #put(String, Object)}. Keys must be strings
     * (toString() will be invoked on each key).
     *
     * Prior to release 5.4, keysAndValues was type String...; changing it to Object... makes
     * it much easier to initialize a JSONObject in a single statement, which is more readable.
     *
     * @since 5.2.0
     */
    public JSONObject(Object... keysAndValues)
    {
        this();

        int i = 0;

        while (i < keysAndValues.length)
        {
            put(keysAndValues[i++].toString(), keysAndValues[i++]);
        }
    }

    /**
     * Returns the number of name/value mappings in this object.
     * 
     * @deprecated Use {@link #size()} instead.
     * @return the length of this.
     */
    @Deprecated
    public int length() {
        return nameValuePairs.size();
    }

    /**
     * Maps {@code name} to {@code value}, clobbering any existing name/value
     * mapping with the same name. If the value is {@code null}, any existing
     * mapping for {@code name} is removed.
     *
     * @param name  The name of the new value.
     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
     *              Integer, Long, Double, {@link #NULL}, or {@code null}. May not be
     *              {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
     *              infinities}.
     * @return this object.
     * @throws IllegalArgumentException if the value is an invalid double (infinite or NaN).
     */
    @Override
    public JSONObject put(String name, Object value) {
        if (value == null) {
            nameValuePairs.remove(name);
            return this;
        }
        JSON.testValidity(value);
        if (value instanceof Number) {
            // deviate from the original by checking all Numbers, not just floats & doubles
            JSON.checkDouble(((Number) value).doubleValue());
        }
        nameValuePairs.put(checkName(name), value);
        return this;
    }

    /**
     * Appends {@code value} to the array already mapped to {@code name}. If
     * this object has no mapping for {@code name}, this inserts a new mapping.
     * If the mapping exists but its value is not an array, the existing
     * and new values are inserted in order into a new array which is itself
     * mapped to {@code name}. In aggregate, this allows values to be added to a
     * mapping one at a time.
     *
     * Note that {@code append(String, Object)} provides better semantics.
     * In particular, the mapping for {@code name} will <b>always</b> be a
     * {@link JSONArray}. Using {@code accumulate} will result in either a
     * {@link JSONArray} or a mapping whose type is the type of {@code value}
     * depending on the number of calls to it.
     *
     * @param name  The name of the field to change.
     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
     *              Integer, Long, Double, {@link #NULL} or null. May not be {@link
     *              Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
     * @return this object after mutation.
     * @throws RuntimeException If the object being added is an invalid number.
     */
    // TODO: Change {@code append) to {@link #append} when append is
    // unhidden.
    public JSONObject accumulate(String name, Object value) {
        Object current = nameValuePairs.get(checkName(name));
        if (current == null) {
            return put(name, value);
        }

        if (current instanceof JSONArray) {
            JSONArray array = (JSONArray) current;
            array.checkedPut(value);
        } else {
            JSONArray array = new JSONArray();
            array.checkedPut(current);
            array.checkedPut(value);
            nameValuePairs.put(name, array);
        }
        return this;
    }

    /**
     * Appends values to the array mapped to {@code name}. A new {@link JSONArray}
     * mapping for {@code name} will be inserted if no mapping exists. If the existing
     * mapping for {@code name} is not a {@link JSONArray}, a {@link RuntimeException}
     * will be thrown.
     *
     * @param name  The name of the array to which the value should be appended.
     * @param value The value to append.
     * @return this object.
     * @throws JSONTypeMismatchException if {@code name} is {@code null} or if the mapping for
     *                       {@code name} is non-null and is not a {@link JSONArray}.
     */
    public JSONObject append(String name, Object value) {
        JSON.testValidity(value);
        Object current = nameValuePairs.get(checkName(name));

        final JSONArray array;
        if (current instanceof JSONArray) {
            array = (JSONArray) current;
        } else if (current == null) {
            JSONArray newArray = new JSONArray();
            nameValuePairs.put(name, newArray);
            array = newArray;
        } else {
            throw new JSONTypeMismatchException("JSONObject[\"" + name + "\"]", JSONType.ARRAY, current.getClass());
        }

        array.checkedPut(value);

        return this;
    }

    String checkName(String name) {
        if (name == null) {
            throw new RuntimeException("Names must be non-null");
        }
        return name;
    }

    /**
     * Returns true if this object has no mapping for {@code name} or if it has
     * a mapping whose value is {@link #NULL}.
     *
     * @param name The name of the value to check on.
     * @return true if the field doesn't exist or is null.
     */
    public boolean isNull(String name) {
        Object value = nameValuePairs.get(name);
        return value == null || value == NULL;
    }

    /**
     * Returns true if this object has a mapping for {@code name}. The mapping
     * may be {@link #NULL}.
     *
     * @deprecated use {@link #containsKey(Object)} instead
     * @param name
     *            The name of the value to check on.
     * @return true if this object has a field named {@code name}
     */
    @Deprecated
    public boolean has(String name) {
        return containsKey(name);
    }

    /**
     * Returns the value mapped by {@code name}, or null if no such mapping
     * exists.
     *
     * @param name The name of the value to get.
     * @return The value.
     */
    public Object opt(Object name) {
        return nameValuePairs.get(name);
    }

    /**
     * Returns the value mapped by {@code name} if it exists and is a boolean or
     * can be coerced to a boolean, or throws otherwise.
     *
     * @param name The name of the field we want.
     * @return The selected value if it exists.
     * @throws JSONValueNotFoundException if the mapping doesn't exist
     * @throws JSONTypeMismatchException if the mapping cannot be coerced
     *                       to a boolean.
     */
    public boolean getBoolean(String name) {
        Object object = opt(name);
        if (object == null) {
            throw JSONExceptionBuilder.valueNotFound(false, name, JSONType.BOOLEAN);
        }
        Boolean result = JSON.toBoolean(object);
        if (result == null) {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.BOOLEAN);
        }
        return result;
    }

    /**
     * Returns the value to which the specified key is mapped and a boolean, or
     * {@code defaultValue} if this JSONObject contains no mapping for the key.
     *
     * @param name the key whose associated value is to be returned
     * @param defaultValue the default mapping of the key
     * @return the value to which the specified key is mapped, or
     * {@code defaultValue} if this JSONObject contains no mapping for the key
     * @throws JSONTypeMismatchException if the mapping cannot be coerced
     *                       to a boolean.
     * @since 5.7
     */
    public boolean getBooleanOrDefault(String name, boolean defaultValue)
    {
        Object object = opt(name);
        if (object == null)
        {
            return defaultValue;
        }
        Boolean result = JSON.toBoolean(object);
        if (result == null)
        {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.BOOLEAN);
        }
        return result;
    }

    /**
     * Returns the value mapped by {@code name} if it exists and is a double or
     * can be coerced to a double, or throws otherwise.
     *
     * @param name The name of the field we want.
     * @return The selected value if it exists.
     * @throws JSONValueNotFoundException if the mapping doesn't exist
     * @throws JSONTypeMismatchException if the mapping cannot be coerced
     *                       to a double.
     */
    public double getDouble(String name) {
        Object object = opt(name);
        if (object == null) {
            throw JSONExceptionBuilder.valueNotFound(false, name, JSONType.NUMBER);
        }
        Double result = JSON.toDouble(object);
        if (result == null) {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.NUMBER);
        }
        return result;
    }

    /**
     * Returns the value mapped by {@code name} if it exists and is an int or
     * can be coerced to an int, or throws otherwise.
     *
     * @param name The name of the field we want.
     * @return The selected value if it exists.
     * @throws JSONValueNotFoundException if the mapping doesn't exist
     * @throws JSONTypeMismatchException if the mapping cannot be coerced
     *                       to an int.
     */
    public int getInt(String name) {
        Object object = opt(name);
        if (object == null) {
            throw JSONExceptionBuilder.valueNotFound(false, name, JSONType.NUMBER);
        }
        Integer result = JSON.toInteger(object);
        if (result == null) {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.NUMBER);
        }
        return result;
    }

    /**
     * Returns the value to which the specified key is mapped and an int, or
     * {@code defaultValue} if this JSONObject contains no mapping for the key.
     *
     * @param name the key whose associated value is to be returned
     * @param defaultValue the default mapping of the key
     * @return the value to which the specified key is mapped, or
     * {@code defaultValue} if this JSONObject contains no mapping for the key
     * @throws JSONTypeMismatchException if the mapping cannot be coerced
     *                       to an int.
     * @since 5.7
     */
    public int getIntOrDefault(String name, int defaultValue)
    {
        Object object = opt(name);
        if (object == null)
        {
            return defaultValue;
        }
        Integer result = JSON.toInteger(object);
        if (result == null)
        {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.NUMBER);
        }
        return result;
    }
    
    /**
     * Returns the value mapped by {@code name} if it exists and is a long or
     * can be coerced to a long, or throws otherwise.
     * Note that JSON represents numbers as doubles,
     *
     * so this is <a href="#lossy">lossy</a>; use strings to transfer numbers
     * via JSON without loss.
     *
     * @param name The name of the field that we want.
     * @return The value of the field.
     * @throws JSONValueNotFoundException if the mapping doesn't exist
     * @throws JSONTypeMismatchException if the mapping cannot be coerced
     *                       to a long.
     */
    public long getLong(String name) {
        Object object = opt(name);
        if (object == null) {
            throw JSONExceptionBuilder.valueNotFound(false, name, JSONType.NUMBER);
        }
        Long result = JSON.toLong(object);
        if (result == null) {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.NUMBER);
        }
        return result;
    }

    /**
     * Returns the value to which the specified key is mapped and a long, or
     * {@code defaultValue} if this JSONObject contains no mapping for the key.
     *
     * @param name the key whose associated value is to be returned
     * @param defaultValue the default mapping of the key
     * @return the value to which the specified key is mapped, or
     * {@code defaultValue} if this JSONObject contains no mapping for the key
     * @throws JSONTypeMismatchException if the mapping cannot be coerced
     *                       to a long.
     * @since 5.7
     */
    public long getLongOrDefault(String name, int defaultValue)
    {
        Object object = opt(name);
        if (object == null)
        {
            return defaultValue;
        }
        Long result = JSON.toLong(object);
        if (result == null)
        {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.NUMBER);
        }
        return result;
    }

    /**
     * Returns the value mapped by {@code name} if it exists, coercing it if
     * necessary, or throws if no such mapping exists.
     *
     * @param name The name of the field we want.
     * @return The value of the field.
     * @throws JSONValueNotFoundException if the mapping doesn't exist
     * @throws JSONTypeMismatchException if the mapping cannot be coerced
     *                               to String
     */
    public String getString(String name) {
        Object object = opt(name);
        if (object == null) {
            throw JSONExceptionBuilder.valueNotFound(false, name, JSONType.STRING);
        }
        String result = JSON.toString(object);
        if (result == null) {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.STRING);
        }
        return result;
    }

    /**
     * Returns the value to which the specified key is mapped and a string, or
     * {@code defaultValue} if this JSONObject contains no mapping for the key.
     *
     * @param name the key whose associated value is to be returned
     * @param defaultValue the default mapping of the key
     * @return the value to which the specified key is mapped, or
     * {@code defaultValue} if this JSONObject contains no mapping for the key
     * @throws JSONTypeMismatchException if the mapping cannot be coerced
     *                       to a string.
     * @since 5.7
     */
    public String getStringOrDefault(String name, String defaultValue)
    {
        Object object = opt(name);
        if (object == null)
        {
            return defaultValue;
        }
        String result = JSON.toString(object);
        if (result == null)
        {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.STRING);
        }
        return result;
    }
    
    /**
     * Returns the value mapped by {@code name} if it exists and is a {@code
     * JSONArray}, or throws otherwise.
     *
     * @param name The field we want to get.
     * @return The value of the field (if it is a JSONArray.
     * @throws JSONValueNotFoundException if the mapping doesn't exist
     * @throws JSONTypeMismatchException if the mapping is not a {@code
     *                       JSONArray}.
     */
    public JSONArray getJSONArray(String name) {
        Object object = opt(name);
        if (object == null) {
            throw JSONExceptionBuilder.valueNotFound(false, name, JSONType.ARRAY);
        }
        if (object instanceof JSONArray) {
            return (JSONArray) object;
        } else {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.ARRAY);
        }
    }

    /**
     * Returns the value to which the specified key is mapped and a JSONArray, or
     * {@code defaultValue} if this JSONObject contains no mapping for the key.
     *
     * @param name the key whose associated value is to be returned
     * @param defaultValue the default mapping of the key
     * @return the value to which the specified key is mapped, or
     * {@code defaultValue} if this JSONObject contains no mapping for the key
     * @throws JSONTypeMismatchException if the mapping cannot be coerced
     *                       to a JSONArray.
     * @since 5.7
     */
    public JSONArray getJSONArrayOrDefault(String name, JSONArray defaultValue)
    {
        Object object = opt(name);
        if (object == null)
        {
            return defaultValue;
        }
        if (object instanceof JSONArray) {
            return (JSONArray) object;
        } else {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.ARRAY);
        }
    }
    
    /**
     * Returns the value mapped by {@code name} if it exists and is a {@code
     * JSONObject}, or throws otherwise.
     *
     * @param name The name of the field that we want.
     * @return a specified field value (if it is a JSONObject)
     * @throws JSONValueNotFoundException if the mapping doesn't exist
     * @throws JSONTypeMismatchException if the mapping is not a {@code
     *                       JSONObject}.
     */
    public JSONObject getJSONObject(String name) {
        Object object = opt(name);
        if (object == null) {
            throw JSONExceptionBuilder.valueNotFound(false, name, JSONType.OBJECT);
        }
        if (object instanceof JSONObject) {
            return (JSONObject) object;
        } else {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.OBJECT);
        }
    }

    
    /**
     * Returns the value to which the specified key is mapped and a JSONObject, or
     * {@code defaultValue} if this map contains no mapping for the key.
     *
     * @param name the key whose associated value is to be returned
     * @param defaultValue the default mapping of the key
     * @return the value to which the specified key is mapped, or
     * {@code defaultValue} if this map contains no mapping for the key
     * @throws JSONTypeMismatchException if the mapping cannot be coerced
     *                       to a JSONObject.
     * @since 5.7
     */
    public JSONObject getJSONObjectOrDefault(String name, JSONObject defaultValue)
    {
        Object object = opt(name);
        if (object == null)
        {
            return defaultValue;
        }
        if (object instanceof JSONObject) {
            return (JSONObject) object;
        } else {
            throw JSONExceptionBuilder.typeMismatch(false, name, object, JSONType.OBJECT);
        }
    }
    /**
     * Returns the set of {@code String} names in this object. The returned set
     * is a view of the keys in this object. {@link Set#remove(Object)} will remove
     * the corresponding mapping from this object and set iterator behaviour
     * is undefined if this object is modified after it is returned.
     *
     * See {@link #keys()}.
     *
     * @return The names in this object.
     */
    public Set<String> keys() {
        return nameValuePairs.keySet();
    }

    /**
     * Returns an array containing the string names in this object. This method
     * returns null if this object contains no mappings.
     *
     * @return the names.
     */
    public JSONArray names() {
        return nameValuePairs.isEmpty()
                ? null
                : JSONArray.from(nameValuePairs.keySet());
    }

    /**
     * Encodes the number as a JSON string.
     *
     * @param number a finite value. May not be {@link Double#isNaN() NaNs} or
     *               {@link Double#isInfinite() infinities}.
     * @return The encoded number in string form.
     * @throws RuntimeException On internal errors. Shouldn't happen.
     */
    public static String numberToString(Number number) {
        if (number == null) {
            throw new RuntimeException("Number must be non-null");
        }

        double doubleValue = number.doubleValue();
        JSON.checkDouble(doubleValue);

        // the original returns "-0" instead of "-0.0" for negative zero
        if (number.equals(NEGATIVE_ZERO)) {
            return "-0";
        }

        long longValue = number.longValue();
        if (doubleValue == (double) longValue) {
            return Long.toString(longValue);
        }

        return number.toString();
    }

    static String doubleToString(double d)
    {
        if (Double.isInfinite(d) || Double.isNaN(d))
        {
            return "null";
        }

        return numberToString(d);
    }

    /**
     * Encodes {@code data} as a JSON string. This applies quotes and any
     * necessary character escaping.
     *
     * @param data the string to encode. Null will be interpreted as an empty
     *             string.
     * @return the quoted string.
     */
    public static String quote(String data) {
        if (data == null) {
            return "\"\"";
        }
        try {
            JSONStringer stringer = new JSONStringer();
            stringer.open(JSONStringer.Scope.NULL, "");
            stringer.string(data);
            stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
            return stringer.toString();
        } catch (RuntimeException e) {
            throw new AssertionError();
        }
    }



    /**
     * Prints the JSONObject using the session.
     *
     * @since 5.2.0
     */
    @Override
    void print(JSONPrintSession session)
    {
        session.printSymbol('{');

        session.indent();

        boolean comma = false;

        for (String key : keys())
        {
            if (comma)
                session.printSymbol(',');

            session.newline();

            session.printQuoted(key);

            session.printSymbol(':');

            printValue(session, nameValuePairs.get(key));

            comma = true;
        }

        session.outdent();

        if (comma)
            session.newline();

        session.printSymbol('}');
    }


    /**
     * Prints a value (a JSONArray or JSONObject, or a value stored in an array or object) using
     * the session.
     *
     * @since 5.2.0
     */
    static void printValue(JSONPrintSession session, Object value)
    {

        if (value == null || value == NULL)
        {
            session.print("null");
            return;
        }
        if (value instanceof JSONObject)
        {
            ((JSONObject) value).print(session);
            return;
        }

        if (value instanceof JSONArray)
        {
            ((JSONArray) value).print(session);
            return;
        }

        if (value instanceof JSONString)
        {
            String printValue = ((JSONString) value).toJSONString();

            session.print(printValue);

            return;
        }

        if (value instanceof Number)
        {
            String printValue = numberToString((Number) value);
            session.print(printValue);
            return;
        }

        if (value instanceof Boolean)
        {
            session.print(value.toString());

            return;
        }

        // Otherwise it really should just be a string. Nothing else can go in.
        session.printQuoted(value.toString());
    }

    public boolean equals(Object obj)
    {
        if (obj == null)
            return false;

        if (!(obj instanceof JSONObject))
            return false;

        JSONObject other = (JSONObject) obj;

        return nameValuePairs.equals(other.nameValuePairs);
    }

    /**
     * Returns a Map of the keys and values of the JSONObject. The returned map is unmodifiable.
     * Note that changes to the JSONObject will be reflected in the map. In addition, null values in the JSONObject
     * are represented as {@link JSONObject#NULL} in the map.
     *
     * @return unmodifiable map of properties and values
     * @since 5.4
     */
    public Map<String, Object> toMap()
    {
        return Collections.unmodifiableMap(nameValuePairs);
    }

    /**
     * Navigates into a nested JSONObject, creating the JSONObject if necessary. They key must not exist,
     * or must be a JSONObject.
     *
     * @param key
     * @return the nested JSONObject
     * @throws IllegalStateException
     *         if the current value for the key is not null and not JSONObject
     */
    public JSONObject in(String key)
    {
        assert key != null;

        Object nested = nameValuePairs.get(key);

        if (nested != null && !(nested instanceof JSONObject))
        {
            throw new IllegalStateException(String.format("JSONObject[%s] is not a JSONObject.", quote(key)));
        }

        if (nested == null)
        {
            nested = new JSONObject();
            nameValuePairs.put(key, nested);
        }

        return (JSONObject) nested;
    }

    /**
     * Returns the number of key-value mappings in this JSONObject.
     * If it contains more than {@code Integer.MAX_VALUE} elements, returns
     * {@code Integer.MAX_VALUE}.
     *
     * @return the number of key-value mappings in this JSONObject
     * @since 5.7
     */
    @Override
    public int size()
    {
        return nameValuePairs.size();
    }

    /**
     * Returns {@code true} if this JSONObject contains no key-value mappings.
     *
     * @return {@code true} if this JSONObject contains no key-value mappings
     * @since 5.7
     */
    @Override
    public boolean isEmpty()
    {
        return nameValuePairs.isEmpty();
    }

    /**
     * Returns {@code true} if this JSONObject contains a mapping for the specified
     * key.
     *
     * @param key
     *            key whose presence in this map is to be tested
     * @return {@code true} if this map contains a mapping for the specified
     *         key
     * @since 5.7
     */
    @Override
    public boolean containsKey(Object key)
    {
        return nameValuePairs.containsKey(key);
    }

    /**
     * Returns {@code true} if this JSONObject maps one or more keys to the
     * specified value.
     *
     * @param value value whose presence in this map is to be tested
     * @return {@code true} if this JSONObject maps one or more keys to the
     *         specified value
     * @since 5.7
     */
    @Override
    public boolean containsValue(Object value)
    {
        return nameValuePairs.containsValue(value);
    }

    /**
     * Returns the value mapped by {@code name}, or throws if no such mapping exists.
     *
     * @param name The name of the value to get.
     * @return The value.
     * @throws JSONValueNotFoundException if no such mapping exists.
     */ @Override
    public Object get(Object name)
    {
        Object result = nameValuePairs.get(name);
         if (result == null) {
            throw JSONExceptionBuilder.valueNotFound(false, name, JSONType.ANY);
         }
         return result;
    }

    /**
      * Returns the value to which the specified key is mapped, or
      * {@code defaultValue} if this JSONObject contains no mapping for the key.
      *
      * @param key the key whose associated value is to be returned
      * @param defaultValue the default mapping of the key
      * @return the value to which the specified key is mapped, or
      *         {@code defaultValue} if this JSONObject contains no mapping for the key
      * @since 5.7
      */
    @Override
    public Object getOrDefault(Object key, Object defaultValue)
    {
        Object value = opt(key);
        return value == null ? defaultValue : value;
    }

    /**
     * Removes the named mapping if it exists; does nothing otherwise.
     *
     * @param name The name of the mapping to remove.
     * @return the value previously mapped by {@code name}, or null if there was
     *         no such mapping.
     */
    @Override
    public Object remove(Object name)
    {
        return nameValuePairs.remove(name);
    }

    /**
     * Invokes {@link #put(String, Object)} for each value from the map.
     *
     * @param newProperties
     *            to add to this JSONObject
     * @since 5.7
     */
    @Override
    public void putAll(Map<? extends String, ? extends Object> newProperties)
    {
        assert newProperties != null;

        for (Map.Entry<? extends String, ? extends Object> e : newProperties.entrySet())
        {
            put(e.getKey(), e.getValue());
        }
    }

    /**
     * Removes all of the mappings from this JSONObject.
     * 
     * @since 5.7
     */
    @Override
    public void clear()
    {
        nameValuePairs.clear();
    }

    /**
     * Returns a {@link Set} view of the keys contained in this JSONObject.
     * The set is backed by the JSONObject, so changes to the map are
     * reflected in the set, and vice-versa.
     *
     * @return a set view of the keys contained in this JSONObject
     * @since 5.7
     */
    @Override
    public Set<String> keySet()
    {
        return nameValuePairs.keySet();
    }

    /**
     * Returns a {@link Collection} view of the values contained in this JSONObject.
     * The collection is backed by the JSONObject, so changes to the map are
     * reflected in the collection, and vice-versa.
     *
     * @return a collection view of the values contained in this JSONObject
     * @since 5.7
     */
    @Override
    public Collection<Object> values()
    {
        return nameValuePairs.values();
    }

    /**
     * Returns a {@link Set} view of the mappings contained in this JSONObject.
     * The set is backed by the JSONObject, so changes to the map are
     * reflected in the set, and vice-versa.
     *
     * @return a set view of the mappings contained in this JSONObject
     * @since 5.7
     */
    @Override
    public Set<Entry<String, Object>> entrySet()
    {
        return nameValuePairs.entrySet();
    }
  

}