You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ud...@apache.org on 2017/02/17 21:01:00 UTC

[1/8] geode git commit: GEODE-2142: Removal of non-compliant org.json implementation.

Repository: geode
Updated Branches:
  refs/heads/develop fe46a433e -> 2e3a88f7b


http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/XMLTokener.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/XMLTokener.java b/geode-json/src/main/java/org/json/XMLTokener.java
deleted file mode 100755
index f56a1f6..0000000
--- a/geode-json/src/main/java/org/json/XMLTokener.java
+++ /dev/null
@@ -1,362 +0,0 @@
-package org.json;
-
-/*
- * Copyright (c) 2002 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * The XMLTokener extends the JSONTokener to provide additional methods for the parsing of XML
- * texts.
- * 
- * @author JSON.org
- * @version 2010-12-24
- */
-public class XMLTokener extends JSONTokener {
-
-
-  /**
-   * The table of entity values. It initially contains Character values for amp, apos, gt, lt, quot.
-   */
-  public static final java.util.HashMap entity;
-
-  static {
-    entity = new java.util.HashMap(8);
-    entity.put("amp", XML.AMP);
-    entity.put("apos", XML.APOS);
-    entity.put("gt", XML.GT);
-    entity.put("lt", XML.LT);
-    entity.put("quot", XML.QUOT);
-  }
-
-  /**
-   * Construct an XMLTokener from a string.
-   * 
-   * @param s A source string.
-   */
-  public XMLTokener(String s) {
-    super(s);
-  }
-
-  /**
-   * Get the text in the CDATA block.
-   * 
-   * @return The string up to the <code>]]&gt;</code>.
-   * @throws JSONException If the <code>]]&gt;</code> is not found.
-   */
-  public String nextCDATA() throws JSONException {
-    char c;
-    int i;
-    StringBuffer sb = new StringBuffer();
-    for (;;) {
-      c = next();
-      if (end()) {
-        throw syntaxError("Unclosed CDATA");
-      }
-      sb.append(c);
-      i = sb.length() - 3;
-      if (i >= 0 && sb.charAt(i) == ']' && sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') {
-        sb.setLength(i);
-        return sb.toString();
-      }
-    }
-  }
-
-
-  /**
-   * Get the next XML outer token, trimming whitespace. There are two kinds of tokens: the '<'
-   * character which begins a markup tag, and the content text between markup tags.
-   *
-   * @return A string, or a '<' Character, or null if there is no more source text.
-   * @throws JSONException
-   */
-  public Object nextContent() throws JSONException {
-    char c;
-    StringBuffer sb;
-    do {
-      c = next();
-    } while (Character.isWhitespace(c));
-    if (c == 0) {
-      return null;
-    }
-    if (c == '<') {
-      return XML.LT;
-    }
-    sb = new StringBuffer();
-    for (;;) {
-      if (c == '<' || c == 0) {
-        back();
-        return sb.toString().trim();
-      }
-      if (c == '&') {
-        sb.append(nextEntity(c));
-      } else {
-        sb.append(c);
-      }
-      c = next();
-    }
-  }
-
-
-  /**
-   * Return the next entity. These entities are translated to Characters:
-   * <code>&amp;  &apos;  &gt;  &lt;  &quot;</code>.
-   * 
-   * @param ampersand An ampersand character.
-   * @return A Character or an entity String if the entity is not recognized.
-   * @throws JSONException If missing ';' in XML entity.
-   */
-  public Object nextEntity(char ampersand) throws JSONException {
-    StringBuffer sb = new StringBuffer();
-    for (;;) {
-      char c = next();
-      if (Character.isLetterOrDigit(c) || c == '#') {
-        sb.append(Character.toLowerCase(c));
-      } else if (c == ';') {
-        break;
-      } else {
-        throw syntaxError("Missing ';' in XML entity: &" + sb);
-      }
-    }
-    String string = sb.toString();
-    Object object = entity.get(string);
-    return object != null ? object : ampersand + string + ";";
-  }
-
-
-  /**
-   * Returns the next XML meta token. This is used for skipping over <!...> and <?...?> structures.
-   * 
-   * @return Syntax characters (<code>< > / = ! ?</code>) are returned as Character, and strings and
-   *         names are returned as Boolean. We don't care what the values actually are.
-   * @throws JSONException If a string is not properly closed or if the XML is badly structured.
-   */
-  public Object nextMeta() throws JSONException {
-    char c;
-    char q;
-    do {
-      c = next();
-    } while (Character.isWhitespace(c));
-    switch (c) {
-      case 0:
-        throw syntaxError("Misshaped meta tag");
-      case '<':
-        return XML.LT;
-      case '>':
-        return XML.GT;
-      case '/':
-        return XML.SLASH;
-      case '=':
-        return XML.EQ;
-      case '!':
-        return XML.BANG;
-      case '?':
-        return XML.QUEST;
-      case '"':
-      case '\'':
-        q = c;
-        for (;;) {
-          c = next();
-          if (c == 0) {
-            throw syntaxError("Unterminated string");
-          }
-          if (c == q) {
-            return Boolean.TRUE;
-          }
-        }
-      default:
-        for (;;) {
-          c = next();
-          if (Character.isWhitespace(c)) {
-            return Boolean.TRUE;
-          }
-          switch (c) {
-            case 0:
-            case '<':
-            case '>':
-            case '/':
-            case '=':
-            case '!':
-            case '?':
-            case '"':
-            case '\'':
-              back();
-              return Boolean.TRUE;
-          }
-        }
-    }
-  }
-
-
-  /**
-   * Get the next XML Token. These tokens are found inside of angle brackets. It may be one of these
-   * characters: <code>/ > = ! ?</code> or it may be a string wrapped in single quotes or double
-   * quotes, or it may be a name.
-   * 
-   * @return a String or a Character.
-   * @throws JSONException If the XML is not well formed.
-   */
-  public Object nextToken() throws JSONException {
-    char c;
-    char q;
-    StringBuffer sb;
-    do {
-      c = next();
-    } while (Character.isWhitespace(c));
-    switch (c) {
-      case 0:
-        throw syntaxError("Misshaped element");
-      case '<':
-        throw syntaxError("Misplaced '<'");
-      case '>':
-        return XML.GT;
-      case '/':
-        return XML.SLASH;
-      case '=':
-        return XML.EQ;
-      case '!':
-        return XML.BANG;
-      case '?':
-        return XML.QUEST;
-
-      // Quoted string
-
-      case '"':
-      case '\'':
-        q = c;
-        sb = new StringBuffer();
-        for (;;) {
-          c = next();
-          if (c == 0) {
-            throw syntaxError("Unterminated string");
-          }
-          if (c == q) {
-            return sb.toString();
-          }
-          if (c == '&') {
-            sb.append(nextEntity(c));
-          } else {
-            sb.append(c);
-          }
-        }
-      default:
-
-        // Name
-
-        sb = new StringBuffer();
-        for (;;) {
-          sb.append(c);
-          c = next();
-          if (Character.isWhitespace(c)) {
-            return sb.toString();
-          }
-          switch (c) {
-            case 0:
-              return sb.toString();
-            case '>':
-            case '/':
-            case '=':
-            case '!':
-            case '?':
-            case '[':
-            case ']':
-              back();
-              return sb.toString();
-            case '<':
-            case '"':
-            case '\'':
-              throw syntaxError("Bad character in a name");
-          }
-        }
-    }
-  }
-
-
-  /**
-   * Skip characters until past the requested string. If it is not found, we are left at the end of
-   * the source with a result of false.
-   * 
-   * @param to A string to skip past.
-   * @throws JSONException
-   */
-  public boolean skipPast(String to) throws JSONException {
-    boolean b;
-    char c;
-    int i;
-    int j;
-    int offset = 0;
-    int length = to.length();
-    char[] circle = new char[length];
-
-    /*
-     * First fill the circle buffer with as many characters as are in the to string. If we reach an
-     * early end, bail.
-     */
-
-    for (i = 0; i < length; i += 1) {
-      c = next();
-      if (c == 0) {
-        return false;
-      }
-      circle[i] = c;
-    }
-    /*
-     * We will loop, possibly for all of the remaining characters.
-     */
-    for (;;) {
-      j = offset;
-      b = true;
-      /*
-       * Compare the circle buffer with the to string.
-       */
-      for (i = 0; i < length; i += 1) {
-        if (circle[j] != to.charAt(i)) {
-          b = false;
-          break;
-        }
-        j += 1;
-        if (j >= length) {
-          j -= length;
-        }
-      }
-      /*
-       * If we exit the loop with b intact, then victory is ours.
-       */
-      if (b) {
-        return true;
-      }
-      /*
-       * Get the next character. If there isn't one, then defeat is ours.
-       */
-      c = next();
-      if (c == 0) {
-        return false;
-      }
-      /*
-       * Shove the character in the circle buffer and advance the circle offset. The offset is mod
-       * n.
-       */
-      circle[offset] = c;
-      offset += 1;
-      if (offset >= length) {
-        offset -= length;
-      }
-    }
-  }
-}


[5/8] geode git commit: GEODE-2142: Removal of non-compliant org.json implementation.

Posted by ud...@apache.org.
GEODE-2142: Removal of non-compliant org.json implementation.


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

Branch: refs/heads/develop
Commit: b3ec80bc72fee3a40da297945a85d8df6c2a6460
Parents: fe46a43
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Fri Feb 17 12:47:03 2017 -0800
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Fri Feb 17 12:56:13 2017 -0800

----------------------------------------------------------------------
 .../geode/management/internal/cli/CliUtil.java  |   42 -
 .../internal/cli/commands/ConfigCommands.java   |    3 +-
 ...xportImportClusterConfigurationCommands.java |    2 +-
 .../cli/functions/ExportConfigFunction.java     |    4 +-
 .../internal/cli/json/GfJsonObject.java         |   54 +-
 .../internal/cli/result/AbstractResultData.java |   56 +-
 .../cli/result/CompositeResultData.java         |   46 -
 .../internal/cli/result/ResultBuilder.java      |   30 -
 .../cli/commands/CliCommandTestBase.java        |    6 +-
 geode-json/src/main/java/org/json/CDL.java      |  272 ---
 geode-json/src/main/java/org/json/Cookie.java   |  162 --
 .../src/main/java/org/json/CookieList.java      |   87 -
 geode-json/src/main/java/org/json/HTTP.java     |  185 --
 .../src/main/java/org/json/HTTPTokener.java     |   77 -
 geode-json/src/main/java/org/json/JSON.java     |  116 ++
 .../src/main/java/org/json/JSONArray.java       | 1587 +++++++-------
 .../src/main/java/org/json/JSONException.java   |   71 +-
 geode-json/src/main/java/org/json/JSONML.java   |  454 ----
 .../src/main/java/org/json/JSONObject.java      | 1952 +++++++-----------
 .../src/main/java/org/json/JSONString.java      |   17 +-
 .../src/main/java/org/json/JSONStringer.java    |  531 ++++-
 .../src/main/java/org/json/JSONTokener.java     | 1013 +++++----
 .../src/main/java/org/json/JSONWriter.java      |  321 ---
 geode-json/src/main/java/org/json/XML.java      |  504 -----
 .../src/main/java/org/json/XMLTokener.java      |  362 ----
 25 files changed, 2758 insertions(+), 5196 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java
index 8525b58..a505001 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/CliUtil.java
@@ -440,11 +440,6 @@ public class CliUtil {
 
       compressedDataLength = compresser.deflate(buffer);
       totalCompressedDataLength += compressedDataLength;
-      // System.out.println(compressedDataLength);
-      // System.out.println("uc: b "+buffer.length);
-      // System.out.println("uc: r "+result.length);
-      // System.out.println("uc: nr "+newResult.length);
-      // System.out.println();
       System.arraycopy(buffer, 0, newResult, result.length, buffer.length);
       result = newResult;
     } while (compressedDataLength != 0);
@@ -500,43 +495,6 @@ public class CliUtil {
     }
   }
 
-  public static void main(String[] args) {
-    try {
-      byte[][] filesToBytes =
-          filesToBytes(new String[] {"/export/abhishek1/work/aspenmm/GFTryouts/test.json"});
-
-      System.out.println(filesToBytes[1].length);
-
-      DeflaterInflaterData compressBytes = compressBytes(filesToBytes[1]);
-      System.out.println(compressBytes);
-
-      DeflaterInflaterData uncompressBytes =
-          uncompressBytes(compressBytes.data, compressBytes.dataLength);
-      System.out.println(uncompressBytes);
-
-      System.out.println(new String(uncompressBytes.getData()));
-    } catch (FileNotFoundException e) {
-      e.printStackTrace();
-    } catch (IOException e) {
-      e.printStackTrace();
-    } catch (DataFormatException e) {
-      e.printStackTrace();
-    }
-  }
-
-  public static void main1(String[] args) {
-    try {
-      byte[][] fileToBytes = filesToBytes(new String[] {"../dumped/source/lib"});
-
-      bytesToFiles(fileToBytes, "../dumped/dest/lib/", true);
-
-    } catch (FileNotFoundException e) {
-      e.printStackTrace();
-    } catch (IOException e) {
-      e.printStackTrace();
-    }
-  }
-
   public static boolean contains(Object[] array, Object object) {
     boolean contains = false;
 

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConfigCommands.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConfigCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConfigCommands.java
index 12a0a64..283f09d 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConfigCommands.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConfigCommands.java
@@ -234,7 +234,8 @@ public class ConfigCommands extends AbstractCommandsSupport {
               false);
         }
       }
-      return ResultBuilder.buildResult(infoData);
+      Result result = ResultBuilder.buildResult(infoData);
+      return result;
     } catch (VirtualMachineError e) {
       SystemFailure.initiateFailure(e);
       throw e;

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportImportClusterConfigurationCommands.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportImportClusterConfigurationCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportImportClusterConfigurationCommands.java
index e94af4f..7485d9f 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportImportClusterConfigurationCommands.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportImportClusterConfigurationCommands.java
@@ -75,6 +75,7 @@ public class ExportImportClusterConfigurationCommands extends AbstractCommandsSu
   public Result exportSharedConfig(@CliOption(key = {CliStrings.EXPORT_SHARED_CONFIG__FILE},
       mandatory = true, help = CliStrings.EXPORT_SHARED_CONFIG__FILE__HELP) String zipFileName) {
 
+    System.err.println("Out 1");
     InternalLocator locator = InternalLocator.getLocator();
     if (!locator.isSharedConfigurationRunning()) {
       return ResultBuilder.createGemFireErrorResult(CliStrings.SHARED_CONFIGURATION_NOT_STARTED);
@@ -99,7 +100,6 @@ public class ExportImportClusterConfigurationCommands extends AbstractCommandsSu
         sc.writeConfigToFile(config);
       }
       ZipUtils.zipDirectory(sc.getSharedConfigurationDirPath(), zipFile.getCanonicalPath());
-
       InfoResultData infoData = ResultBuilder.createInfoResultData();
       byte[] byteData = FileUtils.readFileToByteArray(zipFile);
       infoData.addAsFile(zipFileName, byteData, InfoResultData.FILE_TYPE_BINARY,

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
index 49e27b0..64bc374 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
@@ -93,12 +93,10 @@ public class ExportConfigFunction implements Function, InternalEntity {
               .append(lineSeparator);
         }
       }
-
       CliFunctionResult result = new CliFunctionResult(memberId,
           new String[] {xmlWriter.toString(), propStringBuf.toString()});
-
+      System.err.println("ExportConfigFunction.execute CLI function result: "+result);
       context.getResultSender().lastResult(result);
-
     } catch (CacheClosedException cce) {
       CliFunctionResult result = new CliFunctionResult(memberId, false, null);
       context.getResultSender().lastResult(result);

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
index 69666ff..9137f72 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
@@ -49,22 +49,6 @@ public class GfJsonObject {
       this.jsonObject = (JSONObject) bean;
     } else {
       this.jsonObject = new JSONObject(bean);
-      // If we want to print out the values of the primitive arrays and report back
-      // Class klass = bean.getClass();
-      // if(klass.isArray() && klass.getComponentType().isPrimitive()){
-      // String str = "";
-      // int length = Array.getLength(bean);
-      // for (int i = 0; i < length; i++) {
-      // if(i==0)
-      // str += (Array.get(bean, i));
-      // else
-      // str +=(","+Array.get(bean, i));
-      // }
-      // try {
-      // this.jsonObject.put("Value", str);
-      // } catch (JSONException ignore) {
-      // }
-      // }
     }
     if (checkCyclicDep) {
       JSONObject.cyclicDepChkEnabled.set(false);
@@ -88,9 +72,9 @@ public class GfJsonObject {
     }
   }
 
-  public GfJsonObject(Object bean, String[] paramNames) {
-    this.jsonObject = new JSONObject(bean, paramNames);
-  }
+//  public GfJsonObject(Object bean, String[] paramNames) {
+//    this.jsonObject = new JSONObject(bean, paramNames);
+//  }
 
   /**
    * 
@@ -253,21 +237,21 @@ public class GfJsonObject {
     return this;
   }
 
-  /**
-   * 
-   * @param key
-   * @param value
-   * @return this GfJsonObject
-   * @throws GfJsonException if the key is a duplicate
-   */
-  public GfJsonObject putOnce(String key, Object value) throws GfJsonException {
-    try {
-      jsonObject.putOnce(key, value);
-    } catch (JSONException e) {
-      throw new GfJsonException(e.getMessage());
-    }
-    return this;
-  }
+//  /**
+//   *
+//   * @param key
+//   * @param value
+//   * @return this GfJsonObject
+//   * @throws GfJsonException if the key is a duplicate
+//   */
+//  public GfJsonObject putOnce(String key, Object value) throws GfJsonException {
+//    try {
+//      jsonObject.putOnce(key, value);
+//    } catch (JSONException e) {
+//      throw new GfJsonException(e.getMessage());
+//    }
+//    return this;
+//  }
 
   /**
    * 
@@ -362,7 +346,7 @@ public class GfJsonObject {
     }
   }
 
-  private static Object extractInternalForGfJsonOrReturnSame(Object value) {
+  private Object extractInternalForGfJsonOrReturnSame(Object value) {
     Object returnedValue = value;
     if (value instanceof GfJsonObject) {
       returnedValue = ((GfJsonObject) value).getInternalJsonObject();

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
index e08d9b7..81ab511 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
@@ -20,7 +20,10 @@ import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
 import java.text.MessageFormat;
+import java.util.Base64;
 import java.util.zip.DataFormatException;
 
 import org.apache.geode.management.cli.Result.Status;
@@ -151,26 +154,10 @@ public abstract class AbstractResultData implements ResultData {
     if (addTimeStampToName) {
       fileName = addTimeStampBeforeLastDot(fileName);
     }
-    return addAsFile(fileName.getBytes(), bytes, fileType, message);
+    return addAsFile(fileName, bytes, fileType, message);
   }
 
-  public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
-      boolean addTimeStampToName) throws FileNotFoundException, IOException {
-    byte[][] filesToBytes = CliUtil.filesToBytes(new String[] {filePath});
-
-    byte[] bytes = filesToBytes[0];
-    if (addTimeStampToName) {
-      String fileName = new String(filesToBytes[0]);
-      fileName = addTimeStampBeforeLastDot(fileName);
-      bytes = fileName.getBytes();
-    }
-    return addAsFile(bytes, filesToBytes[1], fileType, message);
-  }
-
-  private ResultData addAsFile(byte[] fileName, byte[] data, int fileType, String message) {
-    // System.out.println("fileType :: "+fileType);
-    // System.out.println("FILE_TYPE_BINARY :: "+FILE_TYPE_BINARY);
-    // System.out.println("FILE_TYPE_TEXT :: "+FILE_TYPE_TEXT);
+  private ResultData addAsFile(String fileName, byte[] data, int fileType, String message) {
     if (fileType != FILE_TYPE_BINARY && fileType != FILE_TYPE_TEXT) {
       throw new IllegalArgumentException("Unsupported file type is specified.");
     }
@@ -186,14 +173,12 @@ public abstract class AbstractResultData implements ResultData {
 
       sectionData.put(FILE_NAME_FIELD, fileName);
       sectionData.put(FILE_TYPE_FIELD, fileType);
-      sectionData.put(FILE_MESSAGE, message.getBytes());
-      sectionData.putAsJSONObject(FILE_DATA_FIELD, CliUtil.compressBytes(data));
-      // System.out.println(data);
-      // sectionData.put(FILE_DATA_FIELD, Base64.encodeBytes(data, Base64.GZIP));
+      sectionData.put(FILE_MESSAGE, message);
+      DeflaterInflaterData deflaterInflaterData = CliUtil.compressBytes(data);
+      sectionData.put(FILE_DATA_FIELD, Base64.getEncoder().encodeToString(deflaterInflaterData.getData()));
+      sectionData.put(DATA_LENGTH_FIELD,deflaterInflaterData.getDataLength());
     } catch (GfJsonException e) {
       throw new ResultDataException(e.getMessage());
-      // } catch (IOException e) {
-      // e.printStackTrace();
     }
     return this;
   }
@@ -223,29 +208,30 @@ public abstract class AbstractResultData implements ResultData {
 
       // build file name
       byte[] fileNameBytes = null;
+      String fileName = null;
       GfJsonArray fileNameJsonBytes = object.getJSONArray(FILE_NAME_FIELD);
       if (fileNameJsonBytes != null) { // if in gfsh
         fileNameBytes = GfJsonArray.toByteArray(fileNameJsonBytes);
+        fileName = new String(fileNameBytes);
       } else { // if on member
-        fileNameBytes = (byte[]) object.get(FILE_NAME_FIELD);
+        fileName = (String) object.get(FILE_NAME_FIELD);
       }
-      String fileName = new String(fileNameBytes);
 
       // build file message
       byte[] fileMessageBytes = null;
+      String fileMessage = null;
       GfJsonArray fileMessageJsonBytes = object.getJSONArray(FILE_MESSAGE);
       if (fileMessageJsonBytes != null) { // if in gfsh
         fileMessageBytes = GfJsonArray.toByteArray(fileMessageJsonBytes);
+        fileMessage = new String(fileMessageBytes);
       } else { // if on member
-        fileMessageBytes = (byte[]) object.get(FILE_MESSAGE);
+        fileMessage = (String) object.get(FILE_MESSAGE);
       }
-      String fileMessage = new String(fileMessageBytes);
 
-      GfJsonObject fileDataBytes = object.getJSONObject(FILE_DATA_FIELD);
-      byte[] byteArray = GfJsonArray.toByteArray(fileDataBytes.getJSONArray(DATA_FIELD));
-      int dataLength = fileDataBytes.getInt(DATA_LENGTH_FIELD);
-      DeflaterInflaterData uncompressBytes = CliUtil.uncompressBytes(byteArray, dataLength);
-      byte[] uncompressed = uncompressBytes.getData();
+      String fileDataString = (String) object.get(FILE_DATA_FIELD);
+      int fileDataLength = (int) object.get(DATA_LENGTH_FIELD);
+      byte[] byteArray = Base64.getDecoder().decode(fileDataString);
+      byte[] uncompressBytes = CliUtil.uncompressBytes(byteArray,fileDataLength).getData();
 
       boolean isGfshVM = CliUtil.isGfshVM();
       File fileToDumpData = new File(fileName);
@@ -299,13 +285,13 @@ public abstract class AbstractResultData implements ResultData {
       if (fileType == FILE_TYPE_TEXT) {
         FileWriter fw = new FileWriter(fileToDumpData);
         BufferedWriter bw = new BufferedWriter(fw);
-        bw.write(new String(uncompressed));
+        bw.write(new String(uncompressBytes));
         bw.flush();
         fw.flush();
         fw.close();
       } else if (fileType == FILE_TYPE_BINARY) {
         FileOutputStream fos = new FileOutputStream(fileToDumpData);
-        fos.write(uncompressed);
+        fos.write(uncompressBytes);
         fos.flush();
         fos.close();
       }

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/CompositeResultData.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/CompositeResultData.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/CompositeResultData.java
index 7d0d23b..c1db133 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/CompositeResultData.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/CompositeResultData.java
@@ -324,50 +324,4 @@ public class CompositeResultData extends AbstractResultData {
     // }
   }
 
-  public static void main(String[] args) {
-    CompositeResultData crd = new CompositeResultData();
-
-    SectionResultData r1Section = crd.addSection("R1");
-    r1Section.addData("Region", "R1").addData("IsPartitioned", false).addData("IsPersistent", true)
-        .addData("Disk Store", "DiskStore1").addData("Group", "Group1");
-    TabularResultData r1Table = r1Section.addTable("R1Members");
-    r1Table.accumulate("Member Id", "host1(3467):12435:12423")
-        .accumulate("PrimaryEntryCount", 20000).accumulate("BackupEntryCount", 20000)
-        .accumulate("Memory(MB)", "100").accumulate("NumOfCopies", 1);
-    r1Table.accumulate("Member Id", "host3(5756):57665:90923")
-        .accumulate("PrimaryEntryCount", 25000).accumulate("BackupEntryCount", 10000)
-        .accumulate("Memory(MB)", "200").accumulate("NumOfCopies", 1);
-
-    SectionResultData r3Section = crd.addSection("R3");
-    r3Section.addData("Region", "R3").addData("IsPartitioned", true).addData("IsPersistent", true)
-        .addData("Disk Store", "DiskStore2").addData("Group", "Group2")
-        .addData("ColocatedWith", "-");
-    SectionResultData r3SubSection = r3Section.addSection("R3Config");
-    r3SubSection.addData("Configuration", "");
-    r3SubSection.addData("Config1", "abcd");
-    r3SubSection.addData("Config2", "abcde");
-    r3SubSection.addData("Config3", "abcdfg");
-    TabularResultData r3Table = r3Section.addTable("R3Members");
-    r3Table.accumulate("Member Id", "host1(3467):12435:12423")
-        .accumulate("PrimaryEntryCount", 20000).accumulate("BackupEntryCount", 20000)
-        .accumulate("Memory(MB)", "100").accumulate("NumOfCopies", 1)
-        .accumulate("NumOfBuckets", 100);
-    r3Table.accumulate("Member Id", "host2(3353):23545:14723")
-        .accumulate("PrimaryEntryCount", 20000).accumulate("BackupEntryCount", 20000)
-        .accumulate("Memory(MB)", "100").accumulate("NumOfCopies", 1)
-        .accumulate("NumOfBuckets", 100);
-    r3Table.accumulate("Member Id", "host3(5756):57665:90923")
-        .accumulate("PrimaryEntryCount", 25000).accumulate("BackupEntryCount", 10000)
-        .accumulate("Memory(MB)", "200").accumulate("NumOfCopies", 1)
-        .accumulate("NumOfBuckets", 100);
-
-    try {
-      System.out.println(crd.getGfJsonObject().toIndentedString(/* 2 */0));
-
-    } catch (GfJsonException e) {
-      e.printStackTrace();
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-  }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java
index 06060a4..9bd2bf9 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/ResultBuilder.java
@@ -301,12 +301,6 @@ public class ResultBuilder {
         }
 
         @Override
-        public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
-            boolean addTimeStampToName) throws FileNotFoundException, IOException {
-          throw new UnsupportedOperationException("This is read only result data");
-        }
-
-        @Override
         public TabularResultData accumulate(String accumulateFor, Object value) {
           throw new UnsupportedOperationException("This is read only result data");
         }
@@ -326,12 +320,6 @@ public class ResultBuilder {
         }
 
         @Override
-        public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
-            boolean addTimeStampToName) throws FileNotFoundException, IOException {
-          throw new UnsupportedOperationException("This is read only result data");
-        }
-
-        @Override
         public ErrorResultData addLine(String line) {
           throw new UnsupportedOperationException("This is read only result data");
         }
@@ -351,12 +339,6 @@ public class ResultBuilder {
         }
 
         @Override
-        public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
-            boolean addTimeStampToName) throws FileNotFoundException, IOException {
-          throw new UnsupportedOperationException("This is read only result data");
-        }
-
-        @Override
         public ErrorResultData addLine(String line) {
           throw new UnsupportedOperationException("This is read only result data");
         }
@@ -381,12 +363,6 @@ public class ResultBuilder {
         }
 
         @Override
-        public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
-            boolean addTimeStampToName) throws FileNotFoundException, IOException {
-          throw new UnsupportedOperationException("This is read only result data");
-        }
-
-        @Override
         public SectionResultData addSection() {
           throw new UnsupportedOperationException("This is read only result data");
         }
@@ -416,12 +392,6 @@ public class ResultBuilder {
         }
 
         @Override
-        public ResultData addByteDataFromFileFile(String filePath, int fileType, String message,
-            boolean addTimeStampToName) throws FileNotFoundException, IOException {
-          throw new UnsupportedOperationException("This is read only result data");
-        }
-
-        @Override
         public ObjectResultData<CliJsonSerializable> addCollection(
             Collection<CliJsonSerializable> infoBeans) {
           throw new UnsupportedOperationException("This is read only result data");

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
index 21426d6..239810b 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
@@ -360,7 +360,11 @@ public abstract class CliCommandTestBase extends JUnit4CacheTestCase {
 
     CommandResult result = null;
     try {
-      result = (CommandResult) shell.getResult(); // TODO: this can result in ClassCastException if
+      Object result1 = shell.getResult();
+      if (result1 instanceof String) {
+        System.err.println("result1 = " + result1);
+      }
+      result = (CommandResult) result1; // TODO: this can result in ClassCastException if
                                                   // command resulted in error
     } catch (InterruptedException ex) {
       error("shell received InterruptedException");

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/CDL.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/CDL.java b/geode-json/src/main/java/org/json/CDL.java
deleted file mode 100755
index d78935b..0000000
--- a/geode-json/src/main/java/org/json/CDL.java
+++ /dev/null
@@ -1,272 +0,0 @@
-package org.json;
-
-/*
- * Copyright (c) 2002 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * This provides static methods to convert comma delimited text into a JSONArray, and to covert a
- * JSONArray into comma delimited text. Comma delimited text is a very popular format for data
- * interchange. It is understood by most database, spreadsheet, and organizer programs.
- * <p>
- * Each row of text represents a row in a table or a data record. Each row ends with a NEWLINE
- * character. Each row contains one or more values. Values are separated by commas. A value can
- * contain any character except for comma, unless is is wrapped in single quotes or double quotes.
- * <p>
- * The first row usually contains the names of the columns.
- * <p>
- * A comma delimited list can be converted into a JSONArray of JSONObjects. The names for the
- * elements in the JSONObjects can be taken from the names in the first row.
- * 
- * @author JSON.org
- * @version 2010-12-24
- */
-public class CDL {
-
-  /**
-   * Get the next value. The value can be wrapped in quotes. The value can be empty.
-   * 
-   * @param x A JSONTokener of the source text.
-   * @return The value string, or null if empty.
-   * @throws JSONException if the quoted string is badly formed.
-   */
-  private static String getValue(JSONTokener x) throws JSONException {
-    char c;
-    char q;
-    StringBuffer sb;
-    do {
-      c = x.next();
-    } while (c == ' ' || c == '\t');
-    switch (c) {
-      case 0:
-        return null;
-      case '"':
-      case '\'':
-        q = c;
-        sb = new StringBuffer();
-        for (;;) {
-          c = x.next();
-          if (c == q) {
-            break;
-          }
-          if (c == 0 || c == '\n' || c == '\r') {
-            throw x.syntaxError("Missing close quote '" + q + "'.");
-          }
-          sb.append(c);
-        }
-        return sb.toString();
-      case ',':
-        x.back();
-        return "";
-      default:
-        x.back();
-        return x.nextTo(',');
-    }
-  }
-
-  /**
-   * Produce a JSONArray of strings from a row of comma delimited values.
-   * 
-   * @param x A JSONTokener of the source text.
-   * @return A JSONArray of strings.
-   * @throws JSONException
-   */
-  public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
-    JSONArray ja = new JSONArray();
-    for (;;) {
-      String value = getValue(x);
-      char c = x.next();
-      if (value == null || (ja.length() == 0 && value.length() == 0 && c != ',')) {
-        return null;
-      }
-      ja.put(value);
-      for (;;) {
-        if (c == ',') {
-          break;
-        }
-        if (c != ' ') {
-          if (c == '\n' || c == '\r' || c == 0) {
-            return ja;
-          }
-          throw x.syntaxError("Bad character '" + c + "' (" + (int) c + ").");
-        }
-        c = x.next();
-      }
-    }
-  }
-
-  /**
-   * Produce a JSONObject from a row of comma delimited text, using a parallel JSONArray of strings
-   * to provides the names of the elements.
-   * 
-   * @param names A JSONArray of names. This is commonly obtained from the first row of a comma
-   *        delimited text file using the rowToJSONArray method.
-   * @param x A JSONTokener of the source text.
-   * @return A JSONObject combining the names and values.
-   * @throws JSONException
-   */
-  public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x) throws JSONException {
-    JSONArray ja = rowToJSONArray(x);
-    return ja != null ? ja.toJSONObject(names) : null;
-  }
-
-  /**
-   * Produce a comma delimited text row from a JSONArray. Values containing the comma character will
-   * be quoted. Troublesome characters may be removed.
-   * 
-   * @param ja A JSONArray of strings.
-   * @return A string ending in NEWLINE.
-   */
-  public static String rowToString(JSONArray ja) {
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < ja.length(); i += 1) {
-      if (i > 0) {
-        sb.append(',');
-      }
-      Object object = ja.opt(i);
-      if (object != null) {
-        String string = object.toString();
-        if (string.length() > 0 && (string.indexOf(',') >= 0 || string.indexOf('\n') >= 0
-            || string.indexOf('\r') >= 0 || string.indexOf(0) >= 0 || string.charAt(0) == '"')) {
-          sb.append('"');
-          int length = string.length();
-          for (int j = 0; j < length; j += 1) {
-            char c = string.charAt(j);
-            if (c >= ' ' && c != '"') {
-              sb.append(c);
-            }
-          }
-          sb.append('"');
-        } else {
-          sb.append(string);
-        }
-      }
-    }
-    sb.append('\n');
-    return sb.toString();
-  }
-
-  /**
-   * Produce a JSONArray of JSONObjects from a comma delimited text string, using the first row as a
-   * source of names.
-   * 
-   * @param string The comma delimited text.
-   * @return A JSONArray of JSONObjects.
-   * @throws JSONException
-   */
-  public static JSONArray toJSONArray(String string) throws JSONException {
-    return toJSONArray(new JSONTokener(string));
-  }
-
-  /**
-   * Produce a JSONArray of JSONObjects from a comma delimited text string, using the first row as a
-   * source of names.
-   * 
-   * @param x The JSONTokener containing the comma delimited text.
-   * @return A JSONArray of JSONObjects.
-   * @throws JSONException
-   */
-  public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
-    return toJSONArray(rowToJSONArray(x), x);
-  }
-
-  /**
-   * Produce a JSONArray of JSONObjects from a comma delimited text string using a supplied
-   * JSONArray as the source of element names.
-   * 
-   * @param names A JSONArray of strings.
-   * @param string The comma delimited text.
-   * @return A JSONArray of JSONObjects.
-   * @throws JSONException
-   */
-  public static JSONArray toJSONArray(JSONArray names, String string) throws JSONException {
-    return toJSONArray(names, new JSONTokener(string));
-  }
-
-  /**
-   * Produce a JSONArray of JSONObjects from a comma delimited text string using a supplied
-   * JSONArray as the source of element names.
-   * 
-   * @param names A JSONArray of strings.
-   * @param x A JSONTokener of the source text.
-   * @return A JSONArray of JSONObjects.
-   * @throws JSONException
-   */
-  public static JSONArray toJSONArray(JSONArray names, JSONTokener x) throws JSONException {
-    if (names == null || names.length() == 0) {
-      return null;
-    }
-    JSONArray ja = new JSONArray();
-    for (;;) {
-      JSONObject jo = rowToJSONObject(names, x);
-      if (jo == null) {
-        break;
-      }
-      ja.put(jo);
-    }
-    if (ja.length() == 0) {
-      return null;
-    }
-    return ja;
-  }
-
-
-  /**
-   * Produce a comma delimited text from a JSONArray of JSONObjects. The first row will be a list of
-   * names obtained by inspecting the first JSONObject.
-   * 
-   * @param ja A JSONArray of JSONObjects.
-   * @return A comma delimited text.
-   * @throws JSONException
-   */
-  public static String toString(JSONArray ja) throws JSONException {
-    JSONObject jo = ja.optJSONObject(0);
-    if (jo != null) {
-      JSONArray names = jo.names();
-      if (names != null) {
-        return rowToString(names) + toString(names, ja);
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Produce a comma delimited text from a JSONArray of JSONObjects using a provided list of names.
-   * The list of names is not included in the output.
-   * 
-   * @param names A JSONArray of strings.
-   * @param ja A JSONArray of JSONObjects.
-   * @return A comma delimited text.
-   * @throws JSONException
-   */
-  public static String toString(JSONArray names, JSONArray ja) throws JSONException {
-    if (names == null || names.length() == 0) {
-      return null;
-    }
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < ja.length(); i += 1) {
-      JSONObject jo = ja.optJSONObject(i);
-      if (jo != null) {
-        sb.append(rowToString(jo.toJSONArray(names)));
-      }
-    }
-    return sb.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/Cookie.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/Cookie.java b/geode-json/src/main/java/org/json/Cookie.java
deleted file mode 100755
index 21f88d8..0000000
--- a/geode-json/src/main/java/org/json/Cookie.java
+++ /dev/null
@@ -1,162 +0,0 @@
-package org.json;
-
-/*
- * Copyright (c) 2002 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * Convert a web browser cookie specification to a JSONObject and back. JSON and Cookies are both
- * notations for name/value pairs.
- * 
- * @author JSON.org
- * @version 2010-12-24
- */
-public class Cookie {
-
-  /**
-   * Produce a copy of a string in which the characters '+', '%', '=', ';' and control characters
-   * are replaced with "%hh". This is a gentle form of URL encoding, attempting to cause as little
-   * distortion to the string as possible. The characters '=' and ';' are meta characters in
-   * cookies. By convention, they are escaped using the URL-encoding. This is only a convention, not
-   * a standard. Often, cookies are expected to have encoded values. We encode '=' and ';' because
-   * we must. We encode '%' and '+' because they are meta characters in URL encoding.
-   * 
-   * @param string The source string.
-   * @return The escaped result.
-   */
-  public static String escape(String string) {
-    char c;
-    String s = string.trim();
-    StringBuffer sb = new StringBuffer();
-    int length = s.length();
-    for (int i = 0; i < length; i += 1) {
-      c = s.charAt(i);
-      if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') {
-        sb.append('%');
-        sb.append(Character.forDigit((char) ((c >>> 4) & 0x0f), 16));
-        sb.append(Character.forDigit((char) (c & 0x0f), 16));
-      } else {
-        sb.append(c);
-      }
-    }
-    return sb.toString();
-  }
-
-
-  /**
-   * Convert a cookie specification string into a JSONObject. The string will contain a name value
-   * pair separated by '='. The name and the value will be unescaped, possibly converting '+' and
-   * '%' sequences. The cookie properties may follow, separated by ';', also represented as
-   * name=value (except the secure property, which does not have a value). The name will be stored
-   * under the key "name", and the value will be stored under the key "value". This method does not
-   * do checking or validation of the parameters. It only converts the cookie string into a
-   * JSONObject.
-   * 
-   * @param string The cookie specification string.
-   * @return A JSONObject containing "name", "value", and possibly other members.
-   * @throws JSONException
-   */
-  public static JSONObject toJSONObject(String string) throws JSONException {
-    String name;
-    JSONObject jo = new JSONObject();
-    Object value;
-    JSONTokener x = new JSONTokener(string);
-    jo.put("name", x.nextTo('='));
-    x.next('=');
-    jo.put("value", x.nextTo(';'));
-    x.next();
-    while (x.more()) {
-      name = unescape(x.nextTo("=;"));
-      if (x.next() != '=') {
-        if (name.equals("secure")) {
-          value = Boolean.TRUE;
-        } else {
-          throw x.syntaxError("Missing '=' in cookie parameter.");
-        }
-      } else {
-        value = unescape(x.nextTo(';'));
-        x.next();
-      }
-      jo.put(name, value);
-    }
-    return jo;
-  }
-
-
-  /**
-   * Convert a JSONObject into a cookie specification string. The JSONObject must contain "name" and
-   * "value" members. If the JSONObject contains "expires", "domain", "path", or "secure" members,
-   * they will be appended to the cookie specification string. All other members are ignored.
-   * 
-   * @param jo A JSONObject
-   * @return A cookie specification string
-   * @throws JSONException
-   */
-  public static String toString(JSONObject jo) throws JSONException {
-    StringBuffer sb = new StringBuffer();
-
-    sb.append(escape(jo.getString("name")));
-    sb.append("=");
-    sb.append(escape(jo.getString("value")));
-    if (jo.has("expires")) {
-      sb.append(";expires=");
-      sb.append(jo.getString("expires"));
-    }
-    if (jo.has("domain")) {
-      sb.append(";domain=");
-      sb.append(escape(jo.getString("domain")));
-    }
-    if (jo.has("path")) {
-      sb.append(";path=");
-      sb.append(escape(jo.getString("path")));
-    }
-    if (jo.optBoolean("secure")) {
-      sb.append(";secure");
-    }
-    return sb.toString();
-  }
-
-  /**
-   * Convert <code>%</code><i>hh</i> sequences to single characters, and convert plus to space.
-   * 
-   * @param string A string that may contain <code>+</code>&nbsp;<small>(plus)</small> and
-   *        <code>%</code><i>hh</i> sequences.
-   * @return The unescaped string.
-   */
-  public static String unescape(String string) {
-    int length = string.length();
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < length; ++i) {
-      char c = string.charAt(i);
-      if (c == '+') {
-        c = ' ';
-      } else if (c == '%' && i + 2 < length) {
-        int d = JSONTokener.dehexchar(string.charAt(i + 1));
-        int e = JSONTokener.dehexchar(string.charAt(i + 2));
-        if (d >= 0 && e >= 0) {
-          c = (char) (d * 16 + e);
-          i += 2;
-        }
-      }
-      sb.append(c);
-    }
-    return sb.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/CookieList.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/CookieList.java b/geode-json/src/main/java/org/json/CookieList.java
deleted file mode 100755
index 35e1a97..0000000
--- a/geode-json/src/main/java/org/json/CookieList.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.json;
-
-/*
- * Copyright (c) 2002 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-import java.util.Iterator;
-
-/**
- * Convert a web browser cookie list string to a JSONObject and back.
- * 
- * @author JSON.org
- * @version 2010-12-24
- */
-public class CookieList {
-
-  /**
-   * Convert a cookie list into a JSONObject. A cookie list is a sequence of name/value pairs. The
-   * names are separated from the values by '='. The pairs are separated by ';'. The names and the
-   * values will be unescaped, possibly converting '+' and '%' sequences.
-   *
-   * To add a cookie to a cooklist, cookielistJSONObject.put(cookieJSONObject.getString("name"),
-   * cookieJSONObject.getString("value"));
-   * 
-   * @param string A cookie list string
-   * @return A JSONObject
-   * @throws JSONException
-   */
-  public static JSONObject toJSONObject(String string) throws JSONException {
-    JSONObject jo = new JSONObject();
-    JSONTokener x = new JSONTokener(string);
-    while (x.more()) {
-      String name = Cookie.unescape(x.nextTo('='));
-      x.next('=');
-      jo.put(name, Cookie.unescape(x.nextTo(';')));
-      x.next();
-    }
-    return jo;
-  }
-
-
-  /**
-   * Convert a JSONObject into a cookie list. A cookie list is a sequence of name/value pairs. The
-   * names are separated from the values by '='. The pairs are separated by ';'. The characters '%',
-   * '+', '=', and ';' in the names and values are replaced by "%hh".
-   * 
-   * @param jo A JSONObject
-   * @return A cookie list string
-   * @throws JSONException
-   */
-  public static String toString(JSONObject jo) throws JSONException {
-    boolean b = false;
-    Iterator keys = jo.keys();
-    String string;
-    StringBuffer sb = new StringBuffer();
-    while (keys.hasNext()) {
-      string = keys.next().toString();
-      if (!jo.isNull(string)) {
-        if (b) {
-          sb.append(';');
-        }
-        sb.append(Cookie.escape(string));
-        sb.append("=");
-        sb.append(Cookie.escape(jo.getString(string)));
-        b = true;
-      }
-    }
-    return sb.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/HTTP.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/HTTP.java b/geode-json/src/main/java/org/json/HTTP.java
deleted file mode 100755
index 1e815aa..0000000
--- a/geode-json/src/main/java/org/json/HTTP.java
+++ /dev/null
@@ -1,185 +0,0 @@
-package org.json;
-
-/*
- * Copyright (c) 2002 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-import java.util.Iterator;
-
-/**
- * Convert an HTTP header to a JSONObject and back.
- * 
- * @author JSON.org
- * @version 2010-12-24
- */
-public class HTTP {
-
-  /** Carriage return/line feed. */
-  public static final String CRLF = "\r\n";
-
-  /**
-   * Convert an HTTP header string into a JSONObject. It can be a request header or a response
-   * header. A request header will contain
-   * 
-   * <pre>
-   * {
-   *    Method: "POST" (for example),
-   *    "Request-URI": "/" (for example),
-   *    "HTTP-Version": "HTTP/1.1" (for example)
-   * }
-   * </pre>
-   * 
-   * A response header will contain
-   * 
-   * <pre>
-   * {
-   *    "HTTP-Version": "HTTP/1.1" (for example),
-   *    "Status-Code": "200" (for example),
-   *    "Reason-Phrase": "OK" (for example)
-   * }
-   * </pre>
-   * 
-   * In addition, the other parameters in the header will be captured, using the HTTP field names as
-   * JSON names, so that
-   * 
-   * <pre>
-   *    Date: Sun, 26 May 2002 18:06:04 GMT
-   *    Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s
-   *    Cache-Control: no-cache
-   * </pre>
-   * 
-   * become
-   * 
-   * <pre>
-   * {...
-   *    Date: "Sun, 26 May 2002 18:06:04 GMT",
-   *    Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s",
-   *    "Cache-Control": "no-cache",
-   * ...}
-   * </pre>
-   * 
-   * It does no further checking or conversion. It does not parse dates. It does not do '%'
-   * transforms on URLs.
-   * 
-   * @param string An HTTP header string.
-   * @return A JSONObject containing the elements and attributes of the XML string.
-   * @throws JSONException
-   */
-  public static JSONObject toJSONObject(String string) throws JSONException {
-    JSONObject jo = new JSONObject();
-    HTTPTokener x = new HTTPTokener(string);
-    String token;
-
-    token = x.nextToken();
-    if (token.toUpperCase().startsWith("HTTP")) {
-
-      // Response
-
-      jo.put("HTTP-Version", token);
-      jo.put("Status-Code", x.nextToken());
-      jo.put("Reason-Phrase", x.nextTo('\0'));
-      x.next();
-
-    } else {
-
-      // Request
-
-      jo.put("Method", token);
-      jo.put("Request-URI", x.nextToken());
-      jo.put("HTTP-Version", x.nextToken());
-    }
-
-    // Fields
-
-    while (x.more()) {
-      String name = x.nextTo(':');
-      x.next(':');
-      jo.put(name, x.nextTo('\0'));
-      x.next();
-    }
-    return jo;
-  }
-
-
-  /**
-   * Convert a JSONObject into an HTTP header. A request header must contain
-   * 
-   * <pre>
-   * {
-   *    Method: "POST" (for example),
-   *    "Request-URI": "/" (for example),
-   *    "HTTP-Version": "HTTP/1.1" (for example)
-   * }
-   * </pre>
-   * 
-   * A response header must contain
-   * 
-   * <pre>
-   * {
-   *    "HTTP-Version": "HTTP/1.1" (for example),
-   *    "Status-Code": "200" (for example),
-   *    "Reason-Phrase": "OK" (for example)
-   * }
-   * </pre>
-   * 
-   * Any other members of the JSONObject will be output as HTTP fields. The result will end with two
-   * CRLF pairs.
-   * 
-   * @param jo A JSONObject
-   * @return An HTTP header string.
-   * @throws JSONException if the object does not contain enough information.
-   */
-  public static String toString(JSONObject jo) throws JSONException {
-    Iterator keys = jo.keys();
-    String string;
-    StringBuffer sb = new StringBuffer();
-    if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
-      sb.append(jo.getString("HTTP-Version"));
-      sb.append(' ');
-      sb.append(jo.getString("Status-Code"));
-      sb.append(' ');
-      sb.append(jo.getString("Reason-Phrase"));
-    } else if (jo.has("Method") && jo.has("Request-URI")) {
-      sb.append(jo.getString("Method"));
-      sb.append(' ');
-      sb.append('"');
-      sb.append(jo.getString("Request-URI"));
-      sb.append('"');
-      sb.append(' ');
-      sb.append(jo.getString("HTTP-Version"));
-    } else {
-      throw new JSONException("Not enough material for an HTTP header.");
-    }
-    sb.append(CRLF);
-    while (keys.hasNext()) {
-      string = keys.next().toString();
-      if (!"HTTP-Version".equals(string) && !"Status-Code".equals(string)
-          && !"Reason-Phrase".equals(string) && !"Method".equals(string)
-          && !"Request-URI".equals(string) && !jo.isNull(string)) {
-        sb.append(string);
-        sb.append(": ");
-        sb.append(jo.getString(string));
-        sb.append(CRLF);
-      }
-    }
-    sb.append(CRLF);
-    return sb.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/HTTPTokener.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/HTTPTokener.java b/geode-json/src/main/java/org/json/HTTPTokener.java
deleted file mode 100755
index 72c9b88..0000000
--- a/geode-json/src/main/java/org/json/HTTPTokener.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.json;
-
-/*
- * Copyright (c) 2002 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * The HTTPTokener extends the JSONTokener to provide additional methods for the parsing of HTTP
- * headers.
- * 
- * @author JSON.org
- * @version 2010-12-24
- */
-public class HTTPTokener extends JSONTokener {
-
-  /**
-   * Construct an HTTPTokener from a string.
-   * 
-   * @param string A source string.
-   */
-  public HTTPTokener(String string) {
-    super(string);
-  }
-
-
-  /**
-   * Get the next token or string. This is used in parsing HTTP headers.
-   * 
-   * @throws JSONException
-   * @return A String.
-   */
-  public String nextToken() throws JSONException {
-    char c;
-    char q;
-    StringBuffer sb = new StringBuffer();
-    do {
-      c = next();
-    } while (Character.isWhitespace(c));
-    if (c == '"' || c == '\'') {
-      q = c;
-      for (;;) {
-        c = next();
-        if (c < ' ') {
-          throw syntaxError("Unterminated string.");
-        }
-        if (c == q) {
-          return sb.toString();
-        }
-        sb.append(c);
-      }
-    }
-    for (;;) {
-      if (c == 0 || Character.isWhitespace(c)) {
-        return sb.toString();
-      }
-      sb.append(c);
-      c = next();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/JSON.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSON.java b/geode-json/src/main/java/org/json/JSON.java
new file mode 100755
index 0000000..1b32e69
--- /dev/null
+++ b/geode-json/src/main/java/org/json/JSON.java
@@ -0,0 +1,116 @@
+/*
+ * 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.json;
+
+class JSON {
+    /**
+     * Returns the input if it is a JSON-permissible value; throws otherwise.
+     */
+    static double checkDouble(double d) throws JSONException {
+        if (Double.isInfinite(d) || Double.isNaN(d)) {
+            throw new JSONException("Forbidden numeric value: " + d);
+        }
+        return d;
+    }
+
+    static Boolean toBoolean(Object value) {
+        if (value instanceof Boolean) {
+            return (Boolean) value;
+        } else if (value instanceof String) {
+            String stringValue = (String) value;
+            if ("true".equalsIgnoreCase(stringValue)) {
+                return true;
+            } else if ("false".equalsIgnoreCase(stringValue)) {
+                return false;
+            }
+        }
+        return null;
+    }
+
+    static Double toDouble(Object value) {
+        if (value instanceof Double) {
+            return (Double) value;
+        } else if (value instanceof Number) {
+            return ((Number) value).doubleValue();
+        } else if (value instanceof String) {
+            try {
+                return Double.valueOf((String) value);
+            } catch (NumberFormatException ignored) {
+            }
+        }
+        return null;
+    }
+
+    static Integer toInteger(Object value) {
+        if (value instanceof Integer) {
+            return (Integer) value;
+        } else if (value instanceof Number) {
+            return ((Number) value).intValue();
+        } else if (value instanceof String) {
+            try {
+                return (int) Double.parseDouble((String) value);
+            } catch (NumberFormatException ignored) {
+            }
+        }
+        return null;
+    }
+
+    static Long toLong(Object value) {
+        if (value instanceof Long) {
+            return (Long) value;
+        } else if (value instanceof Number) {
+            return ((Number) value).longValue();
+        } else if (value instanceof String) {
+            try {
+                return (long) Double.parseDouble((String) value);
+            } catch (NumberFormatException ignored) {
+            }
+        }
+        return null;
+    }
+
+    static String toString(Object value) {
+        if (value instanceof String) {
+            return (String) value;
+        } else if (value != null) {
+            return String.valueOf(value);
+        }
+        return null;
+    }
+
+    public static JSONException typeMismatch(Object indexOrName, Object actual,
+            String requiredType) throws JSONException {
+        if (actual == null) {
+            throw new JSONException("Value at " + indexOrName + " is null.");
+        } else {
+            throw new JSONException("Value " + actual + " at " + indexOrName
+                    + " of type " + actual.getClass().getName()
+                    + " cannot be converted to " + requiredType);
+        }
+    }
+
+    public static JSONException typeMismatch(Object actual, String requiredType)
+            throws JSONException {
+        if (actual == null) {
+            throw new JSONException("Value is null.");
+        } else {
+            throw new JSONException("Value " + actual
+                    + " of type " + actual.getClass().getName()
+                    + " cannot be converted to " + requiredType);
+        }
+    }
+}


[7/8] geode git commit: GEODE-2142: Spotless

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/geode-json/src/main/java/org/json/JSONObject.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONObject.java b/geode-json/src/main/java/org/json/JSONObject.java
index d5de19f..bddfb56 100755
--- a/geode-json/src/main/java/org/json/JSONObject.java
+++ b/geode-json/src/main/java/org/json/JSONObject.java
@@ -1,17 +1,15 @@
 /*
  * 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
+ * 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
+ * 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.
+ * 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.json;
@@ -33,55 +31,53 @@ import java.util.TreeMap;
 // 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.
+ * 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.
+ * <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".
+ * <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:
+ * <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 JSONException} if the requested name has no value
- * or if the value cannot be coerced to the requested type.
- * <li>Use <code>opt<i>Type</i>()</code> to retrieve an optional value. This
- * returns a system- or user-supplied default if the requested name has no
- * value or if the value cannot be coerced to the requested type.
+ * <li>Use <code>get<i>Type</i>()</code> to retrieve a mandatory value. This fails with a
+ * {@code JSONException} if the requested name has no value or if the value cannot be coerced to the
+ * requested type.
+ * <li>Use <code>opt<i>Type</i>()</code> to retrieve an optional value. This returns a system- or
+ * user-supplied default if the requested name has no value or if the value cannot be coerced to the
+ * requested type.
  * </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>
+ * <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. Although this class is
- * nonfinal, it was not designed for inheritance and should not be subclassed.
- * In particular, self-use by overrideable methods is not specified. See
- * <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
+ * <p>
+ * Instances of this class are not thread safe. Although this class is nonfinal, it was not designed
+ * for inheritance and should not be subclassed. In particular, self-use by overrideable methods is
+ * not specified. See <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
  * prohibit it" for further information.
  */
 public class JSONObject {
@@ -92,8 +88,8 @@ public class JSONObject {
   public static ThreadLocal<Boolean> cyclicDepChkEnabled = new ThreadLocal();
 
   /**
-   * A sentinel value used to explicitly define a name with no value. Unlike
-   * {@code null}, names with this value:
+   * 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
@@ -102,9 +98,9 @@ public class JSONObject {
    * <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".
+   * <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 Object() {
     @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
@@ -135,21 +131,21 @@ public class JSONObject {
   }
 
   /**
-   * Creates a new {@code JSONObject} by copying all name/value mappings from
-   * the given map.
+   * Creates a new {@code JSONObject} by copying all name/value mappings from the given map.
+   * 
    * @param copyFrom a map whose keys are of type {@link String} and whose values are of supported
-   * types.
+   *        types.
    * @throws NullPointerException if any of the map's keys are null.
    */
-    /* (accept a raw type for API compatibility) */
+  /* (accept a raw type for API compatibility) */
   public JSONObject(Map copyFrom) {
     this();
     Map<?, ?> contentsTyped = (Map<?, ?>) copyFrom;
     for (Map.Entry<?, ?> entry : contentsTyped.entrySet()) {
-            /*
-             * Deviate from the original by checking that keys are non-null and
-             * of the proper type. (We still defer validating the values).
-             */
+      /*
+       * Deviate from the original by checking that keys are non-null and of the proper type. (We
+       * still defer validating the values).
+       */
       String key = (String) entry.getKey();
       if (key == null) {
         throw new NullPointerException("key == null");
@@ -159,16 +155,16 @@ public class JSONObject {
   }
 
   /**
-   * Creates a new {@code JSONObject} with name/value mappings from the next
-   * object in the tokener.
+   * 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 JSONException if the parse fails or doesn't yield a {@code JSONObject}.
    */
   public JSONObject(JSONTokener readFrom) throws JSONException {
-        /*
-         * Getting the parser to populate this could get tricky. Instead, just
-         * parse to temporary JSONObject and then steal the data from that.
-         */
+    /*
+     * 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();
     if (object instanceof JSONObject) {
       this.nameValuePairs = ((JSONObject) object).nameValuePairs;
@@ -178,8 +174,8 @@ public class JSONObject {
   }
 
   /**
-   * Creates a new {@code JSONObject} with name/value mappings from the JSON
-   * string.
+   * Creates a new {@code JSONObject} with name/value mappings from the JSON string.
+   * 
    * @param json a JSON-encoded string containing an object.
    * @throws JSONException if the parse fails or doesn't yield a {@code JSONObject}.
    */
@@ -188,9 +184,9 @@ public class JSONObject {
   }
 
   /**
-   * 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.
+   * 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 JSONException On internal errors. Shouldn't happen.
@@ -207,6 +203,7 @@ public class JSONObject {
 
   /**
    * Creates a json object from a bean
+   * 
    * @param bean the bean to create the json object from
    * @throws JSONException If there is an exception while reading the bean
    */
@@ -214,7 +211,7 @@ public class JSONObject {
     this(propertiesAsMap(bean));
   }
 
-  //This is custom properties mapping specific for GEODE
+  // This is custom properties mapping specific for GEODE
   private static Map<String, Object> propertiesAsMap(Object bean) {
     Map<String, Object> props = new TreeMap();
     Class klass = bean.getClass();
@@ -273,6 +270,7 @@ public class JSONObject {
 
   /**
    * Returns the number of name/value mappings in this object.
+   * 
    * @return the length of this.
    */
   public int length() {
@@ -280,8 +278,9 @@ public class JSONObject {
   }
 
   /**
-   * Maps {@code name} to {@code value}, clobbering any existing name/value
-   * mapping with the same name.
+   * Maps {@code name} to {@code value}, clobbering any existing name/value mapping with the same
+   * name.
+   * 
    * @param name The name of the value to insert.
    * @param value The value to insert.
    * @return this object.
@@ -293,11 +292,12 @@ public class JSONObject {
   }
 
   /**
-   * Maps {@code name} to {@code value}, clobbering any existing name/value
-   * mapping with the same name.
+   * Maps {@code name} to {@code value}, clobbering any existing name/value mapping with the same
+   * name.
+   * 
    * @param name The name for the new value.
-   * @param value a finite value. May not be {@link Double#isNaN() NaNs} or {@link
-   * Double#isInfinite() infinities}.
+   * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+   *        {@link Double#isInfinite() infinities}.
    * @return this object.
    * @throws JSONException if value is NaN or infinite.
    */
@@ -307,8 +307,9 @@ public class JSONObject {
   }
 
   /**
-   * Maps {@code name} to {@code value}, clobbering any existing name/value
-   * mapping with the same name.
+   * Maps {@code name} to {@code value}, clobbering any existing name/value mapping with the same
+   * name.
+   * 
    * @param name The name for the new value.
    * @param value The new value.
    * @return this object.
@@ -320,8 +321,9 @@ public class JSONObject {
   }
 
   /**
-   * Maps {@code name} to {@code value}, clobbering any existing name/value
-   * mapping with the same name.
+   * Maps {@code name} to {@code value}, clobbering any existing name/value mapping with the same
+   * name.
+   * 
    * @param name The name of the new value.
    * @param value The new value to insert.
    * @return this object.
@@ -333,13 +335,13 @@ public class JSONObject {
   }
 
   /**
-   * 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.
+   * 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}.
+   *        {@link #NULL}, or {@code null}. May not be {@link Double#isNaN() NaNs} or
+   *        {@link Double#isInfinite() infinities}.
    * @return this object.
    * @throws JSONException if the value is an invalid double (infinite or NaN).
    */
@@ -371,8 +373,9 @@ public class JSONObject {
   }
 
   /**
-   * Equivalent to {@code put(name, value)} when both parameters are non-null;
-   * does nothing otherwise.
+   * Equivalent to {@code put(name, value)} when both parameters are non-null; does nothing
+   * otherwise.
+   * 
    * @param name The name of the value to insert.
    * @param value The value to insert.
    * @return this object.
@@ -386,22 +389,21 @@ public class JSONObject {
   }
 
   /**
-   * 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.
+   * 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}
+   * 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}.
+   *        {@link #NULL} or null. May not be {@link Double#isNaN() NaNs} or
+   *        {@link Double#isInfinite() infinities}.
    * @return this object after mutation.
    * @throws JSONException If the object being added is an invalid number.
    */
@@ -426,15 +428,15 @@ public class JSONObject {
   }
 
   /**
-   * 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 JSONException}
-   * will be thrown.
+   * 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 JSONException} 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 JSONException if {@code name} is {@code null} or if the mapping for {@code name} is
-   * non-null and is not a {@link JSONArray}.
+   *         non-null and is not a {@link JSONArray}.
    */
   public JSONObject append(String name, Object value) throws JSONException {
     Object current = nameValuePairs.get(checkName(name));
@@ -464,6 +466,7 @@ public class JSONObject {
 
   /**
    * 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.
    */
@@ -472,8 +475,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns true if this object has no mapping for {@code name} or if it has
-   * a mapping whose value is {@link #NULL}.
+   * 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.
    */
@@ -483,8 +487,8 @@ public class JSONObject {
   }
 
   /**
-   * Returns true if this object has a mapping for {@code name}. The mapping
-   * may be {@link #NULL}.
+   * Returns true if this object has a mapping for {@code name}. The mapping may be {@link #NULL}.
+   * 
    * @param name The name of the value to check on.
    * @return true if this object has a field named {@code name}
    */
@@ -494,6 +498,7 @@ public class JSONObject {
 
   /**
    * 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 JSONException if no such mapping exists.
@@ -507,8 +512,8 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name}, or null if no such mapping
-   * exists.
+   * 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.
    */
@@ -517,8 +522,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists and is a boolean or
-   * can be coerced to a boolean, or throws otherwise.
+   * 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 JSONException if the mapping doesn't exist or cannot be coerced to a boolean.
@@ -533,8 +539,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists and is a boolean or
-   * can be coerced to a boolean, or false otherwise.
+   * Returns the value mapped by {@code name} if it exists and is a boolean or can be coerced to a
+   * boolean, or false otherwise.
+   * 
    * @param name The name of the field we want.
    * @return The selected value if it exists.
    */
@@ -543,8 +550,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists and is a boolean or
-   * can be coerced to a boolean, or {@code fallback} otherwise.
+   * Returns the value mapped by {@code name} if it exists and is a boolean or can be coerced to a
+   * boolean, or {@code fallback} otherwise.
+   * 
    * @param name The name of the field we want.
    * @param fallback The value to return if the field isn't there.
    * @return The selected value or the fallback.
@@ -556,8 +564,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists and is a double or
-   * can be coerced to a double, or throws otherwise.
+   * 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 JSONException if the mapping doesn't exist or cannot be coerced to a double.
@@ -572,8 +581,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists and is a double or
-   * can be coerced to a double, or {@code NaN} otherwise.
+   * Returns the value mapped by {@code name} if it exists and is a double or can be coerced to a
+   * double, or {@code NaN} otherwise.
+   * 
    * @param name The name of the field we want.
    * @return The selected value if it exists.
    */
@@ -582,8 +592,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists and is a double or
-   * can be coerced to a double, or {@code fallback} otherwise.
+   * Returns the value mapped by {@code name} if it exists and is a double or can be coerced to a
+   * double, or {@code fallback} otherwise.
+   * 
    * @param name The name of the field we want.
    * @param fallback The value to return if the field isn't there.
    * @return The selected value or the fallback.
@@ -595,8 +606,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists and is an int or
-   * can be coerced to an int, or throws otherwise.
+   * 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 JSONException if the mapping doesn't exist or cannot be coerced to an int.
@@ -611,8 +623,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists and is an int or
-   * can be coerced to an int, or 0 otherwise.
+   * Returns the value mapped by {@code name} if it exists and is an int or can be coerced to an
+   * int, or 0 otherwise.
+   * 
    * @param name The name of the field we want.
    * @return The selected value if it exists.
    */
@@ -621,8 +634,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists and is an int or
-   * can be coerced to an int, or {@code fallback} otherwise.
+   * Returns the value mapped by {@code name} if it exists and is an int or can be coerced to an
+   * int, or {@code fallback} otherwise.
+   * 
    * @param name The name of the field we want.
    * @param fallback The value to return if the field isn't there.
    * @return The selected value or the fallback.
@@ -634,12 +648,11 @@ public class JSONObject {
   }
 
   /**
-   * 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,
+   * 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.
+   * 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 JSONException if the mapping doesn't exist or cannot be coerced to a long.
@@ -654,9 +667,10 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists and is a long or
-   * can be coerced to a long, or 0 otherwise. Note that JSON represents numbers as doubles,
-   * so this is <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
+   * Returns the value mapped by {@code name} if it exists and is a long or can be coerced to a
+   * long, or 0 otherwise. Note that JSON represents numbers as doubles, so this is
+   * <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
+   * 
    * @param name The name of the field we want.
    * @return The selected value.
    */
@@ -665,10 +679,10 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists and is a long or
-   * can be coerced to a long, or {@code fallback} otherwise. Note that JSON represents
-   * numbers as doubles, so this is <a href="#lossy">lossy</a>; use strings to transfer
-   * numbers via JSON.
+   * Returns the value mapped by {@code name} if it exists and is a long or can be coerced to a
+   * long, or {@code fallback} otherwise. Note that JSON represents numbers as doubles, so this is
+   * <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
+   * 
    * @param name The name of the field we want.
    * @param fallback The value to return if the field isn't there.
    * @return The selected value or the fallback.
@@ -680,8 +694,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists, coercing it if
-   * necessary, or throws if no such mapping exists.
+   * 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 JSONException if no such mapping exists.
@@ -696,8 +711,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists, coercing it if
-   * necessary, or the empty string if no such mapping exists.
+   * Returns the value mapped by {@code name} if it exists, coercing it if necessary, or the empty
+   * string if no such mapping exists.
+   * 
    * @param name The name of the field we want.
    * @return The value of the field.
    */
@@ -706,8 +722,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns the value mapped by {@code name} if it exists, coercing it if
-   * necessary, or {@code fallback} if no such mapping exists.
+   * Returns the value mapped by {@code name} if it exists, coercing it if necessary, or
+   * {@code fallback} if no such mapping exists.
+   * 
    * @param name The name of the field that we want.
    * @param fallback The value to return if the field doesn't exist.
    * @return The value of the field or fallback.
@@ -721,6 +738,7 @@ public class JSONObject {
   /**
    * 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 JSONException if the mapping doesn't exist or is not a {@code JSONArray}.
@@ -737,6 +755,7 @@ public class JSONObject {
   /**
    * Returns the value mapped by {@code name} if it exists and is a {@code
    * JSONArray}, or null otherwise.
+   * 
    * @param name The name of the field we want.
    * @return The value of the specified field (assuming it is a JSNOArray
    */
@@ -748,6 +767,7 @@ public class JSONObject {
   /**
    * 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 JSONException if the mapping doesn't exist or is not a {@code JSONObject}.
@@ -764,6 +784,7 @@ public class JSONObject {
   /**
    * Returns the value mapped by {@code name} if it exists and is a {@code
    * JSONObject}, or null otherwise.
+   * 
    * @param name The name of the value we want.
    * @return The specified value.
    */
@@ -773,9 +794,9 @@ public class JSONObject {
   }
 
   /**
-   * Returns an array with the values corresponding to {@code names}. The
-   * array contains null for names that aren't mapped. This method returns
-   * null if {@code names} is either null or empty.
+   * Returns an array with the values corresponding to {@code names}. The array contains null for
+   * names that aren't mapped. This method returns null if {@code names} is either null or empty.
+   * 
    * @param names The names of the fields that we want the values for.
    * @return The selected values.
    * @throws JSONException On internal errors. Shouldn't happen.
@@ -797,11 +818,11 @@ public class JSONObject {
   }
 
   /**
-   * Returns an iterator of the {@code String} names in this object. The
-   * returned iterator supports {@link Iterator#remove() remove}, which will
-   * remove the corresponding mapping from this object. If this object is
-   * modified after the iterator is returned, the iterator's behavior is
+   * Returns an iterator of the {@code String} names in this object. The returned iterator supports
+   * {@link Iterator#remove() remove}, which will remove the corresponding mapping from this object.
+   * If this object is modified after the iterator is returned, the iterator's behavior is
    * undefined. The order of the keys is undefined.
+   * 
    * @return an iterator over the keys.
    */
   public Iterator<String> keys() {
@@ -809,12 +830,12 @@ public class JSONObject {
   }
 
   /**
-   * 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.
+   * 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> keySet() {
@@ -822,19 +843,22 @@ public class JSONObject {
   }
 
   /**
-   * Returns an array containing the string names in this object. This method
-   * returns null if this object contains no mappings.
+   * 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
+    return nameValuePairs.isEmpty() ? null
         : new JSONArray(new ArrayList<String>(nameValuePairs.keySet()));
   }
 
   /**
    * Encodes this object as a compact JSON string, such as:
-   * <pre>{"query":"Pizza","locations":[94043,90210]}</pre>
+   * 
+   * <pre>
+   * {"query":"Pizza","locations":[94043,90210]}
+   * </pre>
    */
   @Override
   public String toString() {
@@ -848,8 +872,8 @@ public class JSONObject {
   }
 
   /**
-   * Encodes this object as a human readable JSON string for debugging, such
-   * as:
+   * Encodes this object as a human readable JSON string for debugging, such as:
+   * 
    * <pre>
    * {
    *     "query": "Pizza",
@@ -857,7 +881,9 @@ public class JSONObject {
    *         94043,
    *         90210
    *     ]
-   * }</pre>
+   * }
+   * </pre>
+   * 
    * @param indentSpaces the number of spaces to indent for each level of nesting.
    * @return The string containing the pretty form of this.
    * @throws JSONException On internal errors. Shouldn't happen.
@@ -878,8 +904,9 @@ public class JSONObject {
 
   /**
    * Encodes the number as a JSON string.
-   * @param number a finite value. May not be {@link Double#isNaN() NaNs} or {@link
-   * Double#isInfinite() infinities}.
+   * 
+   * @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 JSONException On internal errors. Shouldn't happen.
    */
@@ -905,8 +932,9 @@ public class JSONObject {
   }
 
   /**
-   * Encodes {@code data} as a JSON string. This applies quotes and any
-   * necessary character escaping.
+   * 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.
    */
@@ -928,7 +956,8 @@ public class JSONObject {
   /**
    * Wraps the given object if necessary.
    *
-   * <p>If the object is null or , returns {@link #NULL}. If the object is a {@code JSONArray} or
+   * <p>
+   * If the object is null or , returns {@link #NULL}. If the object is a {@code JSONArray} or
    * {@code JSONObject}, no wrapping is necessary. If the object is {@code NULL}, no wrapping is
    * necessary. If the object is an array or {@code Collection}, returns an equivalent {@code
    * JSONArray}. If the object is a {@code Map}, returns an equivalent {@code JSONObject}. If the
@@ -936,6 +965,7 @@ public class JSONObject {
    * a {@code java} package, returns the result of {@code toString}. If the object is some other
    * kind of object then it is assumed to be a bean and is converted to a JSONObject. If wrapping
    * fails, returns null.
+   * 
    * @param o The object to wrap.
    * @return The wrapped (if necessary) form of the object {$code o}
    */
@@ -958,34 +988,28 @@ public class JSONObject {
       if (o instanceof Map) {
         return new JSONObject((Map) o);
       }
-      if (o instanceof Boolean ||
-          o instanceof Byte ||
-          o instanceof Character ||
-          o instanceof Double ||
-          o instanceof Float ||
-          o instanceof Integer ||
-          o instanceof Long ||
-          o instanceof Short ||
-          o instanceof String) {
+      if (o instanceof Boolean || o instanceof Byte || o instanceof Character || o instanceof Double
+          || o instanceof Float || o instanceof Integer || o instanceof Long || o instanceof Short
+          || o instanceof String) {
         return o;
       }
       // GEODE-2142: Added check to ignore GemFireCacheImpl
-//      if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?>) {
-//        return o.toString();
-//      }
+      // if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?>) {
+      // return o.toString();
+      // }
       Package objectPackage = o.getClass().getPackage();
       String objectPackageName = objectPackage != null ? objectPackage.getName() : "";
-      if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.") || o instanceof Enum<?>
-          || o.getClass().getClassLoader() == null
+      if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.")
+          || o instanceof Enum<?> || o.getClass().getClassLoader() == null
           || o.getClass().getName().contains("GemFireCacheImpl")) {
         return o.toString();
       }
-//      if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?> ||
-//          || objectPackageName.startsWith("javax.")
-//          || o.getClass().getClassLoader() == null
-//          o.getClass().getName().contains("GemFireCacheImpl")) {
-//        return o.toString();
-//      }
+      // if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?> ||
+      // || objectPackageName.startsWith("javax.")
+      // || o.getClass().getClassLoader() == null
+      // o.getClass().getName().contains("GemFireCacheImpl")) {
+      // return o.toString();
+      // }
       // GEODE-2142: Added the cyclicalDepCheck
       if (cyclicDepChkEnabled.get() != null && cyclicDependencySet.get() != null) {
         if (cyclicDepChkEnabled.get() && cyclicDependencySet.get().contains(o)) {
@@ -1002,4 +1026,4 @@ public class JSONObject {
     }
     return null;
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/geode-json/src/main/java/org/json/JSONString.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONString.java b/geode-json/src/main/java/org/json/JSONString.java
index 34815a8..4a09d89 100755
--- a/geode-json/src/main/java/org/json/JSONString.java
+++ b/geode-json/src/main/java/org/json/JSONString.java
@@ -1,18 +1,17 @@
 package org.json;
+
 /**
- * The <code>JSONString</code> interface allows a <code>toJSONString()</code> 
- * method so that a class can change the behavior of 
- * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
- * and <code>JSONWriter.value(</code>Object<code>)</code>. The 
- * <code>toJSONString</code> method will be used instead of the default behavior 
- * of using the Object's <code>toString()</code> method and quoting the result.
+ * The <code>JSONString</code> interface allows a <code>toJSONString()</code> method so that a class
+ * can change the behavior of <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
+ * and <code>JSONWriter.value(</code>Object<code>)</code>. The <code>toJSONString</code> method will
+ * be used instead of the default behavior of using the Object's <code>toString()</code> method and
+ * quoting the result.
  */
 public interface JSONString {
   /**
-   * The <code>toJSONString</code> method allows a class to produce its own JSON 
-   * serialization. 
+   * The <code>toJSONString</code> method allows a class to produce its own JSON serialization.
    * 
    * @return A strictly syntactically correct JSON text.
    */
   public String toJSONString();
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/geode-json/src/main/java/org/json/JSONStringer.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONStringer.java b/geode-json/src/main/java/org/json/JSONStringer.java
index db1121e..43224a5 100755
--- a/geode-json/src/main/java/org/json/JSONStringer.java
+++ b/geode-json/src/main/java/org/json/JSONStringer.java
@@ -1,17 +1,15 @@
 /*
  * 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
+ * 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
+ * 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.
+ * 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.json;
@@ -23,448 +21,439 @@ import java.util.List;
 // Note: this class was written without inspecting the non-free org.json sourcecode.
 
 /**
- * Implements {@link JSONObject#toString} and {@link JSONArray#toString}. Most
- * application developers should use those methods directly and disregard this
- * API. For example:<pre>
+ * Implements {@link JSONObject#toString} and {@link JSONArray#toString}. Most application
+ * developers should use those methods directly and disregard this API. For example:
+ * 
+ * <pre>
  * JSONObject object = ...
- * String json = object.toString();</pre>
+ * String json = object.toString();
+ * </pre>
  *
- * <p>Stringers only encode well-formed JSON strings. In particular:
+ * <p>
+ * Stringers only encode well-formed JSON strings. In particular:
  * <ul>
  * <li>The stringer must have exactly one top-level array or object.
- * <li>Lexical scopes must be balanced: every call to {@link #array} must
- * have a matching call to {@link #endArray} and every call to {@link
- * #object} must have a matching call to {@link #endObject}.
+ * <li>Lexical scopes must be balanced: every call to {@link #array} must have a matching call to
+ * {@link #endArray} and every call to {@link #object} must have a matching call to
+ * {@link #endObject}.
  * <li>Arrays may not contain keys (property names).
  * <li>Objects must alternate keys (property names) and values.
- * <li>Values are inserted with either literal {@link #value(Object) value}
- * calls, or by nesting arrays or objects.
+ * <li>Values are inserted with either literal {@link #value(Object) value} calls, or by nesting
+ * arrays or objects.
  * </ul>
- * Calls that would result in a malformed JSON string will fail with a
- * {@link JSONException}.
+ * Calls that would result in a malformed JSON string will fail with a {@link JSONException}.
  *
- * <p>This class provides no facility for pretty-printing (ie. indenting)
- * output. To encode indented output, use {@link JSONObject#toString(int)} or
- * {@link JSONArray#toString(int)}.
+ * <p>
+ * This class provides no facility for pretty-printing (ie. indenting) output. To encode indented
+ * output, use {@link JSONObject#toString(int)} or {@link JSONArray#toString(int)}.
  *
- * <p>Some implementations of the API support at most 20 levels of nesting.
- * Attempts to create more than 20 levels of nesting may fail with a {@link
- * JSONException}.
+ * <p>
+ * Some implementations of the API support at most 20 levels of nesting. Attempts to create more
+ * than 20 levels of nesting may fail with a {@link JSONException}.
  *
- * <p>Each stringer may be used to encode a single top level value. Instances of
- * this class are not thread safe. Although this class is nonfinal, it was not
- * designed for inheritance and should not be subclassed. In particular,
- * self-use by overrideable methods is not specified. See <i>Effective Java</i>
- * Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * <p>
+ * Each stringer may be used to encode a single top level value. Instances of this class are not
+ * thread safe. Although this class is nonfinal, it was not designed for inheritance and should not
+ * be subclassed. In particular, self-use by overrideable methods is not specified. See <i>Effective
+ * Java</i> Item 17, "Design and Document or inheritance or else prohibit it" for further
  * information.
  */
 public class JSONStringer {
 
-    /**
-     * The output data, containing at most one top-level array or object.
-     */
-    final StringBuilder out = new StringBuilder();
+  /**
+   * The output data, containing at most one top-level array or object.
+   */
+  final StringBuilder out = new StringBuilder();
 
-    /**
-     * Lexical scoping elements within this stringer, necessary to insert the
-     * appropriate separator characters (ie. commas and colons) and to detect
-     * nesting errors.
-     */
-    enum Scope {
-
-        /**
-         * An array with no elements requires no separators or newlines before
-         * it is closed.
-         */
-        EMPTY_ARRAY,
-
-        /**
-         * A array with at least one value requires a comma and newline before
-         * the next element.
-         */
-        NONEMPTY_ARRAY,
-
-        /**
-         * An object with no keys or values requires no separators or newlines
-         * before it is closed.
-         */
-        EMPTY_OBJECT,
-
-        /**
-         * An object whose most recent element is a key. The next element must
-         * be a value.
-         */
-        DANGLING_KEY,
-
-        /**
-         * An object with at least one name/value pair requires a comma and
-         * newline before the next element.
-         */
-        NONEMPTY_OBJECT,
-
-        /**
-         * A special bracketless array needed by JSONStringer.join() and
-         * JSONObject.quote() only. Not used for JSON encoding.
-         */
-        NULL,
-    }
+  /**
+   * Lexical scoping elements within this stringer, necessary to insert the appropriate separator
+   * characters (ie. commas and colons) and to detect nesting errors.
+   */
+  enum Scope {
 
     /**
-     * Unlike the original implementation, this stack isn't limited to 20
-     * levels of nesting.
+     * An array with no elements requires no separators or newlines before it is closed.
      */
-    private final List<Scope> stack = new ArrayList<Scope>();
+    EMPTY_ARRAY,
 
     /**
-     * A string containing a full set of spaces for a single level of
-     * indentation, or null for no pretty printing.
+     * A array with at least one value requires a comma and newline before the next element.
      */
-    private final String indent;
-
-    public JSONStringer() {
-        indent = null;
-    }
-
-    JSONStringer(int indentSpaces) {
-        char[] indentChars = new char[indentSpaces];
-        Arrays.fill(indentChars, ' ');
-        indent = new String(indentChars);
-    }
+    NONEMPTY_ARRAY,
 
     /**
-     * Begins encoding a new array. Each call to this method must be paired with
-     * a call to {@link #endArray}.
-     *
-     * @return this stringer.
-     * @throws JSONException On internal errors. Shouldn't happen.
+     * An object with no keys or values requires no separators or newlines before it is closed.
      */
-    public JSONStringer array() throws JSONException {
-        return open(Scope.EMPTY_ARRAY, "[");
-    }
+    EMPTY_OBJECT,
 
     /**
-     * Ends encoding the current array.
-     *
-     * @return this stringer.
-     * @throws JSONException On internal errors. Shouldn't happen.
+     * An object whose most recent element is a key. The next element must be a value.
      */
-    public JSONStringer endArray() throws JSONException {
-        return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]");
-    }
+    DANGLING_KEY,
 
     /**
-     * Begins encoding a new object. Each call to this method must be paired
-     * with a call to {@link #endObject}.
-     *
-     * @return this stringer.
-     * @throws JSONException On internal errors. Shouldn't happen.
+     * An object with at least one name/value pair requires a comma and newline before the next
+     * element.
      */
-    public JSONStringer object() throws JSONException {
-        return open(Scope.EMPTY_OBJECT, "{");
-    }
+    NONEMPTY_OBJECT,
 
     /**
-     * Ends encoding the current object.
-     *
-     * @return this stringer.
-     * @throws JSONException On internal errors. Shouldn't happen.
+     * A special bracketless array needed by JSONStringer.join() and JSONObject.quote() only. Not
+     * used for JSON encoding.
      */
-    public JSONStringer endObject() throws JSONException {
-        return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}");
+    NULL,
+  }
+
+  /**
+   * Unlike the original implementation, this stack isn't limited to 20 levels of nesting.
+   */
+  private final List<Scope> stack = new ArrayList<Scope>();
+
+  /**
+   * A string containing a full set of spaces for a single level of indentation, or null for no
+   * pretty printing.
+   */
+  private final String indent;
+
+  public JSONStringer() {
+    indent = null;
+  }
+
+  JSONStringer(int indentSpaces) {
+    char[] indentChars = new char[indentSpaces];
+    Arrays.fill(indentChars, ' ');
+    indent = new String(indentChars);
+  }
+
+  /**
+   * Begins encoding a new array. Each call to this method must be paired with a call to
+   * {@link #endArray}.
+   *
+   * @return this stringer.
+   * @throws JSONException On internal errors. Shouldn't happen.
+   */
+  public JSONStringer array() throws JSONException {
+    return open(Scope.EMPTY_ARRAY, "[");
+  }
+
+  /**
+   * Ends encoding the current array.
+   *
+   * @return this stringer.
+   * @throws JSONException On internal errors. Shouldn't happen.
+   */
+  public JSONStringer endArray() throws JSONException {
+    return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]");
+  }
+
+  /**
+   * Begins encoding a new object. Each call to this method must be paired with a call to
+   * {@link #endObject}.
+   *
+   * @return this stringer.
+   * @throws JSONException On internal errors. Shouldn't happen.
+   */
+  public JSONStringer object() throws JSONException {
+    return open(Scope.EMPTY_OBJECT, "{");
+  }
+
+  /**
+   * Ends encoding the current object.
+   *
+   * @return this stringer.
+   * @throws JSONException On internal errors. Shouldn't happen.
+   */
+  public JSONStringer endObject() throws JSONException {
+    return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}");
+  }
+
+  /**
+   * Enters a new scope by appending any necessary whitespace and the given bracket.
+   */
+  JSONStringer open(Scope empty, String openBracket) throws JSONException {
+    if (stack.isEmpty() && out.length() > 0) {
+      throw new JSONException("Nesting problem: multiple top-level roots");
     }
-
-    /**
-     * Enters a new scope by appending any necessary whitespace and the given
-     * bracket.
-     */
-    JSONStringer open(Scope empty, String openBracket) throws JSONException {
-        if (stack.isEmpty() && out.length() > 0) {
-            throw new JSONException("Nesting problem: multiple top-level roots");
-        }
-        beforeValue();
-        stack.add(empty);
-        out.append(openBracket);
-        return this;
+    beforeValue();
+    stack.add(empty);
+    out.append(openBracket);
+    return this;
+  }
+
+  /**
+   * Closes the current scope by appending any necessary whitespace and the given bracket.
+   */
+  JSONStringer close(Scope empty, Scope nonempty, String closeBracket) throws JSONException {
+    Scope context = peek();
+    if (context != nonempty && context != empty) {
+      throw new JSONException("Nesting problem");
     }
 
-    /**
-     * Closes the current scope by appending any necessary whitespace and the
-     * given bracket.
-     */
-    JSONStringer close(Scope empty, Scope nonempty, String closeBracket) throws JSONException {
-        Scope context = peek();
-        if (context != nonempty && context != empty) {
-            throw new JSONException("Nesting problem");
-        }
-
-        stack.remove(stack.size() - 1);
-        if (context == nonempty) {
-            newline();
-        }
-        out.append(closeBracket);
-        return this;
+    stack.remove(stack.size() - 1);
+    if (context == nonempty) {
+      newline();
     }
-
-    /**
-     * Returns the value on the top of the stack.
-     */
-    private Scope peek() throws JSONException {
-        if (stack.isEmpty()) {
-            throw new JSONException("Nesting problem");
-        }
-        return stack.get(stack.size() - 1);
+    out.append(closeBracket);
+    return this;
+  }
+
+  /**
+   * Returns the value on the top of the stack.
+   */
+  private Scope peek() throws JSONException {
+    if (stack.isEmpty()) {
+      throw new JSONException("Nesting problem");
     }
-
-    /**
-     * Replace the value on the top of the stack with the given value.
-     */
-    private void replaceTop(Scope topOfStack) {
-        stack.set(stack.size() - 1, topOfStack);
+    return stack.get(stack.size() - 1);
+  }
+
+  /**
+   * Replace the value on the top of the stack with the given value.
+   */
+  private void replaceTop(Scope topOfStack) {
+    stack.set(stack.size() - 1, topOfStack);
+  }
+
+  /**
+   * Encodes {@code value}.
+   *
+   * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double or
+   *        null. May not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
+   * @return this stringer.
+   * @throws JSONException On internal errors. Shouldn't happen.
+   */
+  public JSONStringer value(Object value) throws JSONException {
+    if (stack.isEmpty()) {
+      throw new JSONException("Nesting problem");
     }
 
-    /**
-     * Encodes {@code value}.
-     *
-     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
-     *              Integer, Long, Double or null. May not be {@link Double#isNaN() NaNs}
-     *              or {@link Double#isInfinite() infinities}.
-     * @return this stringer.
-     * @throws JSONException On internal errors. Shouldn't happen.
-     */
-    public JSONStringer value(Object value) throws JSONException {
-        if (stack.isEmpty()) {
-            throw new JSONException("Nesting problem");
-        }
-
-        if (value instanceof JSONArray) {
-            ((JSONArray) value).writeTo(this);
-            return this;
-
-        } else if (value instanceof JSONObject) {
-            ((JSONObject) value).writeTo(this);
-            return this;
-        }
-
-        beforeValue();
-
-        if (value instanceof JSONString) {
-          out.append(((JSONString) value).toJSONString());
-          return this;
-        }
-
-        if (value == null
-              || value instanceof Boolean
-              || value == JSONObject.NULL) {
-            out.append(value);
-
-        } else if (value instanceof Number) {
-            out.append(JSONObject.numberToString((Number) value));
-
-        } else {
-            // Hack to make it possible that the value is not surrounded by quotes. (Used for JavaScript function calls)
-            // Example: { "name": "testkey", "value": window.myfunction() }
-            if (value.getClass().getSimpleName().contains("JSONFunction")) {
-                // note that no escaping of quotes (or anything else) is done in this case.
-                // that is fine because the only way to get to this point is to
-                // explicitly put a special kind of object into the JSON data structure.
-                out.append(value);
-            } else {
-                string(value.toString());
-            }
-        }
-
-        return this;
-    }
+    if (value instanceof JSONArray) {
+      ((JSONArray) value).writeTo(this);
+      return this;
 
-    /**
-     * Encodes {@code value} to this stringer.
-     *
-     * @param value The value to encode.
-     * @return this stringer.
-     * @throws JSONException On internal errors. Shouldn't happen.
-     */
-    public JSONStringer value(boolean value) throws JSONException {
-        if (stack.isEmpty()) {
-            throw new JSONException("Nesting problem");
-        }
-        beforeValue();
-        out.append(value);
-        return this;
+    } else if (value instanceof JSONObject) {
+      ((JSONObject) value).writeTo(this);
+      return this;
     }
 
-    /**
-     * Encodes {@code value} to this stringer.
-     *
-     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
-     *              {@link Double#isInfinite() infinities}.
-     * @return this stringer.
-     * @throws JSONException On internal errors. Shouldn't happen.
-     */
-    public JSONStringer value(double value) throws JSONException {
-        if (stack.isEmpty()) {
-            throw new JSONException("Nesting problem");
-        }
-        beforeValue();
-        out.append(JSONObject.numberToString(value));
-        return this;
+    beforeValue();
+
+    if (value instanceof JSONString) {
+      out.append(((JSONString) value).toJSONString());
+      return this;
     }
 
-    /**
-     * Encodes {@code value} to this stringer.
-     *
-     * @param value The value to encode.
-     * @return this stringer.
-     * @throws JSONException If we have an internal error. Shouldn't happen.
-     */
-    public JSONStringer value(long value) throws JSONException {
-        if (stack.isEmpty()) {
-            throw new JSONException("Nesting problem");
-        }
-        beforeValue();
+    if (value == null || value instanceof Boolean || value == JSONObject.NULL) {
+      out.append(value);
+
+    } else if (value instanceof Number) {
+      out.append(JSONObject.numberToString((Number) value));
+
+    } else {
+      // Hack to make it possible that the value is not surrounded by quotes. (Used for JavaScript
+      // function calls)
+      // Example: { "name": "testkey", "value": window.myfunction() }
+      if (value.getClass().getSimpleName().contains("JSONFunction")) {
+        // note that no escaping of quotes (or anything else) is done in this case.
+        // that is fine because the only way to get to this point is to
+        // explicitly put a special kind of object into the JSON data structure.
         out.append(value);
-        return this;
+      } else {
+        string(value.toString());
+      }
     }
 
-    private void string(String value) {
-        out.append("\"");
-        char currentChar = 0;
-
-        for (int i = 0, length = value.length(); i < length; i++) {
-            char previousChar = currentChar;
-            currentChar = value.charAt(i);
-
-            /*
-             * From RFC 4627, "All Unicode characters may be placed within the
-             * quotation marks except for the characters that must be escaped:
-             * quotation mark, reverse solidus, and the control characters
-             * (U+0000 through U+001F)."
-             */
-            switch (currentChar) {
-                case '"':
-                case '\\':
-                    out.append('\\').append(currentChar);
-                    break;
-
-                case '/':
-                    // it makes life easier for HTML embedding of javascript if we escape </ sequences
-                    if (previousChar == '<') {
-                        out.append('\\');
-                    }
-                    out.append(currentChar);
-                    break;
-
-                case '\t':
-                    out.append("\\t");
-                    break;
-
-                case '\b':
-                    out.append("\\b");
-                    break;
-
-                case '\n':
-                    out.append("\\n");
-                    break;
-
-                case '\r':
-                    out.append("\\r");
-                    break;
-
-                case '\f':
-                    out.append("\\f");
-                    break;
-
-                default:
-                    if (currentChar <= 0x1F) {
-                        out.append(String.format("\\u%04x", (int) currentChar));
-                    } else {
-                        out.append(currentChar);
-                    }
-                    break;
-            }
-
-        }
-        out.append("\"");
+    return this;
+  }
+
+  /**
+   * Encodes {@code value} to this stringer.
+   *
+   * @param value The value to encode.
+   * @return this stringer.
+   * @throws JSONException On internal errors. Shouldn't happen.
+   */
+  public JSONStringer value(boolean value) throws JSONException {
+    if (stack.isEmpty()) {
+      throw new JSONException("Nesting problem");
     }
-
-    private void newline() {
-        if (indent == null) {
-            return;
-        }
-
-        out.append("\n");
-        for (int i = 0; i < stack.size(); i++) {
-            out.append(indent);
-        }
+    beforeValue();
+    out.append(value);
+    return this;
+  }
+
+  /**
+   * Encodes {@code value} to this stringer.
+   *
+   * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+   *        {@link Double#isInfinite() infinities}.
+   * @return this stringer.
+   * @throws JSONException On internal errors. Shouldn't happen.
+   */
+  public JSONStringer value(double value) throws JSONException {
+    if (stack.isEmpty()) {
+      throw new JSONException("Nesting problem");
     }
+    beforeValue();
+    out.append(JSONObject.numberToString(value));
+    return this;
+  }
+
+  /**
+   * Encodes {@code value} to this stringer.
+   *
+   * @param value The value to encode.
+   * @return this stringer.
+   * @throws JSONException If we have an internal error. Shouldn't happen.
+   */
+  public JSONStringer value(long value) throws JSONException {
+    if (stack.isEmpty()) {
+      throw new JSONException("Nesting problem");
+    }
+    beforeValue();
+    out.append(value);
+    return this;
+  }
+
+  private void string(String value) {
+    out.append("\"");
+    char currentChar = 0;
+
+    for (int i = 0, length = value.length(); i < length; i++) {
+      char previousChar = currentChar;
+      currentChar = value.charAt(i);
+
+      /*
+       * From RFC 4627, "All Unicode characters may be placed within the quotation marks except for
+       * the characters that must be escaped: quotation mark, reverse solidus, and the control
+       * characters (U+0000 through U+001F)."
+       */
+      switch (currentChar) {
+        case '"':
+        case '\\':
+          out.append('\\').append(currentChar);
+          break;
+
+        case '/':
+          // it makes life easier for HTML embedding of javascript if we escape </ sequences
+          if (previousChar == '<') {
+            out.append('\\');
+          }
+          out.append(currentChar);
+          break;
+
+        case '\t':
+          out.append("\\t");
+          break;
+
+        case '\b':
+          out.append("\\b");
+          break;
+
+        case '\n':
+          out.append("\\n");
+          break;
+
+        case '\r':
+          out.append("\\r");
+          break;
+
+        case '\f':
+          out.append("\\f");
+          break;
+
+        default:
+          if (currentChar <= 0x1F) {
+            out.append(String.format("\\u%04x", (int) currentChar));
+          } else {
+            out.append(currentChar);
+          }
+          break;
+      }
 
-    /**
-     * Encodes the key (property name) to this stringer.
-     *
-     * @param name the name of the forthcoming value. May not be null.
-     * @return this stringer.
-     * @throws JSONException on internal errors, shouldn't happen.
-     */
-    public JSONStringer key(String name) throws JSONException {
-        if (name == null) {
-            throw new JSONException("Names must be non-null");
-        }
-        beforeKey();
-        string(name);
-        return this;
     }
+    out.append("\"");
+  }
 
-    /**
-     * Inserts any necessary separators and whitespace before a name. Also
-     * adjusts the stack to expect the key's value.
-     */
-    private void beforeKey() throws JSONException {
-        Scope context = peek();
-        if (context == Scope.NONEMPTY_OBJECT) { // first in object
-            out.append(',');
-        } else if (context != Scope.EMPTY_OBJECT) { // not in an object!
-            throw new JSONException("Nesting problem");
-        }
-        newline();
-        replaceTop(Scope.DANGLING_KEY);
+  private void newline() {
+    if (indent == null) {
+      return;
     }
 
-    /**
-     * Inserts any necessary separators and whitespace before a literal value,
-     * inline array, or inline object. Also adjusts the stack to expect either a
-     * closing bracket or another element.
-     */
-    private void beforeValue() throws JSONException {
-        if (stack.isEmpty()) {
-            return;
-        }
-
-        Scope context = peek();
-        if (context == Scope.EMPTY_ARRAY) { // first in array
-            replaceTop(Scope.NONEMPTY_ARRAY);
-            newline();
-        } else if (context == Scope.NONEMPTY_ARRAY) { // another in array
-            out.append(',');
-            newline();
-        } else if (context == Scope.DANGLING_KEY) { // value for key
-            out.append(indent == null ? ":" : ": ");
-            replaceTop(Scope.NONEMPTY_OBJECT);
-        } else if (context != Scope.NULL) {
-            throw new JSONException("Nesting problem");
-        }
+    out.append("\n");
+    for (int i = 0; i < stack.size(); i++) {
+      out.append(indent);
+    }
+  }
+
+  /**
+   * Encodes the key (property name) to this stringer.
+   *
+   * @param name the name of the forthcoming value. May not be null.
+   * @return this stringer.
+   * @throws JSONException on internal errors, shouldn't happen.
+   */
+  public JSONStringer key(String name) throws JSONException {
+    if (name == null) {
+      throw new JSONException("Names must be non-null");
+    }
+    beforeKey();
+    string(name);
+    return this;
+  }
+
+  /**
+   * Inserts any necessary separators and whitespace before a name. Also adjusts the stack to expect
+   * the key's value.
+   */
+  private void beforeKey() throws JSONException {
+    Scope context = peek();
+    if (context == Scope.NONEMPTY_OBJECT) { // first in object
+      out.append(',');
+    } else if (context != Scope.EMPTY_OBJECT) { // not in an object!
+      throw new JSONException("Nesting problem");
+    }
+    newline();
+    replaceTop(Scope.DANGLING_KEY);
+  }
+
+  /**
+   * Inserts any necessary separators and whitespace before a literal value, inline array, or inline
+   * object. Also adjusts the stack to expect either a closing bracket or another element.
+   */
+  private void beforeValue() throws JSONException {
+    if (stack.isEmpty()) {
+      return;
     }
 
-    /**
-     * Returns the encoded JSON string.
-     *
-     * <p>If invoked with unterminated arrays or unclosed objects, this method's
-     * return value is undefined.
-     *
-     * <p><strong>Warning:</strong> although it contradicts the general contract
-     * of {@link Object#toString}, this method returns null if the stringer
-     * contains no data.
-     */
-    @Override
-    public String toString() {
-        return out.length() == 0 ? null : out.toString();
+    Scope context = peek();
+    if (context == Scope.EMPTY_ARRAY) { // first in array
+      replaceTop(Scope.NONEMPTY_ARRAY);
+      newline();
+    } else if (context == Scope.NONEMPTY_ARRAY) { // another in array
+      out.append(',');
+      newline();
+    } else if (context == Scope.DANGLING_KEY) { // value for key
+      out.append(indent == null ? ":" : ": ");
+      replaceTop(Scope.NONEMPTY_OBJECT);
+    } else if (context != Scope.NULL) {
+      throw new JSONException("Nesting problem");
     }
+  }
+
+  /**
+   * Returns the encoded JSON string.
+   *
+   * <p>
+   * If invoked with unterminated arrays or unclosed objects, this method's return value is
+   * undefined.
+   *
+   * <p>
+   * <strong>Warning:</strong> although it contradicts the general contract of
+   * {@link Object#toString}, this method returns null if the stringer contains no data.
+   */
+  @Override
+  public String toString() {
+    return out.length() == 0 ? null : out.toString();
+  }
 }


[3/8] geode git commit: GEODE-2142: Removal of non-compliant org.json implementation.

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/JSONObject.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONObject.java b/geode-json/src/main/java/org/json/JSONObject.java
index a2c6d8b..d5de19f 100755
--- a/geode-json/src/main/java/org/json/JSONObject.java
+++ b/geode-json/src/main/java/org/json/JSONObject.java
@@ -1,1525 +1,1005 @@
-package org.json;
-
 /*
- * Copyright (c) 2002 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
  */
 
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.reflect.Field;
+package org.json;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
-import java.util.Locale;
 import java.util.Map;
-import java.util.ResourceBundle;
 import java.util.Set;
+import java.util.TreeMap;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
 
 /**
- * A JSONObject is an unordered collection of name/value pairs. Its external form is a string
- * wrapped in curly braces with colons between the names and values, and commas between the values
- * and names. The internal form is an object having <code>get</code> and <code>opt</code> methods
- * for accessing the values by name, and <code>put</code> methods for adding or replacing values by
- * name. The values can be any of these types: <code>Boolean</code>, <code>JSONArray</code>,
- * <code>JSONObject</code>, <code>Number</code>, <code>String</code>, or the
- * <code>JSONObject.NULL</code> object. A JSONObject constructor can be used to convert an external
- * form JSON text into an internal form whose values can be retrieved with the <code>get</code> and
- * <code>opt</code> methods, or to convert values into a JSON text using the <code>put</code> and
- * <code>toString</code> methods. A <code>get</code> method returns a value if one can be found, and
- * throws an exception if one cannot be found. An <code>opt</code> method returns a default value
- * instead of throwing an exception, and so is useful for obtaining optional values.
- * <p>
- * The generic <code>get()</code> and <code>opt()</code> methods return an object, which you can
- * cast or query for type. There are also typed <code>get</code> and <code>opt</code> methods that
- * do type checking and type coercion for you. The opt methods differ from the get methods in that
- * they do not throw. Instead, they return a specified value, such as null.
- * <p>
- * The <code>put</code> methods add or replace values in an object. For example,
+ * 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.
  *
- * <pre>
- * myString = new JSONObject().put(&quot;JSON&quot;, &quot;Hello, World!&quot;).toString();
- * </pre>
+ * <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>
  *
- * produces the string <code>{"JSON": "Hello, World"}</code>.
- * <p>
- * The texts produced by the <code>toString</code> methods strictly conform to the JSON syntax
- * rules. The constructors are more forgiving in the texts they will accept:
+ * <p>This class can look up both mandatory and optional values:
  * <ul>
- * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just before the closing
- * brace.</li>
- * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single quote)</small>.</li>
- * <li>Strings do not need to be quoted at all if they do not begin with a quote or single quote,
- * and if they do not contain leading or trailing spaces, and if they do not contain any of these
- * characters: <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers and if they
- * are not the reserved words <code>true</code>, <code>false</code>, or <code>null</code>.</li>
- * <li>Keys can be followed by <code>=</code> or <code>=></code> as well as by <code>:</code>.</li>
- * <li>Values can be followed by <code>;</code> <small>(semicolon)</small> as well as by
- * <code>,</code> <small>(comma)</small>.</li>
+ * <li>Use <code>get<i>Type</i>()</code> to retrieve a mandatory value. This
+ * fails with a {@code JSONException} if the requested name has no value
+ * or if the value cannot be coerced to the requested type.
+ * <li>Use <code>opt<i>Type</i>()</code> to retrieve an optional value. This
+ * returns a system- or user-supplied default if the requested name has no
+ * value or if the value cannot be coerced to the requested type.
  * </ul>
  *
- * @author JSON.org
- * @version 2012-05-29
+ * <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. Although this class is
+ * nonfinal, it was not designed for inheritance and should not be subclassed.
+ * In particular, self-use by overrideable methods is not specified. See
+ * <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
+ * prohibit it" for further information.
  */
 public class JSONObject {
+
+  private static final Double NEGATIVE_ZERO = -0d;
+
+  public static ThreadLocal<Set> cyclicDependencySet = new ThreadLocal();
+  public static ThreadLocal<Boolean> cyclicDepChkEnabled = new ThreadLocal();
+
   /**
-   * JSONObject.NULL is equivalent to the value that JavaScript calls null, whilst Java's null is
-   * equivalent to the value that JavaScript calls undefined.
+   * 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(String)}
+   * <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".
    */
-  private static final class Null {
-
-    /**
-     * There is only intended to be a single instance of the NULL object, so the clone method
-     * returns itself.
-     * 
-     * @return NULL.
-     */
-    protected final Object clone() {
-      return this;
+  public static final Object NULL = new Object() {
+    @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
+    @Override
+    public boolean equals(Object o) {
+      return o == this || o == null; // API specifies this broken equals implementation
     }
 
-    /**
-     * A Null object is equal to the null value and to itself.
-     * 
-     * @param object An object to test for nullness.
-     * @return true if the object parameter is the JSONObject.NULL object or null.
-     */
-    public boolean equals(Object object) {
-      return object == null || object == this;
+    // at least make the broken equals(null) consistent with Objects.hashCode(null).
+    @Override
+    public int hashCode() {
+      return 0;
     }
 
-    /**
-     * Get the "null" string value.
-     * 
-     * @return The string "null".
-     */
+    @Override
     public String toString() {
       return "null";
     }
-  }
-
-
-  /**
-   * The map where the JSONObject's properties are kept.
-   */
-  private final Map map;
-
-
-  /**
-   * It is sometimes more convenient and less ambiguous to have a <code>NULL</code> object than to
-   * use Java's <code>null</code> value. <code>JSONObject.NULL.equals(null)</code> returns
-   * <code>true</code>. <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>.
-   */
-  public static final Object NULL = new Null();
-
-
-  public static ThreadLocal<Set> cyclicDependencySet = new ThreadLocal();
-  public static ThreadLocal<Boolean> cyclicDepChkEnabled = new ThreadLocal();
+  };
 
+  private final LinkedHashMap<String, Object> nameValuePairs;
 
   /**
-   * Construct an empty JSONObject.
+   * Creates a {@code JSONObject} with no name/value mappings.
    */
   public JSONObject() {
-    this.map = new LinkedHashMap();
+    nameValuePairs = new LinkedHashMap<String, Object>();
   }
 
-
   /**
-   * Construct a JSONObject from a subset of another JSONObject. An array of strings is used to
-   * identify the keys that should be copied. Missing keys are ignored.
-   * 
-   * @param jo A JSONObject.
-   * @param names An array of strings.
+   * Creates a new {@code JSONObject} by copying all name/value mappings from
+   * the given map.
+   * @param copyFrom a map whose keys are of type {@link String} and whose values are of supported
+   * types.
+   * @throws NullPointerException if any of the map's keys are null.
    */
-  public JSONObject(JSONObject jo, String[] names) {
+    /* (accept a raw type for API compatibility) */
+  public JSONObject(Map copyFrom) {
     this();
-    for (int i = 0; i < names.length; i += 1) {
-      try {
-        this.putOnce(names[i], jo.opt(names[i]));
-      } catch (Exception ignore) {
-      }
-    }
-  }
-
-
-  /**
-   * Construct a JSONObject from a JSONTokener.
-   * 
-   * @param x A JSONTokener object containing the source string.
-   * @throws JSONException If there is a syntax error in the source string or a duplicated key.
-   */
-  public JSONObject(JSONTokener x) throws JSONException {
-    this();
-    char c;
-    String key;
-
-    if (x.nextClean() != '{') {
-      throw x.syntaxError("A JSONObject text must begin with '{'");
-    }
-    for (;;) {
-      c = x.nextClean();
-      switch (c) {
-        case 0:
-          throw x.syntaxError("A JSONObject text must end with '}'");
-        case '}':
-          return;
-        default:
-          x.back();
-          key = x.nextValue().toString();
-      }
-
-      // The key is followed by ':'. We will also tolerate '=' or '=>'.
-
-      c = x.nextClean();
-      if (c == '=') {
-        if (x.next() != '>') {
-          x.back();
-        }
-      } else if (c != ':') {
-        throw x.syntaxError("Expected a ':' after a key");
-      }
-      this.putOnce(key, x.nextValue());
-
-      // Pairs are separated by ','. We will also tolerate ';'.
-
-      switch (x.nextClean()) {
-        case ';':
-        case ',':
-          if (x.nextClean() == '}') {
-            return;
-          }
-          x.back();
-          break;
-        case '}':
-          return;
-        default:
-          throw x.syntaxError("Expected a ',' or '}'");
+    Map<?, ?> contentsTyped = (Map<?, ?>) copyFrom;
+    for (Map.Entry<?, ?> entry : contentsTyped.entrySet()) {
+            /*
+             * Deviate from the original by checking that keys are non-null and
+             * of the proper type. (We still defer validating the values).
+             */
+      String key = (String) entry.getKey();
+      if (key == null) {
+        throw new NullPointerException("key == null");
       }
+      nameValuePairs.put(key, wrap(entry.getValue()));
     }
   }
 
-
   /**
-   * Construct a JSONObject from a Map.
-   *
-   * @param map A map object that can be used to initialize the contents of the JSONObject.
+   * 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 JSONException if the parse fails or doesn't yield a {@code JSONObject}.
    */
-  public JSONObject(Map map) {
-    this.map = new LinkedHashMap();
-    if (map != null) {
-      Iterator i = map.entrySet().iterator();
-      while (i.hasNext()) {
-        Map.Entry e = (Map.Entry) i.next();
-        Object value = e.getValue();
-        if (value != null) {
-          this.map.put(e.getKey(), wrap(value));
-        }
-      }
+  public JSONObject(JSONTokener readFrom) throws JSONException {
+        /*
+         * 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();
+    if (object instanceof JSONObject) {
+      this.nameValuePairs = ((JSONObject) object).nameValuePairs;
+    } else {
+      throw JSON.typeMismatch(object, "JSONObject");
     }
   }
 
-
   /**
-   * Construct a JSONObject from an Object using bean getters. It reflects on all of the public
-   * methods of the object. For each of the methods with no parameters and a name starting with
-   * <code>"get"</code> or <code>"is"</code> followed by an uppercase letter, the method is invoked,
-   * and a key and the value returned from the getter method are put into the new JSONObject.
-   *
-   * The key is formed by removing the <code>"get"</code> or <code>"is"</code> prefix. If the second
-   * remaining character is not upper case, then the first character is converted to lower case.
-   *
-   * For example, if an object has a method named <code>"getName"</code>, and if the result of
-   * calling <code>object.getName()</code> is <code>"Larry Fine"</code>, then the JSONObject will
-   * contain <code>"name": "Larry Fine"</code>.
-   *
-   * @param bean An object that has getter methods that should be used to make a JSONObject.
+   * Creates a new {@code JSONObject} with name/value mappings from the JSON
+   * string.
+   * @param json a JSON-encoded string containing an object.
+   * @throws JSONException if the parse fails or doesn't yield a {@code JSONObject}.
    */
-  public JSONObject(Object bean) {
-    this();
-    this.populateMap(bean);
+  public JSONObject(String json) throws JSONException {
+    this(new JSONTokener(json));
   }
 
-
   /**
-   * Construct a JSONObject from an Object, using reflection to find the public members. The
-   * resulting JSONObject's keys will be the strings from the names array, and the values will be
-   * the field values associated with those keys in the object. If a key is not found or not
-   * visible, then it will not be copied into the new JSONObject.
-   * 
-   * @param object An object that has fields that should be used to make a JSONObject.
-   * @param names An array of strings, the names of the fields to be obtained from the object.
+   * 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 JSONException On internal errors. Shouldn't happen.
    */
-  public JSONObject(Object object, String names[]) {
+  public JSONObject(JSONObject copyFrom, String[] names) throws JSONException {
     this();
-    Class c = object.getClass();
-    for (int i = 0; i < names.length; i += 1) {
-      String name = names[i];
-      try {
-        this.putOpt(name, c.getField(name).get(object));
-      } catch (Exception ignore) {
+    for (String name : names) {
+      Object value = copyFrom.opt(name);
+      if (value != null) {
+        nameValuePairs.put(name, value);
       }
     }
   }
 
-
   /**
-   * Construct a JSONObject from a source JSON text string. This is the most commonly used
-   * JSONObject constructor.
-   * 
-   * @param source A string beginning with <code>{</code>&nbsp;<small>(left brace)</small> and
-   *        ending with <code>}</code>&nbsp;<small>(right brace)</small>.
-   * @exception JSONException If there is a syntax error in the source string or a duplicated key.
+   * Creates a json object from a bean
+   * @param bean the bean to create the json object from
+   * @throws JSONException If there is an exception while reading the bean
    */
-  public JSONObject(String source) throws JSONException {
-    this(new JSONTokener(source));
+  public JSONObject(Object bean) throws JSONException {
+    this(propertiesAsMap(bean));
   }
 
+  //This is custom properties mapping specific for GEODE
+  private static Map<String, Object> propertiesAsMap(Object bean) {
+    Map<String, Object> props = new TreeMap();
+    Class klass = bean.getClass();
 
-  /**
-   * Construct a JSONObject from a ResourceBundle.
-   * 
-   * @param baseName The ResourceBundle base name.
-   * @param locale The Locale to load the ResourceBundle for.
-   * @throws JSONException If any JSONExceptions are detected.
-   */
-  public JSONObject(String baseName, Locale locale) throws JSONException {
-    this();
-    ResourceBundle bundle =
-        ResourceBundle.getBundle(baseName, locale, Thread.currentThread().getContextClassLoader());
-
-    // Iterate through the keys in the bundle.
-
-    Enumeration keys = bundle.getKeys();
-    while (keys.hasMoreElements()) {
-      Object key = keys.nextElement();
-      if (key instanceof String) {
-
-        // Go through the path, ensuring that there is a nested JSONObject for each
-        // segment except the last. Add the value using the last segment's name into
-        // the deepest nested JSONObject.
-
-        String[] path = ((String) key).split("\\.");
-        int last = path.length - 1;
-        JSONObject target = this;
-        for (int i = 0; i < last; i += 1) {
-          String segment = path[i];
-          JSONObject nextTarget = target.optJSONObject(segment);
-          if (nextTarget == null) {
-            nextTarget = new JSONObject();
-            target.put(segment, nextTarget);
+    // If klass is a System class then set includeSuperClass to false.
+
+    boolean includeSuperClass = klass.getClassLoader() != null;
+
+    Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods();
+    for (int i = 0; i < methods.length; i += 1) {
+      try {
+        Method method = methods[i];
+        if (Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers())) {
+          String name = method.getName();
+          String key = "";
+          if (name.startsWith("get")) {
+            if ("getClass".equals(name) || "getDeclaringClass".equals(name)) {
+              key = "";
+            } else {
+              key = name.substring(3);
+            }
+          } else if (name.startsWith("is")) {
+            key = name.substring(2);
+          }
+          if (key.length() > 0 && Character.isUpperCase(key.charAt(0))
+              && method.getParameterTypes().length == 0) {
+            if (key.length() == 1) {
+              key = key.toLowerCase();
+            } else if (!Character.isUpperCase(key.charAt(1))) {
+              key = key.substring(0, 1).toLowerCase() + key.substring(1);
+            }
+            Object result = method.invoke(bean, (Object[]) null);
+            if (result != null) {
+              props.put(key, wrap(result));
+            } else if (!method.getReturnType().isArray()) {
+              props.put(key, JSONObject.NULL);
+            }
           }
-          target = nextTarget;
         }
-        target.put(path[last], bundle.getString((String) key));
+      } catch (Exception ignore) {
       }
     }
+    props.put("type-class", klass.getCanonicalName());
+    return props;
   }
 
-
-  /**
-   * Accumulate values under a key. It is similar to the put method except that if there is already
-   * an object stored under the key then a JSONArray is stored under the key to hold all of the
-   * accumulated values. If there is already a JSONArray, then the new value is appended to it. In
-   * contrast, the put method replaces the previous value.
-   *
-   * If only one value is accumulated that is not a JSONArray, then the result will be the same as
-   * using put. But if multiple values are accumulated, then the result will be like append.
-   * 
-   * @param key A key string.
-   * @param value An object to be accumulated under the key.
-   * @return this.
-   * @throws JSONException If the value is an invalid number or if the key is null.
-   */
-  public JSONObject accumulate(String key, Object value) throws JSONException {
-    testValidity(value);
-    Object object = this.opt(key);
-    if (object == null) {
-      this.put(key, value instanceof JSONArray ? new JSONArray().put(value) : value);
-    } else if (object instanceof JSONArray) {
-      ((JSONArray) object).put(value);
-    } else {
-      this.put(key, new JSONArray().put(object).put(value));
+  public static String[] getNames(JSONObject x) {
+    Set<String> names = x.keySet();
+    String[] r = new String[names.size()];
+    int i = 0;
+    for (String name : names) {
+      r[i++] = name;
     }
-    return this;
+    return r;
   }
 
-
   /**
-   * Append values to the array under a key. If the key does not exist in the JSONObject, then the
-   * key is put in the JSONObject with its value being a JSONArray containing the value parameter.
-   * If the key was already associated with a JSONArray, then the value parameter is appended to it.
-   * 
-   * @param key A key string.
-   * @param value An object to be accumulated under the key.
-   * @return this.
-   * @throws JSONException If the key is null or if the current value associated with the key is not
-   *         a JSONArray.
+   * Returns the number of name/value mappings in this object.
+   * @return the length of this.
    */
-  public JSONObject append(String key, Object value) throws JSONException {
-    testValidity(value);
-    Object object = this.opt(key);
-    if (object == null) {
-      this.put(key, new JSONArray().put(value));
-    } else if (object instanceof JSONArray) {
-      this.put(key, ((JSONArray) object).put(value));
-    } else {
-      throw new JSONException("JSONObject[" + key + "] is not a JSONArray.");
-    }
-    return this;
+  public int length() {
+    return nameValuePairs.size();
   }
 
-
   /**
-   * Produce a string from a double. The string "null" will be returned if the number is not finite.
-   * 
-   * @param d A double.
-   * @return A String.
+   * Maps {@code name} to {@code value}, clobbering any existing name/value
+   * mapping with the same name.
+   * @param name The name of the value to insert.
+   * @param value The value to insert.
+   * @return this object.
+   * @throws JSONException Should not be possible.
    */
-  public static String doubleToString(double d) {
-    if (Double.isInfinite(d) || Double.isNaN(d)) {
-      return "null";
-    }
-
-    // Shave off trailing zeros and decimal point, if possible.
-
-    String string = Double.toString(d);
-    if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && string.indexOf('E') < 0) {
-      while (string.endsWith("0")) {
-        string = string.substring(0, string.length() - 1);
-      }
-      if (string.endsWith(".")) {
-        string = string.substring(0, string.length() - 1);
-      }
-    }
-    return string;
+  public JSONObject put(String name, boolean value) throws JSONException {
+    nameValuePairs.put(checkName(name), value);
+    return this;
   }
 
-
   /**
-   * Get the value object associated with a key.
-   *
-   * @param key A key string.
-   * @return The object associated with the key.
-   * @throws JSONException if the key is not found.
+   * Maps {@code name} to {@code value}, clobbering any existing name/value
+   * mapping with the same name.
+   * @param name The name for the new value.
+   * @param value a finite value. May not be {@link Double#isNaN() NaNs} or {@link
+   * Double#isInfinite() infinities}.
+   * @return this object.
+   * @throws JSONException if value is NaN or infinite.
    */
-  public Object get(String key) throws JSONException {
-    if (key == null) {
-      throw new JSONException("Null key.");
-    }
-    Object object = this.opt(key);
-    if (object == null) {
-      throw new JSONException("JSONObject[" + quote(key) + "] not found.");
-    }
-    return object;
+  public JSONObject put(String name, double value) throws JSONException {
+    nameValuePairs.put(checkName(name), JSON.checkDouble(value));
+    return this;
   }
 
-
   /**
-   * Get the boolean value associated with a key.
-   *
-   * @param key A key string.
-   * @return The truth.
-   * @throws JSONException if the value is not a Boolean or the String "true" or "false".
+   * Maps {@code name} to {@code value}, clobbering any existing name/value
+   * mapping with the same name.
+   * @param name The name for the new value.
+   * @param value The new value.
+   * @return this object.
+   * @throws JSONException Should not be possible.
    */
-  public boolean getBoolean(String key) throws JSONException {
-    Object object = this.get(key);
-    if (object.equals(Boolean.FALSE)
-        || (object instanceof String && ((String) object).equalsIgnoreCase("false"))) {
-      return false;
-    } else if (object.equals(Boolean.TRUE)
-        || (object instanceof String && ((String) object).equalsIgnoreCase("true"))) {
-      return true;
-    }
-    throw new JSONException("JSONObject[" + quote(key) + "] is not a Boolean.");
+  public JSONObject put(String name, int value) throws JSONException {
+    nameValuePairs.put(checkName(name), value);
+    return this;
   }
 
-
   /**
-   * Get the double value associated with a key.
-   * 
-   * @param key A key string.
-   * @return The numeric value.
-   * @throws JSONException if the key is not found or if the value is not a Number object and cannot
-   *         be converted to a number.
+   * Maps {@code name} to {@code value}, clobbering any existing name/value
+   * mapping with the same name.
+   * @param name The name of the new value.
+   * @param value The new value to insert.
+   * @return this object.
+   * @throws JSONException Should not be possible.
    */
-  public double getDouble(String key) throws JSONException {
-    Object object = this.get(key);
-    try {
-      return object instanceof Number ? ((Number) object).doubleValue()
-          : Double.parseDouble((String) object);
-    } catch (Exception e) {
-      throw new JSONException("JSONObject[" + quote(key) + "] is not a number.");
-    }
+  public JSONObject put(String name, long value) throws JSONException {
+    nameValuePairs.put(checkName(name), value);
+    return this;
   }
 
-
   /**
-   * Get the int value associated with a key.
-   *
-   * @param key A key string.
-   * @return The integer value.
-   * @throws JSONException if the key is not found or if the value cannot be converted to an
-   *         integer.
+   * 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 JSONException if the value is an invalid double (infinite or NaN).
    */
-  public int getInt(String key) throws JSONException {
-    Object object = this.get(key);
-    try {
-      return object instanceof Number ? ((Number) object).intValue()
-          : Integer.parseInt((String) object);
-    } catch (Exception e) {
-      throw new JSONException("JSONObject[" + quote(key) + "] is not an int.");
+  public JSONObject put(String name, Object value) throws JSONException {
+    if (value == null) {
+      nameValuePairs.remove(name);
+      return this;
     }
-  }
-
-
-  /**
-   * Get the JSONArray value associated with a key.
-   *
-   * @param key A key string.
-   * @return A JSONArray which is the value.
-   * @throws JSONException if the key is not found or if the value is not a JSONArray.
-   */
-  public JSONArray getJSONArray(String key) throws JSONException {
-    Object object = this.get(key);
-    if (object instanceof JSONArray) {
-      return (JSONArray) object;
+    if (value instanceof Number) {
+      // deviate from the original by checking all Numbers, not just floats & doubles
+      JSON.checkDouble(((Number) value).doubleValue());
     }
-    throw new JSONException("JSONObject[" + quote(key) + "] is not a JSONArray.");
+    nameValuePairs.put(checkName(name), value);
+    return this;
   }
 
-
   /**
-   * Get the JSONObject value associated with a key.
+   * Put a key/value pair in the JSONObject, where the value will be a JSONArray which is produced
+   * from a Collection.
    *
    * @param key A key string.
-   * @return A JSONObject which is the value.
-   * @throws JSONException if the key is not found or if the value is not a JSONObject.
+   * @param value A Collection value.
+   * @return this.
+   * @throws JSONException
    */
-  public JSONObject getJSONObject(String key) throws JSONException {
-    Object object = this.get(key);
-    if (object instanceof JSONObject) {
-      return (JSONObject) object;
-    }
-    throw new JSONException("JSONObject[" + quote(key) + "] is not a JSONObject.");
+  public JSONObject put(String key, Collection value) throws JSONException {
+    this.put(key, new JSONArray(value));
+    return this;
   }
 
-
   /**
-   * Get the long value associated with a key.
-   *
-   * @param key A key string.
-   * @return The long value.
-   * @throws JSONException if the key is not found or if the value cannot be converted to a long.
+   * Equivalent to {@code put(name, value)} when both parameters are non-null;
+   * does nothing otherwise.
+   * @param name The name of the value to insert.
+   * @param value The value to insert.
+   * @return this object.
+   * @throws JSONException if the value is an invalid double (infinite or NaN).
    */
-  public long getLong(String key) throws JSONException {
-    Object object = this.get(key);
-    try {
-      return object instanceof Number ? ((Number) object).longValue()
-          : Long.parseLong((String) object);
-    } catch (Exception e) {
-      throw new JSONException("JSONObject[" + quote(key) + "] is not a long.");
+  public JSONObject putOpt(String name, Object value) throws JSONException {
+    if (name == null || value == null) {
+      return this;
     }
+    return put(name, value);
   }
 
-
   /**
-   * Get an array of field names from a JSONObject.
+   * 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.
    *
-   * @return An array of field names, or null if there are no names.
+   * 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 JSONException If the object being added is an invalid number.
    */
-  public static String[] getNames(JSONObject jo) {
-    int length = jo.length();
-    if (length == 0) {
-      return null;
-    }
-    Iterator iterator = jo.keys();
-    String[] names = new String[length];
-    int i = 0;
-    while (iterator.hasNext()) {
-      names[i] = (String) iterator.next();
-      i += 1;
+  // TODO: Change {@code append) to {@link #append} when append is
+  // unhidden.
+  public JSONObject accumulate(String name, Object value) throws JSONException {
+    Object current = nameValuePairs.get(checkName(name));
+    if (current == null) {
+      return put(name, value);
     }
-    return names;
-  }
-
 
-  /**
-   * Get an array of field names from an Object.
-   *
-   * @return An array of field names, or null if there are no names.
-   */
-  public static String[] getNames(Object object) {
-    if (object == null) {
-      return null;
-    }
-    Class klass = object.getClass();
-    Field[] fields = klass.getFields();
-    int length = fields.length;
-    if (length == 0) {
-      return null;
-    }
-    String[] names = new String[length];
-    for (int i = 0; i < length; i += 1) {
-      names[i] = fields[i].getName();
+    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 names;
+    return this;
   }
 
-
   /**
-   * Get the string associated with a key.
-   *
-   * @param key A key string.
-   * @return A string which is the value.
-   * @throws JSONException if there is no string value for the key.
+   * 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 JSONException}
+   * 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 JSONException if {@code name} is {@code null} or if the mapping for {@code name} is
+   * non-null and is not a {@link JSONArray}.
    */
-  public String getString(String key) throws JSONException {
-    Object object = this.get(key);
-    if (object instanceof String) {
-      return (String) object;
+  public JSONObject append(String name, Object value) throws JSONException {
+    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 JSONException("Key " + name + " is not a JSONArray");
     }
-    throw new JSONException("JSONObject[" + quote(key) + "] not a string.");
-  }
 
+    array.checkedPut(value);
 
-  /**
-   * Determine if the JSONObject contains a specific key.
-   * 
-   * @param key A key string.
-   * @return true if the key exists in the JSONObject.
-   */
-  public boolean has(String key) {
-    return this.map.containsKey(key);
+    return this;
   }
 
-
-  /**
-   * Increment a property of a JSONObject. If there is no such property, create one with a value of
-   * 1. If there is such a property, and if it is an Integer, Long, Double, or Float, then add one
-   * to it.
-   * 
-   * @param key A key string.
-   * @return this.
-   * @throws JSONException If there is already a property with this name that is not an Integer,
-   *         Long, Double, or Float.
-   */
-  public JSONObject increment(String key) throws JSONException {
-    Object value = this.opt(key);
-    if (value == null) {
-      this.put(key, 1);
-    } else if (value instanceof Integer) {
-      this.put(key, ((Integer) value).intValue() + 1);
-    } else if (value instanceof Long) {
-      this.put(key, ((Long) value).longValue() + 1);
-    } else if (value instanceof Double) {
-      this.put(key, ((Double) value).doubleValue() + 1);
-    } else if (value instanceof Float) {
-      this.put(key, ((Float) value).floatValue() + 1);
-    } else {
-      throw new JSONException("Unable to increment [" + quote(key) + "].");
+  String checkName(String name) throws JSONException {
+    if (name == null) {
+      throw new JSONException("Names must be non-null");
     }
-    return this;
+    return name;
   }
 
-
   /**
-   * Determine if the value associated with the key is null or if there is no value.
-   * 
-   * @param key A key string.
-   * @return true if there is no value associated with the key or if the value is the
-   *         JSONObject.NULL object.
+   * 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.
    */
-  public boolean isNull(String key) {
-    return JSONObject.NULL.equals(this.opt(key));
+  public Object remove(String name) {
+    return nameValuePairs.remove(name);
   }
 
-
   /**
-   * Get an enumeration of the keys of the JSONObject.
-   *
-   * @return An iterator of the keys.
+   * 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 Iterator keys() {
-    return this.map.keySet().iterator();
+  public boolean isNull(String name) {
+    Object value = nameValuePairs.get(name);
+    return value == null || value == NULL;
   }
 
-
   /**
-   * Get the number of keys stored in the JSONObject.
-   *
-   * @return The number of keys in the JSONObject.
+   * Returns true if this object has a mapping for {@code name}. The mapping
+   * may be {@link #NULL}.
+   * @param name The name of the value to check on.
+   * @return true if this object has a field named {@code name}
    */
-  public int length() {
-    return this.map.size();
+  public boolean has(String name) {
+    return nameValuePairs.containsKey(name);
   }
 
-
   /**
-   * Produce a JSONArray containing the names of the elements of this JSONObject.
-   * 
-   * @return A JSONArray containing the key strings, or null if the JSONObject is empty.
+   * 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 JSONException if no such mapping exists.
    */
-  public JSONArray names() {
-    JSONArray ja = new JSONArray();
-    Iterator keys = this.keys();
-    while (keys.hasNext()) {
-      ja.put(keys.next());
+  public Object get(String name) throws JSONException {
+    Object result = nameValuePairs.get(name);
+    if (result == null) {
+      throw new JSONException("No value for " + name);
     }
-    return ja.length() == 0 ? null : ja;
+    return result;
   }
 
   /**
-   * Produce a string from a Number.
-   * 
-   * @param number A Number
-   * @return A String.
-   * @throws JSONException If n is a non-finite number.
+   * 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 static String numberToString(Number number) throws JSONException {
-    if (number == null) {
-      throw new JSONException("Null pointer");
-    }
-    testValidity(number);
-
-    // Shave off trailing zeros and decimal point, if possible.
-
-    String string = number.toString();
-    if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && string.indexOf('E') < 0) {
-      while (string.endsWith("0")) {
-        string = string.substring(0, string.length() - 1);
-      }
-      if (string.endsWith(".")) {
-        string = string.substring(0, string.length() - 1);
-      }
-    }
-    return string;
+  public Object opt(String name) {
+    return nameValuePairs.get(name);
   }
 
-
   /**
-   * Get an optional value associated with a key.
-   * 
-   * @param key A key string.
-   * @return An object which is the value, or null if there is no value.
+   * 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 JSONException if the mapping doesn't exist or cannot be coerced to a boolean.
    */
-  public Object opt(String key) {
-    return key == null ? null : this.map.get(key);
+  public boolean getBoolean(String name) throws JSONException {
+    Object object = get(name);
+    Boolean result = JSON.toBoolean(object);
+    if (result == null) {
+      throw JSON.typeMismatch(name, object, "boolean");
+    }
+    return result;
   }
 
-
   /**
-   * Get an optional boolean associated with a key. It returns false if there is no such key, or if
-   * the value is not Boolean.TRUE or the String "true".
-   *
-   * @param key A key string.
-   * @return The truth.
+   * Returns the value mapped by {@code name} if it exists and is a boolean or
+   * can be coerced to a boolean, or false otherwise.
+   * @param name The name of the field we want.
+   * @return The selected value if it exists.
    */
-  public boolean optBoolean(String key) {
-    return this.optBoolean(key, false);
+  public boolean optBoolean(String name) {
+    return optBoolean(name, false);
   }
 
-
   /**
-   * Get an optional boolean associated with a key. It returns the defaultValue if there is no such
-   * key, or if it is not a Boolean or the String "true" or "false" (case insensitive).
-   *
-   * @param key A key string.
-   * @param defaultValue The default.
-   * @return The truth.
+   * Returns the value mapped by {@code name} if it exists and is a boolean or
+   * can be coerced to a boolean, or {@code fallback} otherwise.
+   * @param name The name of the field we want.
+   * @param fallback The value to return if the field isn't there.
+   * @return The selected value or the fallback.
    */
-  public boolean optBoolean(String key, boolean defaultValue) {
-    try {
-      return this.getBoolean(key);
-    } catch (Exception e) {
-      return defaultValue;
-    }
+  public boolean optBoolean(String name, boolean fallback) {
+    Object object = opt(name);
+    Boolean result = JSON.toBoolean(object);
+    return result != null ? result : fallback;
   }
 
-
   /**
-   * Get an optional double associated with a key, or NaN if there is no such key or if its value is
-   * not a number. If the value is a string, an attempt will be made to evaluate it as a number.
-   *
-   * @param key A string which is the key.
-   * @return An object which is the value.
+   * 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 JSONException if the mapping doesn't exist or cannot be coerced to a double.
    */
-  public double optDouble(String key) {
-    return this.optDouble(key, Double.NaN);
+  public double getDouble(String name) throws JSONException {
+    Object object = get(name);
+    Double result = JSON.toDouble(object);
+    if (result == null) {
+      throw JSON.typeMismatch(name, object, "double");
+    }
+    return result;
   }
 
-
   /**
-   * Get an optional double associated with a key, or the defaultValue if there is no such key or if
-   * its value is not a number. If the value is a string, an attempt will be made to evaluate it as
-   * a number.
-   *
-   * @param key A key string.
-   * @param defaultValue The default.
-   * @return An object which is the value.
+   * Returns the value mapped by {@code name} if it exists and is a double or
+   * can be coerced to a double, or {@code NaN} otherwise.
+   * @param name The name of the field we want.
+   * @return The selected value if it exists.
    */
-  public double optDouble(String key, double defaultValue) {
-    try {
-      return this.getDouble(key);
-    } catch (Exception e) {
-      return defaultValue;
-    }
+  public double optDouble(String name) {
+    return optDouble(name, Double.NaN);
   }
 
-
   /**
-   * Get an optional int value associated with a key, or zero if there is no such key or if the
-   * value is not a number. If the value is a string, an attempt will be made to evaluate it as a
-   * number.
-   *
-   * @param key A key string.
-   * @return An object which is the value.
+   * Returns the value mapped by {@code name} if it exists and is a double or
+   * can be coerced to a double, or {@code fallback} otherwise.
+   * @param name The name of the field we want.
+   * @param fallback The value to return if the field isn't there.
+   * @return The selected value or the fallback.
    */
-  public int optInt(String key) {
-    return this.optInt(key, 0);
+  public double optDouble(String name, double fallback) {
+    Object object = opt(name);
+    Double result = JSON.toDouble(object);
+    return result != null ? result : fallback;
   }
 
-
   /**
-   * Get an optional int value associated with a key, or the default if there is no such key or if
-   * the value is not a number. If the value is a string, an attempt will be made to evaluate it as
-   * a number.
-   *
-   * @param key A key string.
-   * @param defaultValue The default.
-   * @return An object which is the value.
+   * 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 JSONException if the mapping doesn't exist or cannot be coerced to an int.
    */
-  public int optInt(String key, int defaultValue) {
-    try {
-      return this.getInt(key);
-    } catch (Exception e) {
-      return defaultValue;
+  public int getInt(String name) throws JSONException {
+    Object object = get(name);
+    Integer result = JSON.toInteger(object);
+    if (result == null) {
+      throw JSON.typeMismatch(name, object, "int");
     }
+    return result;
   }
 
-
   /**
-   * Get an optional JSONArray associated with a key. It returns null if there is no such key, or if
-   * its value is not a JSONArray.
-   *
-   * @param key A key string.
-   * @return A JSONArray which is the value.
+   * Returns the value mapped by {@code name} if it exists and is an int or
+   * can be coerced to an int, or 0 otherwise.
+   * @param name The name of the field we want.
+   * @return The selected value if it exists.
    */
-  public JSONArray optJSONArray(String key) {
-    Object o = this.opt(key);
-    return o instanceof JSONArray ? (JSONArray) o : null;
+  public int optInt(String name) {
+    return optInt(name, 0);
   }
 
-
   /**
-   * Get an optional JSONObject associated with a key. It returns null if there is no such key, or
-   * if its value is not a JSONObject.
-   *
-   * @param key A key string.
-   * @return A JSONObject which is the value.
+   * Returns the value mapped by {@code name} if it exists and is an int or
+   * can be coerced to an int, or {@code fallback} otherwise.
+   * @param name The name of the field we want.
+   * @param fallback The value to return if the field isn't there.
+   * @return The selected value or the fallback.
    */
-  public JSONObject optJSONObject(String key) {
-    Object object = this.opt(key);
-    return object instanceof JSONObject ? (JSONObject) object : null;
+  public int optInt(String name, int fallback) {
+    Object object = opt(name);
+    Integer result = JSON.toInteger(object);
+    return result != null ? result : fallback;
   }
 
-
   /**
-   * Get an optional long value associated with a key, or zero if there is no such key or if the
-   * value is not a number. If the value is a string, an attempt will be made to evaluate it as a
-   * number.
+   * 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,
    *
-   * @param key A key string.
-   * @return An object which is the value.
+   * 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 JSONException if the mapping doesn't exist or cannot be coerced to a long.
    */
-  public long optLong(String key) {
-    return this.optLong(key, 0);
+  public long getLong(String name) throws JSONException {
+    Object object = get(name);
+    Long result = JSON.toLong(object);
+    if (result == null) {
+      throw JSON.typeMismatch(name, object, "long");
+    }
+    return result;
   }
 
-
   /**
-   * Get an optional long value associated with a key, or the default if there is no such key or if
-   * the value is not a number. If the value is a string, an attempt will be made to evaluate it as
-   * a number.
-   *
-   * @param key A key string.
-   * @param defaultValue The default.
-   * @return An object which is the value.
+   * Returns the value mapped by {@code name} if it exists and is a long or
+   * can be coerced to a long, or 0 otherwise. Note that JSON represents numbers as doubles,
+   * so this is <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
+   * @param name The name of the field we want.
+   * @return The selected value.
    */
-  public long optLong(String key, long defaultValue) {
-    try {
-      return this.getLong(key);
-    } catch (Exception e) {
-      return defaultValue;
-    }
+  public long optLong(String name) {
+    return optLong(name, 0L);
   }
 
-
   /**
-   * Get an optional string associated with a key. It returns an empty string if there is no such
-   * key. If the value is not a string and is not null, then it is converted to a string.
-   *
-   * @param key A key string.
-   * @return A string which is the value.
+   * Returns the value mapped by {@code name} if it exists and is a long or
+   * can be coerced to a long, or {@code fallback} otherwise. Note that JSON represents
+   * numbers as doubles, so this is <a href="#lossy">lossy</a>; use strings to transfer
+   * numbers via JSON.
+   * @param name The name of the field we want.
+   * @param fallback The value to return if the field isn't there.
+   * @return The selected value or the fallback.
    */
-  public String optString(String key) {
-    return this.optString(key, "");
+  public long optLong(String name, long fallback) {
+    Object object = opt(name);
+    Long result = JSON.toLong(object);
+    return result != null ? result : fallback;
   }
 
-
   /**
-   * Get an optional string associated with a key. It returns the defaultValue if there is no such
-   * key.
-   *
-   * @param key A key string.
-   * @param defaultValue The default.
-   * @return A string which is the value.
+   * 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 JSONException if no such mapping exists.
    */
-  public String optString(String key, String defaultValue) {
-    Object object = this.opt(key);
-    return NULL.equals(object) ? defaultValue : object.toString();
-  }
-
-
-  private void populateMap(Object bean) {
-    Class klass = bean.getClass();
-
-    // If klass is a System class then set includeSuperClass to false.
-
-    boolean includeSuperClass = klass.getClassLoader() != null;
-
-    Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods();
-    for (int i = 0; i < methods.length; i += 1) {
-      try {
-        Method method = methods[i];
-        if (Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers())) {
-          String name = method.getName();
-          String key = "";
-          if (name.startsWith("get")) {
-            if ("getClass".equals(name) || "getDeclaringClass".equals(name)) {
-              key = "";
-            } else {
-              key = name.substring(3);
-            }
-          } else if (name.startsWith("is")) {
-            key = name.substring(2);
-          }
-          if (key.length() > 0 && Character.isUpperCase(key.charAt(0))
-              && method.getParameterTypes().length == 0) {
-            if (key.length() == 1) {
-              key = key.toLowerCase();
-            } else if (!Character.isUpperCase(key.charAt(1))) {
-              key = key.substring(0, 1).toLowerCase() + key.substring(1);
-            }
-            Object result = method.invoke(bean, (Object[]) null);
-            if (result != null) {
-              this.map.put(key, wrap(result));
-            } else if (!method.getReturnType().isArray()) {
-              this.map.put(key, JSONObject.NULL);
-            }
-          }
-        }
-      } catch (Exception ignore) {
-      }
+  public String getString(String name) throws JSONException {
+    Object object = get(name);
+    String result = JSON.toString(object);
+    if (result == null) {
+      throw JSON.typeMismatch(name, object, "String");
     }
-    this.map.put("type-class", klass.getCanonicalName());
+    return result;
   }
 
-
   /**
-   * Put a key/boolean pair in the JSONObject.
-   *
-   * @param key A key string.
-   * @param value A boolean which is the value.
-   * @return this.
-   * @throws JSONException If the key is null.
+   * Returns the value mapped by {@code name} if it exists, coercing it if
+   * necessary, or the empty string if no such mapping exists.
+   * @param name The name of the field we want.
+   * @return The value of the field.
    */
-  public JSONObject put(String key, boolean value) throws JSONException {
-    this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
-    return this;
+  public String optString(String name) {
+    return optString(name, "");
   }
 
-
   /**
-   * Put a key/value pair in the JSONObject, where the value will be a JSONArray which is produced
-   * from a Collection.
-   * 
-   * @param key A key string.
-   * @param value A Collection value.
-   * @return this.
-   * @throws JSONException
+   * Returns the value mapped by {@code name} if it exists, coercing it if
+   * necessary, or {@code fallback} if no such mapping exists.
+   * @param name The name of the field that we want.
+   * @param fallback The value to return if the field doesn't exist.
+   * @return The value of the field or fallback.
    */
-  public JSONObject put(String key, Collection value) throws JSONException {
-    this.put(key, new JSONArray(value));
-    return this;
+  public String optString(String name, String fallback) {
+    Object object = opt(name);
+    String result = JSON.toString(object);
+    return result != null ? result : fallback;
   }
 
-
   /**
-   * Put a key/double pair in the JSONObject.
-   *
-   * @param key A key string.
-   * @param value A double which is the value.
-   * @return this.
-   * @throws JSONException If the key is null or if the number is invalid.
+   * 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 JSONException if the mapping doesn't exist or is not a {@code JSONArray}.
    */
-  public JSONObject put(String key, double value) throws JSONException {
-    this.put(key, new Double(value));
-    return this;
+  public JSONArray getJSONArray(String name) throws JSONException {
+    Object object = get(name);
+    if (object instanceof JSONArray) {
+      return (JSONArray) object;
+    } else {
+      throw JSON.typeMismatch(name, object, "JSONArray");
+    }
   }
 
-
   /**
-   * Put a key/int pair in the JSONObject.
-   *
-   * @param key A key string.
-   * @param value An int which is the value.
-   * @return this.
-   * @throws JSONException If the key is null.
+   * Returns the value mapped by {@code name} if it exists and is a {@code
+   * JSONArray}, or null otherwise.
+   * @param name The name of the field we want.
+   * @return The value of the specified field (assuming it is a JSNOArray
    */
-  public JSONObject put(String key, int value) throws JSONException {
-    this.put(key, new Integer(value));
-    return this;
+  public JSONArray optJSONArray(String name) {
+    Object object = opt(name);
+    return object instanceof JSONArray ? (JSONArray) object : null;
   }
 
-
   /**
-   * Put a key/long pair in the JSONObject.
-   *
-   * @param key A key string.
-   * @param value A long which is the value.
-   * @return this.
-   * @throws JSONException If the key is null.
+   * 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 JSONException if the mapping doesn't exist or is not a {@code JSONObject}.
    */
-  public JSONObject put(String key, long value) throws JSONException {
-    this.put(key, new Long(value));
-    return this;
+  public JSONObject getJSONObject(String name) throws JSONException {
+    Object object = get(name);
+    if (object instanceof JSONObject) {
+      return (JSONObject) object;
+    } else {
+      throw JSON.typeMismatch(name, object, "JSONObject");
+    }
   }
 
-
   /**
-   * Put a key/value pair in the JSONObject, where the value will be a JSONObject which is produced
-   * from a Map.
-   * 
-   * @param key A key string.
-   * @param value A Map value.
-   * @return this.
-   * @throws JSONException
+   * Returns the value mapped by {@code name} if it exists and is a {@code
+   * JSONObject}, or null otherwise.
+   * @param name The name of the value we want.
+   * @return The specified value.
    */
-  public JSONObject put(String key, Map value) throws JSONException {
-    this.put(key, new JSONObject(value));
-    return this;
+  public JSONObject optJSONObject(String name) {
+    Object object = opt(name);
+    return object instanceof JSONObject ? (JSONObject) object : null;
   }
 
-
   /**
-   * Put a key/value pair in the JSONObject. If the value is null, then the key will be removed from
-   * the JSONObject if it is present.
-   * 
-   * @param key A key string.
-   * @param value An object which is the value. It should be of one of these types: Boolean, Double,
-   *        Integer, JSONArray, JSONObject, Long, String, or the JSONObject.NULL object.
-   * @return this.
-   * @throws JSONException If the value is non-finite number or if the key is null.
+   * Returns an array with the values corresponding to {@code names}. The
+   * array contains null for names that aren't mapped. This method returns
+   * null if {@code names} is either null or empty.
+   * @param names The names of the fields that we want the values for.
+   * @return The selected values.
+   * @throws JSONException On internal errors. Shouldn't happen.
    */
-  public JSONObject put(String key, Object value) throws JSONException {
-    if (key == null) {
-      throw new JSONException("Null key.");
+  public JSONArray toJSONArray(JSONArray names) throws JSONException {
+    JSONArray result = new JSONArray();
+    if (names == null) {
+      return null;
     }
-    if (value != null) {
-      testValidity(value);
-      this.map.put(key, value);
-    } else {
-      this.remove(key);
+    int length = names.length();
+    if (length == 0) {
+      return null;
     }
-    return this;
+    for (int i = 0; i < length; i++) {
+      String name = JSON.toString(names.opt(i));
+      result.put(opt(name));
+    }
+    return result;
   }
 
-
   /**
-   * Put a key/value pair in the JSONObject, but only if the key and the value are both non-null,
-   * and only if there is not already a member with that name.
-   * 
-   * @param key
-   * @param value
-   * @return his.
-   * @throws JSONException if the key is a duplicate
+   * Returns an iterator of the {@code String} names in this object. The
+   * returned iterator supports {@link Iterator#remove() remove}, which will
+   * remove the corresponding mapping from this object. If this object is
+   * modified after the iterator is returned, the iterator's behavior is
+   * undefined. The order of the keys is undefined.
+   * @return an iterator over the keys.
    */
-  public JSONObject putOnce(String key, Object value) throws JSONException {
-    if (key != null && value != null) {
-      if (this.opt(key) != null) {
-        throw new JSONException("Duplicate key \"" + key + "\"");
-      }
-      this.put(key, value);
-    }
-    return this;
+  public Iterator<String> keys() {
+    return nameValuePairs.keySet().iterator();
   }
 
-
   /**
-   * Put a key/value pair in the JSONObject, but only if the key and the value are both non-null.
-   * 
-   * @param key A key string.
-   * @param value An object which is the value. It should be of one of these types: Boolean, Double,
-   *        Integer, JSONArray, JSONObject, Long, String, or the JSONObject.NULL object.
-   * @return this.
-   * @throws JSONException If the value is a non-finite number.
+   * 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 JSONObject putOpt(String key, Object value) throws JSONException {
-    if (key != null && value != null) {
-      this.put(key, value);
-    }
-    return this;
+  public Set<String> keySet() {
+    return nameValuePairs.keySet();
   }
 
-
   /**
-   * Produce a string in double quotes with backslash sequences in all the right places. A backslash
-   * will be inserted within </, producing <\/, allowing JSON text to be delivered in HTML. In JSON
-   * text, a string cannot contain a control character or an unescaped quote or backslash.
-   * 
-   * @param string A String
-   * @return A String correctly formatted for insertion in a JSON text.
+   * Returns an array containing the string names in this object. This method
+   * returns null if this object contains no mappings.
+   * @return the names.
    */
-  public static String quote(String string) {
-    StringWriter sw = new StringWriter();
-    synchronized (sw.getBuffer()) {
-      try {
-        return quote(string, sw).toString();
-      } catch (IOException ignored) {
-        // will never happen - we are writing to a string writer
-        return "";
-      }
-    }
-  }
-
-  public static Writer quote(String string, Writer w) throws IOException {
-    if (string == null || string.length() == 0) {
-      w.write("\"\"");
-      return w;
-    }
-
-    char b;
-    char c = 0;
-    String hhhh;
-    int i;
-    int len = string.length();
-
-    w.write('"');
-    for (i = 0; i < len; i += 1) {
-      b = c;
-      c = string.charAt(i);
-      switch (c) {
-        case '\\':
-        case '"':
-          w.write('\\');
-          w.write(c);
-          break;
-        case '/':
-          if (b == '<') {
-            w.write('\\');
-          }
-          w.write(c);
-          break;
-        case '\b':
-          w.write("\\b");
-          break;
-        case '\t':
-          w.write("\\t");
-          break;
-        case '\n':
-          w.write("\\n");
-          break;
-        case '\f':
-          w.write("\\f");
-          break;
-        case '\r':
-          w.write("\\r");
-          break;
-        default:
-          if (c < ' ' || (c >= '\u0080' && c < '\u00a0') || (c >= '\u2000' && c < '\u2100')) {
-            hhhh = "000" + Integer.toHexString(c);
-            w.write("\\u" + hhhh.substring(hhhh.length() - 4));
-          } else {
-            w.write(c);
-          }
-      }
-    }
-    w.write('"');
-    return w;
+  public JSONArray names() {
+    return nameValuePairs.isEmpty()
+        ? null
+        : new JSONArray(new ArrayList<String>(nameValuePairs.keySet()));
   }
 
   /**
-   * Remove a name and its value, if present.
-   * 
-   * @param key The name to be removed.
-   * @return The value that was associated with the name, or null if there was no value.
+   * Encodes this object as a compact JSON string, such as:
+   * <pre>{"query":"Pizza","locations":[94043,90210]}</pre>
    */
-  public Object remove(String key) {
-    return this.map.remove(key);
+  @Override
+  public String toString() {
+    try {
+      JSONStringer stringer = new JSONStringer();
+      writeTo(stringer);
+      return stringer.toString();
+    } catch (JSONException e) {
+      return null;
+    }
   }
 
   /**
-   * Try to convert a string into a number, boolean, or null. If the string can't be converted,
-   * return the string.
-   * 
-   * @param string A String.
-   * @return A simple JSON value.
+   * Encodes this object as a human readable JSON string for debugging, such
+   * as:
+   * <pre>
+   * {
+   *     "query": "Pizza",
+   *     "locations": [
+   *         94043,
+   *         90210
+   *     ]
+   * }</pre>
+   * @param indentSpaces the number of spaces to indent for each level of nesting.
+   * @return The string containing the pretty form of this.
+   * @throws JSONException On internal errors. Shouldn't happen.
    */
-  public static Object stringToValue(String string) {
-    Double d;
-    if (string.equals("")) {
-      return string;
-    }
-    if (string.equalsIgnoreCase("true")) {
-      return Boolean.TRUE;
-    }
-    if (string.equalsIgnoreCase("false")) {
-      return Boolean.FALSE;
-    }
-    if (string.equalsIgnoreCase("null")) {
-      return JSONObject.NULL;
-    }
-
-    /*
-     * If it might be a number, try converting it. If a number cannot be produced, then the value
-     * will just be a string. Note that the plus and implied string conventions are non-standard. A
-     * JSON parser may accept non-JSON forms as long as it accepts all correct JSON forms.
-     */
+  public String toString(int indentSpaces) throws JSONException {
+    JSONStringer stringer = new JSONStringer(indentSpaces);
+    writeTo(stringer);
+    return stringer.toString();
+  }
 
-    char b = string.charAt(0);
-    if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') {
-      try {
-        if (string.indexOf('.') > -1 || string.indexOf('e') > -1 || string.indexOf('E') > -1) {
-          d = Double.valueOf(string);
-          if (!d.isInfinite() && !d.isNaN()) {
-            return d;
-          }
-        } else {
-          Long myLong = new Long(string);
-          if (myLong.longValue() == myLong.intValue()) {
-            return new Integer(myLong.intValue());
-          } else {
-            return myLong;
-          }
-        }
-      } catch (Exception ignore) {
-      }
+  void writeTo(JSONStringer stringer) throws JSONException {
+    stringer.object();
+    for (Map.Entry<String, Object> entry : nameValuePairs.entrySet()) {
+      stringer.key(entry.getKey()).value(entry.getValue());
     }
-    return string;
+    stringer.endObject();
   }
 
-
   /**
-   * Throw an exception if the object is a NaN or infinite number.
-   * 
-   * @param o The object to test.
-   * @throws JSONException If o is a non-finite number.
+   * 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 JSONException On internal errors. Shouldn't happen.
    */
-  public static void testValidity(Object o) throws JSONException {
-    if (o != null) {
-      if (o instanceof Double) {
-        if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
-          throw new JSONException("JSON does not allow non-finite numbers.");
-        }
-      } else if (o instanceof Float) {
-        if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
-          throw new JSONException("JSON does not allow non-finite numbers.");
-        }
-      }
+  public static String numberToString(Number number) throws JSONException {
+    if (number == null) {
+      throw new JSONException("Number must be non-null");
     }
-  }
 
+    double doubleValue = number.doubleValue();
+    JSON.checkDouble(doubleValue);
 
-  /**
-   * Produce a JSONArray containing the values of the members of this JSONObject.
-   * 
-   * @param names A JSONArray containing a list of key strings. This determines the sequence of the
-   *        values in the result.
-   * @return A JSONArray of values.
-   * @throws JSONException If any of the values are non-finite numbers.
-   */
-  public JSONArray toJSONArray(JSONArray names) throws JSONException {
-    if (names == null || names.length() == 0) {
-      return null;
+    // the original returns "-0" instead of "-0.0" for negative zero
+    if (number.equals(NEGATIVE_ZERO)) {
+      return "-0";
     }
-    JSONArray ja = new JSONArray();
-    for (int i = 0; i < names.length(); i += 1) {
-      ja.put(this.opt(names.getString(i)));
-    }
-    return ja;
-  }
 
-  /**
-   * Make a JSON text of this JSONObject. For compactness, no whitespace is added. If this would not
-   * result in a syntactically correct JSON text, then null will be returned instead.
-   * <p>
-   * Warning: This method assumes that the data structure is acyclical.
-   *
-   * @return a printable, displayable, portable, transmittable representation of the object,
-   *         beginning with <code>{</code>&nbsp;<small>(left brace)</small> and ending with
-   *         <code>}</code>&nbsp;<small>(right brace)</small>.
-   */
-  public String toString() {
-    try {
-      return this.toString(0);
-    } catch (Exception e) {
-      return null;
+    long longValue = number.longValue();
+    if (doubleValue == (double) longValue) {
+      return Long.toString(longValue);
     }
-  }
 
+    return number.toString();
+  }
 
   /**
-   * Make a prettyprinted JSON text of this JSONObject.
-   * <p>
-   * Warning: This method assumes that the data structure is acyclical.
-   * 
-   * @param indentFactor The number of spaces to add to each level of indentation.
-   * @return a printable, displayable, portable, transmittable representation of the object,
-   *         beginning with <code>{</code>&nbsp;<small>(left brace)</small> and ending with
-   *         <code>}</code>&nbsp;<small>(right brace)</small>.
-   * @throws JSONException If the object contains an invalid number.
+   * 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 String toString(int indentFactor) throws JSONException {
-    StringWriter w = new StringWriter();
-    synchronized (w.getBuffer()) {
-      return this.write(w, indentFactor, 0).toString();
+  public static String quote(String data) {
+    if (data == null) {
+      return "\"\"";
+    }
+    try {
+      JSONStringer stringer = new JSONStringer();
+      stringer.open(JSONStringer.Scope.NULL, "");
+      stringer.value(data);
+      stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
+      return stringer.toString();
+    } catch (JSONException e) {
+      throw new AssertionError();
     }
   }
 
   /**
-   * Make a JSON text of an Object value. If the object has an value.toJSONString() method, then
-   * that method will be used to produce the JSON text. The method is required to produce a strictly
-   * conforming text. If the object does not contain a toJSONString method (which is the most common
-   * case), then a text will be produced by other means. If the value is an array or Collection,
-   * then a JSONArray will be made from it and its toJSONString method will be called. If the value
-   * is a MAP, then a JSONObject will be made from it and its toJSONString method will be called.
-   * Otherwise, the value's toString method will be called, and the result will be quoted.
+   * Wraps the given object if necessary.
    *
-   * <p>
-   * Warning: This method assumes that the data structure is acyclical.
-   * 
-   * @param value The value to be serialized.
-   * @return a printable, displayable, transmittable representation of the object, beginning with
-   *         <code>{</code>&nbsp;<small>(left brace)</small> and ending with
-   *         <code>}</code>&nbsp;<small>(right brace)</small>.
-   * @throws JSONException If the value is or contains an invalid number.
+   * <p>If the object is null or , returns {@link #NULL}. If the object is a {@code JSONArray} or
+   * {@code JSONObject}, no wrapping is necessary. If the object is {@code NULL}, no wrapping is
+   * necessary. If the object is an array or {@code Collection}, returns an equivalent {@code
+   * JSONArray}. If the object is a {@code Map}, returns an equivalent {@code JSONObject}. If the
+   * object is a primitive wrapper type or {@code String}, returns the object. If the object is from
+   * a {@code java} package, returns the result of {@code toString}. If the object is some other
+   * kind of object then it is assumed to be a bean and is converted to a JSONObject. If wrapping
+   * fails, returns null.
+   * @param o The object to wrap.
+   * @return The wrapped (if necessary) form of the object {$code o}
    */
-  public static String valueToString(Object value) throws JSONException {
-    if (value == null || value.equals(null)) {
-      return "null";
-    }
-    if (value instanceof JSONString) {
-      Object object;
-      try {
-        object = ((JSONString) value).toJSONString();
-      } catch (Exception e) {
-        throw new JSONException(e);
-      }
-      if (object instanceof String) {
-        return (String) object;
-      }
-      throw new JSONException("Bad value from toJSONString: " + object);
-    }
-    if (value instanceof Number) {
-      return numberToString((Number) value);
-    }
-    if (value instanceof Boolean || value instanceof JSONObject || value instanceof JSONArray) {
-      return value.toString();
+  public static Object wrap(Object o) {
+    if (o == null) {
+      return NULL;
     }
-    if (value instanceof Map) {
-      return new JSONObject((Map) value).toString();
+    if (o instanceof JSONArray || o instanceof JSONObject) {
+      return o;
     }
-    if (value instanceof Collection) {
-      return new JSONArray((Collection) value).toString();
+    if (o.equals(NULL)) {
+      return o;
     }
-    if (value.getClass().isArray()) {
-      return new JSONArray(value).toString();
-    }
-    return quote(value.toString());
-  }
-
-  /**
-   * Wrap an object, if necessary. If the object is null, return the NULL object. If it is an array
-   * or collection, wrap it in a JSONArray. If it is a map, wrap it in a JSONObject. If it is a
-   * standard property (Double, String, et al) then it is already wrapped. Otherwise, if it comes
-   * from one of the java packages, turn it into a string. And if it doesn't, try to wrap it in a
-   * JSONObject. If the wrapping fails, then null is returned.
-   *
-   * @param object The object to wrap
-   * @return The wrapped value
-   */
-  public static Object wrap(Object object) {
     try {
-      if (object == null) {
-        return NULL;
+      if (o instanceof Collection) {
+        return new JSONArray((Collection) o);
+      } else if (o.getClass().isArray()) {
+        return new JSONArray(o);
       }
-      if (object instanceof JSONObject || object instanceof JSONArray || NULL.equals(object)
-          || object instanceof JSONString || object instanceof Byte || object instanceof Character
-          || object instanceof Short || object instanceof Integer || object instanceof Long
-          || object instanceof Boolean || object instanceof Float || object instanceof Double
-          || object instanceof String) {
-        return object;
+      if (o instanceof Map) {
+        return new JSONObject((Map) o);
       }
-
-      if (object instanceof Collection) {
-        return new JSONArray((Collection) object);
-      }
-      if (object.getClass().isArray()) {
-        return new JSONArray(object);
+      if (o instanceof Boolean ||
+          o instanceof Byte ||
+          o instanceof Character ||
+          o instanceof Double ||
+          o instanceof Float ||
+          o instanceof Integer ||
+          o instanceof Long ||
+          o instanceof Short ||
+          o instanceof String) {
+        return o;
       }
-      if (object instanceof Map) {
-        return new JSONObject((Map) object);
-      }
-      Package objectPackage = object.getClass().getPackage();
+      // GEODE-2142: Added check to ignore GemFireCacheImpl
+//      if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?>) {
+//        return o.toString();
+//      }
+      Package objectPackage = o.getClass().getPackage();
       String objectPackageName = objectPackage != null ? objectPackage.getName() : "";
-      if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.")
-          || object.getClass().getClassLoader() == null
-          || object.getClass().getName().contains("GemFireCacheImpl")) {
-        return object.toString();
+      if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.") || o instanceof Enum<?>
+          || o.getClass().getClassLoader() == null
+          || o.getClass().getName().contains("GemFireCacheImpl")) {
+        return o.toString();
       }
-
+//      if (o.getClass().getPackage().getName().startsWith("java.") || o instanceof Enum<?> ||
+//          || objectPackageName.startsWith("javax.")
+//          || o.getClass().getClassLoader() == null
+//          o.getClass().getName().contains("GemFireCacheImpl")) {
+//        return o.toString();
+//      }
+      // GEODE-2142: Added the cyclicalDepCheck
       if (cyclicDepChkEnabled.get() != null && cyclicDependencySet.get() != null) {
-        if (cyclicDepChkEnabled.get() && cyclicDependencySet.get().contains(object)) {
+        if (cyclicDepChkEnabled.get() && cyclicDependencySet.get().contains(o)) {
           // break cyclic reference
-          return object.getClass().getCanonicalName();
+          return o.getClass().getCanonicalName();
         } else {
-          cyclicDependencySet.get().add(object);
-          return new JSONObject(object);
-        }
-      } else
-        return new JSONObject(object);
-
-    } catch (Exception exception) {
-      return null;
-    }
-  }
-
-
-  /**
-   * Write the contents of the JSONObject as JSON text to a writer. For compactness, no whitespace
-   * is added.
-   * <p>
-   * Warning: This method assumes that the data structure is acyclical.
-   *
-   * @return The writer.
-   * @throws JSONException
-   */
-  public Writer write(Writer writer) throws JSONException {
-    return this.write(writer, 0, 0);
-  }
-
-
-  static final Writer writeValue(Writer writer, Object value, int indentFactor, int indent)
-      throws JSONException, IOException {
-    if (value == null || value.equals(null)) {
-      writer.write("null");
-    } else if (value instanceof JSONObject) {
-      ((JSONObject) value).write(writer, indentFactor, indent);
-    } else if (value instanceof JSONArray) {
-      ((JSONArray) value).write(writer, indentFactor, indent);
-    } else if (value instanceof Map) {
-      new JSONObject((Map) value).write(writer, indentFactor, indent);
-    } else if (value instanceof Collection) {
-      new JSONArray((Collection) value).write(writer, indentFactor, indent);
-    } else if (value.getClass().isArray()) {
-      new JSONArray(value).write(writer, indentFactor, indent);
-    } else if (value instanceof Number) {
-      writer.write(numberToString((Number) value));
-    } else if (value instanceof Boolean) {
-      writer.write(value.toString());
-    } else if (value instanceof JSONString) {
-      Object o;
-      try {
-        o = ((JSONString) value).toJSONString();
-      } catch (Exception e) {
-        throw new JSONException(e);
-      }
-      writer.write(o != null ? o.toString() : quote(value.toString()));
-    } else {
-      quote(value.toString(), writer);
-    }
-    return writer;
-  }
-
-  static final void indent(Writer writer, int indent) throws IOException {
-    for (int i = 0; i < indent; i += 1) {
-      writer.write(' ');
-    }
-  }
-
-  /**
-   * Write the contents of the JSONObject as JSON text to a writer. For compactness, no whitespace
-   * is added.
-   * <p>
-   * Warning: This method assumes that the data structure is acyclical.
-   *
-   * @return The writer.
-   * @throws JSONException
-   */
-  Writer write(Writer writer, int indentFactor, int indent) throws JSONException {
-    try {
-      boolean commanate = false;
-      final int length = this.length();
-      Iterator keys = this.keys();
-      writer.write('{');
-
-      if (length == 1) {
-        Object key = keys.next();
-        writer.write(quote(key.toString()));
-        writer.write(':');
-        if (indentFactor > 0) {
-          writer.write(' ');
-        }
-        writeValue(writer, this.map.get(key), indentFactor, indent);
-      } else if (length != 0) {
-        final int newindent = indent + indentFactor;
-        while (keys.hasNext()) {
-          Object key = keys.next();
-          if (commanate) {
-            writer.write(',');
-          }
-          if (indentFactor > 0) {
-            writer.write('\n');
-          }
-          indent(writer, newindent);
-          writer.write(quote(key.toString()));
-          writer.write(':');
-          if (indentFactor > 0) {
-            writer.write(' ');
-          }
-          writeValue(writer, this.map.get(key), indentFactor, newindent);
-          commanate = true;
-        }
-        if (indentFactor > 0) {
-          writer.write('\n');
+          cyclicDependencySet.get().add(o);
+          return new JSONObject(o);
         }
-        indent(writer, indent);
+      } else {
+        return new JSONObject(o);
       }
-      writer.write('}');
-      return writer;
-    } catch (IOException exception) {
-      throw new JSONException(exception);
+    } catch (Exception ignored) {
     }
+    return null;
   }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/JSONString.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONString.java b/geode-json/src/main/java/org/json/JSONString.java
index 4a09d89..34815a8 100755
--- a/geode-json/src/main/java/org/json/JSONString.java
+++ b/geode-json/src/main/java/org/json/JSONString.java
@@ -1,17 +1,18 @@
 package org.json;
-
 /**
- * The <code>JSONString</code> interface allows a <code>toJSONString()</code> method so that a class
- * can change the behavior of <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
- * and <code>JSONWriter.value(</code>Object<code>)</code>. The <code>toJSONString</code> method will
- * be used instead of the default behavior of using the Object's <code>toString()</code> method and
- * quoting the result.
+ * The <code>JSONString</code> interface allows a <code>toJSONString()</code> 
+ * method so that a class can change the behavior of 
+ * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
+ * and <code>JSONWriter.value(</code>Object<code>)</code>. The 
+ * <code>toJSONString</code> method will be used instead of the default behavior 
+ * of using the Object's <code>toString()</code> method and quoting the result.
  */
 public interface JSONString {
   /**
-   * The <code>toJSONString</code> method allows a class to produce its own JSON serialization.
+   * The <code>toJSONString</code> method allows a class to produce its own JSON 
+   * serialization. 
    * 
    * @return A strictly syntactically correct JSON text.
    */
   public String toJSONString();
-}
+}
\ No newline at end of file


[6/8] geode git commit: GEODE-2142: Spotless

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/geode-json/src/main/java/org/json/JSONTokener.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONTokener.java b/geode-json/src/main/java/org/json/JSONTokener.java
index 59eb4bc..21c9fb0 100755
--- a/geode-json/src/main/java/org/json/JSONTokener.java
+++ b/geode-json/src/main/java/org/json/JSONTokener.java
@@ -1,17 +1,15 @@
 /*
  * 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
+ * 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
+ * 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.
+ * 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.json;
@@ -22,637 +20,620 @@ import java.io.IOException;
 import java.io.Reader;
 
 /**
- * Parses a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>)
- * encoded string into the corresponding object. Most clients of
- * this class will use only need the {@link #JSONTokener(String) constructor}
- * and {@link #nextValue} method. Example usage: <pre>
- * String json = "{"
- *         + "  \"query\": \"Pizza\", "
- *         + "  \"locations\": [ 94043, 90210 ] "
- *         + "}";
+ * Parses a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>) encoded string into
+ * the corresponding object. Most clients of this class will use only need the
+ * {@link #JSONTokener(String) constructor} and {@link #nextValue} method. Example usage:
+ * 
+ * <pre>
+ * String json = "{" + "  \"query\": \"Pizza\", " + "  \"locations\": [ 94043, 90210 ] " + "}";
  *
  * JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
  * String query = object.getString("query");
- * JSONArray locations = object.getJSONArray("locations");</pre>
+ * JSONArray locations = object.getJSONArray("locations");
+ * </pre>
  *
- * <p>For best interoperability and performance use JSON that complies with
- * RFC 4627, such as that generated by {@link JSONStringer}. For legacy reasons
- * this parser is lenient, so a successful parse does not indicate that the
- * input string was valid JSON. All of the following syntax errors will be
- * ignored:
+ * <p>
+ * For best interoperability and performance use JSON that complies with RFC 4627, such as that
+ * generated by {@link JSONStringer}. For legacy reasons this parser is lenient, so a successful
+ * parse does not indicate that the input string was valid JSON. All of the following syntax errors
+ * will be ignored:
  * <ul>
- * <li>End of line comments starting with {@code //} or {@code #} and ending
- * with a newline character.
- * <li>C-style comments starting with {@code /*} and ending with
- * {@code *}{@code /}. Such comments may not be nested.
+ * <li>End of line comments starting with {@code //} or {@code #} and ending with a newline
+ * character.
+ * <li>C-style comments starting with {@code /*} and ending with {@code *}{@code /}. Such comments
+ * may not be nested.
  * <li>Strings that are unquoted or {@code 'single quoted'}.
  * <li>Hexadecimal integers prefixed with {@code 0x} or {@code 0X}.
  * <li>Octal integers prefixed with {@code 0}.
  * <li>Array elements separated by {@code ;}.
- * <li>Unnecessary array separators. These are interpreted as if null was the
- * omitted value.
+ * <li>Unnecessary array separators. These are interpreted as if null was the omitted value.
  * <li>Key-value pairs separated by {@code =} or {@code =>}.
  * <li>Key-value pairs separated by {@code ;}.
  * </ul>
  *
- * <p>Each tokener may be used to parse a single JSON string. Instances of this
- * class are not thread safe. Although this class is nonfinal, it was not
- * designed for inheritance and should not be subclassed. In particular,
- * self-use by overrideable methods is not specified. See <i>Effective Java</i>
- * Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * <p>
+ * Each tokener may be used to parse a single JSON string. Instances of this class are not thread
+ * safe. Although this class is nonfinal, it was not designed for inheritance and should not be
+ * subclassed. In particular, self-use by overrideable methods is not specified. See <i>Effective
+ * Java</i> Item 17, "Design and Document or inheritance or else prohibit it" for further
  * information.
  */
 public class JSONTokener {
 
-    /**
-     * The input JSON.
-     */
-    private final String in;
-
-    /**
-     * The index of the next character to be returned by {@link #next}. When
-     * the input is exhausted, this equals the input's length.
-     */
-    private int pos;
-
-    /**
-     * @param in JSON encoded string. Null is not permitted and will yield a
-     *           tokener that throws {@code NullPointerExceptions} when methods are
-     *           called.
-     */
-    public JSONTokener(String in) {
-        // consume an optional byte order mark (BOM) if it exists
-        if (in != null && in.startsWith("\ufeff")) {
-            in = in.substring(1);
-        }
-        this.in = in;
+  /**
+   * The input JSON.
+   */
+  private final String in;
+
+  /**
+   * The index of the next character to be returned by {@link #next}. When the input is exhausted,
+   * this equals the input's length.
+   */
+  private int pos;
+
+  /**
+   * @param in JSON encoded string. Null is not permitted and will yield a tokener that throws
+   *        {@code NullPointerExceptions} when methods are called.
+   */
+  public JSONTokener(String in) {
+    // consume an optional byte order mark (BOM) if it exists
+    if (in != null && in.startsWith("\ufeff")) {
+      in = in.substring(1);
     }
-
-    public JSONTokener(Reader input) throws IOException {
-        StringBuilder s = new StringBuilder();
-        char[] readBuf = new char[102400];
-        int n = input.read(readBuf);
-        while (n >= 0) {
-            s.append(readBuf, 0, n);
-            n = input.read(readBuf);
-        }
-        in = s.toString();
-        pos = 0;
+    this.in = in;
+  }
+
+  public JSONTokener(Reader input) throws IOException {
+    StringBuilder s = new StringBuilder();
+    char[] readBuf = new char[102400];
+    int n = input.read(readBuf);
+    while (n >= 0) {
+      s.append(readBuf, 0, n);
+      n = input.read(readBuf);
     }
-
-    /**
-     * Returns the next value from the input.
-     *
-     * @return a {@link JSONObject}, {@link JSONArray}, String, Boolean,
-     * Integer, Long, Double or {@link JSONObject#NULL}.
-     * @throws JSONException if the input is malformed.
-     */
-    public Object nextValue() throws JSONException {
-        int c = nextCleanInternal();
-        switch (c) {
-            case -1:
-                throw syntaxError("End of input");
-
-            case '{':
-                return readObject();
-
-            case '[':
-                return readArray();
-
-            case '\'':
-            case '"':
-                return nextString((char) c);
+    in = s.toString();
+    pos = 0;
+  }
+
+  /**
+   * Returns the next value from the input.
+   *
+   * @return a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double or
+   *         {@link JSONObject#NULL}.
+   * @throws JSONException if the input is malformed.
+   */
+  public Object nextValue() throws JSONException {
+    int c = nextCleanInternal();
+    switch (c) {
+      case -1:
+        throw syntaxError("End of input");
+
+      case '{':
+        return readObject();
+
+      case '[':
+        return readArray();
+
+      case '\'':
+      case '"':
+        return nextString((char) c);
+
+      default:
+        pos--;
+        return readLiteral();
+    }
+  }
+
+  private int nextCleanInternal() throws JSONException {
+    while (pos < in.length()) {
+      int c = in.charAt(pos++);
+      switch (c) {
+        case '\t':
+        case ' ':
+        case '\n':
+        case '\r':
+          continue;
+
+        case '/':
+          if (pos == in.length()) {
+            return c;
+          }
+
+          char peek = in.charAt(pos);
+          switch (peek) {
+            case '*':
+              // skip a /* c-style comment */
+              pos++;
+              int commentEnd = in.indexOf("*/", pos);
+              if (commentEnd == -1) {
+                throw syntaxError("Unterminated comment");
+              }
+              pos = commentEnd + 2;
+              continue;
+
+            case '/':
+              // skip a // end-of-line comment
+              pos++;
+              skipToEndOfLine();
+              continue;
 
             default:
-                pos--;
-                return readLiteral();
-        }
+              return c;
+          }
+
+        case '#':
+          /*
+           * Skip a # hash end-of-line comment. The JSON RFC doesn't specify this behavior, but it's
+           * required to parse existing documents. See http://b/2571423.
+           */
+          skipToEndOfLine();
+          continue;
+
+        default:
+          return c;
+      }
     }
 
-    private int nextCleanInternal() throws JSONException {
-        while (pos < in.length()) {
-            int c = in.charAt(pos++);
-            switch (c) {
-                case '\t':
-                case ' ':
-                case '\n':
-                case '\r':
-                    continue;
-
-                case '/':
-                    if (pos == in.length()) {
-                        return c;
-                    }
-
-                    char peek = in.charAt(pos);
-                    switch (peek) {
-                        case '*':
-                            // skip a /* c-style comment */
-                            pos++;
-                            int commentEnd = in.indexOf("*/", pos);
-                            if (commentEnd == -1) {
-                                throw syntaxError("Unterminated comment");
-                            }
-                            pos = commentEnd + 2;
-                            continue;
-
-                        case '/':
-                            // skip a // end-of-line comment
-                            pos++;
-                            skipToEndOfLine();
-                            continue;
-
-                        default:
-                            return c;
-                    }
-
-                case '#':
-                    /*
-                     * Skip a # hash end-of-line comment. The JSON RFC doesn't
-                     * specify this behavior, but it's required to parse
-                     * existing documents. See http://b/2571423.
-                     */
-                    skipToEndOfLine();
-                    continue;
-
-                default:
-                    return c;
-            }
-        }
-
-        return -1;
+    return -1;
+  }
+
+  /**
+   * Advances the position until after the next newline character. If the line is terminated by
+   * "\r\n", the '\n' must be consumed as whitespace by the caller.
+   */
+  private void skipToEndOfLine() {
+    for (; pos < in.length(); pos++) {
+      char c = in.charAt(pos);
+      if (c == '\r' || c == '\n') {
+        pos++;
+        break;
+      }
     }
-
-    /**
-     * Advances the position until after the next newline character. If the line
-     * is terminated by "\r\n", the '\n' must be consumed as whitespace by the
-     * caller.
+  }
+
+  /**
+   * Returns the string up to but not including {@code quote}, unescaping any character escape
+   * sequences encountered along the way. The opening quote should have already been read. This
+   * consumes the closing quote, but does not include it in the returned string.
+   *
+   * @param quote either ' or ".
+   * @return The unescaped string.
+   * @throws JSONException if the string isn't terminated by a closing quote correctly.
+   */
+  public String nextString(char quote) throws JSONException {
+    /*
+     * For strings that are free of escape sequences, we can just extract the result as a substring
+     * of the input. But if we encounter an escape sequence, we need to use a StringBuilder to
+     * compose the result.
      */
-    private void skipToEndOfLine() {
-        for (; pos < in.length(); pos++) {
-            char c = in.charAt(pos);
-            if (c == '\r' || c == '\n') {
-                pos++;
-                break;
-            }
+    StringBuilder builder = null;
+
+    /* the index of the first character not yet appended to the builder. */
+    int start = pos;
+
+    while (pos < in.length()) {
+      int c = in.charAt(pos++);
+      if (c == quote) {
+        if (builder == null) {
+          // a new string avoids leaking memory
+          // noinspection RedundantStringConstructorCall
+          return new String(in.substring(start, pos - 1));
+        } else {
+          builder.append(in, start, pos - 1);
+          return builder.toString();
         }
-    }
+      }
 
-    /**
-     * Returns the string up to but not including {@code quote}, unescaping any
-     * character escape sequences encountered along the way. The opening quote
-     * should have already been read. This consumes the closing quote, but does
-     * not include it in the returned string.
-     *
-     * @param quote either ' or ".
-     * @return The unescaped string.
-     * @throws JSONException if the string isn't terminated by a closing quote correctly.
-     */
-    public String nextString(char quote) throws JSONException {
-        /*
-         * For strings that are free of escape sequences, we can just extract
-         * the result as a substring of the input. But if we encounter an escape
-         * sequence, we need to use a StringBuilder to compose the result.
-         */
-        StringBuilder builder = null;
-
-        /* the index of the first character not yet appended to the builder. */
-        int start = pos;
-
-        while (pos < in.length()) {
-            int c = in.charAt(pos++);
-            if (c == quote) {
-                if (builder == null) {
-                    // a new string avoids leaking memory
-                    //noinspection RedundantStringConstructorCall
-                    return new String(in.substring(start, pos - 1));
-                } else {
-                    builder.append(in, start, pos - 1);
-                    return builder.toString();
-                }
-            }
-
-            if (c == '\\') {
-                if (pos == in.length()) {
-                    throw syntaxError("Unterminated escape sequence");
-                }
-                if (builder == null) {
-                    builder = new StringBuilder();
-                }
-                builder.append(in, start, pos - 1);
-                builder.append(readEscapeCharacter());
-                start = pos;
-            }
+      if (c == '\\') {
+        if (pos == in.length()) {
+          throw syntaxError("Unterminated escape sequence");
         }
-
-        throw syntaxError("Unterminated string");
-    }
-
-    /**
-     * Unescapes the character identified by the character or characters that
-     * immediately follow a backslash. The backslash '\' should have already
-     * been read. This supports both unicode escapes "u000A" and two-character
-     * escapes "\n".
-     */
-    private char readEscapeCharacter() throws JSONException {
-        char escaped = in.charAt(pos++);
-        switch (escaped) {
-            case 'u':
-                if (pos + 4 > in.length()) {
-                    throw syntaxError("Unterminated escape sequence");
-                }
-                String hex = in.substring(pos, pos + 4);
-                pos += 4;
-                try {
-                    return (char) Integer.parseInt(hex, 16);
-                } catch (NumberFormatException nfe) {
-                    throw syntaxError("Invalid escape sequence: " + hex);
-                }
-
-            case 't':
-                return '\t';
-
-            case 'b':
-                return '\b';
-
-            case 'n':
-                return '\n';
-
-            case 'r':
-                return '\r';
-
-            case 'f':
-                return '\f';
-
-            case '\'':
-            case '"':
-            case '\\':
-            default:
-                return escaped;
+        if (builder == null) {
+          builder = new StringBuilder();
         }
+        builder.append(in, start, pos - 1);
+        builder.append(readEscapeCharacter());
+        start = pos;
+      }
     }
 
-    /**
-     * Reads a null, boolean, numeric or unquoted string literal value. Numeric
-     * values will be returned as an Integer, Long, or Double, in that order of
-     * preference.
-     */
-    private Object readLiteral() throws JSONException {
-        String literal = nextToInternal("{}[]/\\:,=;# \t\f");
-
-        if (literal.length() == 0) {
-            throw syntaxError("Expected literal value");
-        } else if ("null".equalsIgnoreCase(literal)) {
-            return JSONObject.NULL;
-        } else if ("true".equalsIgnoreCase(literal)) {
-            return Boolean.TRUE;
-        } else if ("false".equalsIgnoreCase(literal)) {
-            return Boolean.FALSE;
-        }
-
-        /* try to parse as an integral type... */
-        if (literal.indexOf('.') == -1) {
-            int base = 10;
-            String number = literal;
-            if (number.startsWith("0x") || number.startsWith("0X")) {
-                number = number.substring(2);
-                base = 16;
-            } else if (number.startsWith("0") && number.length() > 1) {
-                number = number.substring(1);
-                base = 8;
-            }
-            try {
-                long longValue = Long.parseLong(number, base);
-                if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
-                    return (int) longValue;
-                } else {
-                    return longValue;
-                }
-            } catch (NumberFormatException e) {
-                /*
-                 * This only happens for integral numbers greater than
-                 * Long.MAX_VALUE, numbers in exponential form (5e-10) and
-                 * unquoted strings. Fall through to try floating point.
-                 */
-            }
+    throw syntaxError("Unterminated string");
+  }
+
+  /**
+   * Unescapes the character identified by the character or characters that immediately follow a
+   * backslash. The backslash '\' should have already been read. This supports both unicode escapes
+   * "u000A" and two-character escapes "\n".
+   */
+  private char readEscapeCharacter() throws JSONException {
+    char escaped = in.charAt(pos++);
+    switch (escaped) {
+      case 'u':
+        if (pos + 4 > in.length()) {
+          throw syntaxError("Unterminated escape sequence");
         }
-
-        /* ...next try to parse as a floating point... */
+        String hex = in.substring(pos, pos + 4);
+        pos += 4;
         try {
-            return Double.valueOf(literal);
-        } catch (NumberFormatException ignored) {
+          return (char) Integer.parseInt(hex, 16);
+        } catch (NumberFormatException nfe) {
+          throw syntaxError("Invalid escape sequence: " + hex);
         }
 
-        /* ... finally give up. We have an unquoted string */
-        //noinspection RedundantStringConstructorCall
-        return new String(literal); // a new string avoids leaking memory
-    }
+      case 't':
+        return '\t';
 
-    /**
-     * Returns the string up to but not including any of the given characters or
-     * a newline character. This does not consume the excluded character.
-     */
-    private String nextToInternal(String excluded) {
-        int start = pos;
-        for (; pos < in.length(); pos++) {
-            char c = in.charAt(pos);
-            if (c == '\r' || c == '\n' || excluded.indexOf(c) != -1) {
-                return in.substring(start, pos);
-            }
-        }
-        return in.substring(start);
-    }
+      case 'b':
+        return '\b';
 
-    /**
-     * Reads a sequence of key/value pairs and the trailing closing brace '}' of
-     * an object. The opening brace '{' should have already been read.
-     */
-    private JSONObject readObject() throws JSONException {
-        JSONObject result = new JSONObject();
-
-        /* Peek to see if this is the empty object. */
-        int first = nextCleanInternal();
-        if (first == '}') {
-            return result;
-        } else if (first != -1) {
-            pos--;
-        }
+      case 'n':
+        return '\n';
 
-        while (true) {
-            Object name = nextValue();
-            if (!(name instanceof String)) {
-                if (name == null) {
-                    throw syntaxError("Names cannot be null");
-                } else {
-                    throw syntaxError("Names must be strings, but " + name
-                            + " is of type " + name.getClass().getName());
-                }
-            }
-
-            /*
-             * Expect the name/value separator to be either a colon ':', an
-             * equals sign '=', or an arrow "=>". The last two are bogus but we
-             * include them because that's what the original implementation did.
-             */
-            int separator = nextCleanInternal();
-            if (separator != ':' && separator != '=') {
-                throw syntaxError("Expected ':' after " + name);
-            }
-            if (pos < in.length() && in.charAt(pos) == '>') {
-                pos++;
-            }
-
-            result.put((String) name, nextValue());
-
-            switch (nextCleanInternal()) {
-                case '}':
-                    return result;
-                case ';':
-                case ',':
-                    continue;
-                default:
-                    throw syntaxError("Unterminated object");
-            }
-        }
-    }
+      case 'r':
+        return '\r';
 
-    /**
-     * Reads a sequence of values and the trailing closing brace ']' of an
-     * array. The opening brace '[' should have already been read. Note that
-     * "[]" yields an empty array, but "[,]" returns a two-element array
-     * equivalent to "[null,null]".
-     */
-    private JSONArray readArray() throws JSONException {
-        JSONArray result = new JSONArray();
-
-        /* to cover input that ends with ",]". */
-        boolean hasTrailingSeparator = false;
-
-        while (true) {
-            switch (nextCleanInternal()) {
-                case -1:
-                    throw syntaxError("Unterminated array");
-                case ']':
-                    if (hasTrailingSeparator) {
-                        result.put(null);
-                    }
-                    return result;
-                case ',':
-                case ';':
-                    /* A separator without a value first means "null". */
-                    result.put(null);
-                    hasTrailingSeparator = true;
-                    continue;
-                default:
-                    pos--;
-            }
-
-            result.put(nextValue());
-
-            switch (nextCleanInternal()) {
-                case ']':
-                    return result;
-                case ',':
-                case ';':
-                    hasTrailingSeparator = true;
-                    continue;
-                default:
-                    throw syntaxError("Unterminated array");
-            }
-        }
-    }
+      case 'f':
+        return '\f';
 
-    /**
-     * Returns an exception containing the given message plus the current
-     * position and the entire input string.
-     *
-     * @param message The message we want to include.
-     * @return An exception that we can throw.
-     */
-    public JSONException syntaxError(String message) {
-        return new JSONException(message + this);
+      case '\'':
+      case '"':
+      case '\\':
+      default:
+        return escaped;
     }
-
-    /**
-     * Returns the current position and the entire input string.
-     */
-    @Override
-    public String toString() {
-        // consistent with the original implementation
-        return " at character " + pos + " of " + in;
+  }
+
+  /**
+   * Reads a null, boolean, numeric or unquoted string literal value. Numeric values will be
+   * returned as an Integer, Long, or Double, in that order of preference.
+   */
+  private Object readLiteral() throws JSONException {
+    String literal = nextToInternal("{}[]/\\:,=;# \t\f");
+
+    if (literal.length() == 0) {
+      throw syntaxError("Expected literal value");
+    } else if ("null".equalsIgnoreCase(literal)) {
+      return JSONObject.NULL;
+    } else if ("true".equalsIgnoreCase(literal)) {
+      return Boolean.TRUE;
+    } else if ("false".equalsIgnoreCase(literal)) {
+      return Boolean.FALSE;
     }
 
-    /*
-     * Legacy APIs.
-     *
-     * None of the methods below are on the critical path of parsing JSON
-     * documents. They exist only because they were exposed by the original
-     * implementation and may be used by some clients.
-     */
-
-    /**
-     * Returns true until the input has been exhausted.
-     *
-     * @return true if more input exists.
-     */
-    public boolean more() {
-        return pos < in.length();
+    /* try to parse as an integral type... */
+    if (literal.indexOf('.') == -1) {
+      int base = 10;
+      String number = literal;
+      if (number.startsWith("0x") || number.startsWith("0X")) {
+        number = number.substring(2);
+        base = 16;
+      } else if (number.startsWith("0") && number.length() > 1) {
+        number = number.substring(1);
+        base = 8;
+      }
+      try {
+        long longValue = Long.parseLong(number, base);
+        if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
+          return (int) longValue;
+        } else {
+          return longValue;
+        }
+      } catch (NumberFormatException e) {
+        /*
+         * This only happens for integral numbers greater than Long.MAX_VALUE, numbers in
+         * exponential form (5e-10) and unquoted strings. Fall through to try floating point.
+         */
+      }
     }
 
-    /**
-     * Returns the next available character, or the null character '\0' if all
-     * input has been exhausted. The return value of this method is ambiguous
-     * for JSON strings that contain the character '\0'.
-     *
-     * @return the next character.
-     */
-    public char next() {
-        return pos < in.length() ? in.charAt(pos++) : '\0';
+    /* ...next try to parse as a floating point... */
+    try {
+      return Double.valueOf(literal);
+    } catch (NumberFormatException ignored) {
     }
 
-    /**
-     * Returns the next available character if it equals {@code c}. Otherwise an
-     * exception is thrown.
-     *
-     * @param c The character we are looking for.
-     * @return the next character.
-     * @throws JSONException If the next character isn't {@code c}
-     */
-    public char next(char c) throws JSONException {
-        char result = next();
-        if (result != c) {
-            throw syntaxError("Expected " + c + " but was " + result);
-        }
-        return result;
+    /* ... finally give up. We have an unquoted string */
+    // noinspection RedundantStringConstructorCall
+    return new String(literal); // a new string avoids leaking memory
+  }
+
+  /**
+   * Returns the string up to but not including any of the given characters or a newline character.
+   * This does not consume the excluded character.
+   */
+  private String nextToInternal(String excluded) {
+    int start = pos;
+    for (; pos < in.length(); pos++) {
+      char c = in.charAt(pos);
+      if (c == '\r' || c == '\n' || excluded.indexOf(c) != -1) {
+        return in.substring(start, pos);
+      }
     }
-
-    /**
-     * Returns the next character that is not whitespace and does not belong to
-     * a comment. If the input is exhausted before such a character can be
-     * found, the null character '\0' is returned. The return value of this
-     * method is ambiguous for JSON strings that contain the character '\0'.
-     *
-     * @return The next non-whitespace character.
-     * @throws JSONException Should not be possible.
-     */
-    public char nextClean() throws JSONException {
-        int nextCleanInt = nextCleanInternal();
-        return nextCleanInt == -1 ? '\0' : (char) nextCleanInt;
+    return in.substring(start);
+  }
+
+  /**
+   * Reads a sequence of key/value pairs and the trailing closing brace '}' of an object. The
+   * opening brace '{' should have already been read.
+   */
+  private JSONObject readObject() throws JSONException {
+    JSONObject result = new JSONObject();
+
+    /* Peek to see if this is the empty object. */
+    int first = nextCleanInternal();
+    if (first == '}') {
+      return result;
+    } else if (first != -1) {
+      pos--;
     }
 
-    /**
-     * Returns the next {@code length} characters of the input.
-     *
-     * <p>The returned string shares its backing character array with this
-     * tokener's input string. If a reference to the returned string may be held
-     * indefinitely, you should use {@code new String(result)} to copy it first
-     * to avoid memory leaks.
-     *
-     * @param length The desired number of characters to return.
-     * @return The next few characters.
-     * @throws JSONException if the remaining input is not long enough to
-     *                       satisfy this request.
-     */
-    public String next(int length) throws JSONException {
-        if (pos + length > in.length()) {
-            throw syntaxError(length + " is out of bounds");
+    while (true) {
+      Object name = nextValue();
+      if (!(name instanceof String)) {
+        if (name == null) {
+          throw syntaxError("Names cannot be null");
+        } else {
+          throw syntaxError(
+              "Names must be strings, but " + name + " is of type " + name.getClass().getName());
         }
-        String result = in.substring(pos, pos + length);
-        pos += length;
-        return result;
+      }
+
+      /*
+       * Expect the name/value separator to be either a colon ':', an equals sign '=', or an arrow
+       * "=>". The last two are bogus but we include them because that's what the original
+       * implementation did.
+       */
+      int separator = nextCleanInternal();
+      if (separator != ':' && separator != '=') {
+        throw syntaxError("Expected ':' after " + name);
+      }
+      if (pos < in.length() && in.charAt(pos) == '>') {
+        pos++;
+      }
+
+      result.put((String) name, nextValue());
+
+      switch (nextCleanInternal()) {
+        case '}':
+          return result;
+        case ';':
+        case ',':
+          continue;
+        default:
+          throw syntaxError("Unterminated object");
+      }
     }
-
-    /**
-     * Returns the {@link String#trim trimmed} string holding the characters up
-     * to but not including the first of:
-     * <ul>
-     * <li>any character in {@code excluded}
-     * <li>a newline character '\n'
-     * <li>a carriage return '\r'
-     * </ul>
-     *
-     * <p>The returned string shares its backing character array with this
-     * tokener's input string. If a reference to the returned string may be held
-     * indefinitely, you should use {@code new String(result)} to copy it first
-     * to avoid memory leaks.
-     *
-     * @param excluded The limiting string where the search should stop.
-     * @return a possibly-empty string
-     */
-    public String nextTo(String excluded) {
-        if (excluded == null) {
-            throw new NullPointerException("excluded == null");
-        }
-        return nextToInternal(excluded).trim();
+  }
+
+  /**
+   * Reads a sequence of values and the trailing closing brace ']' of an array. The opening brace
+   * '[' should have already been read. Note that "[]" yields an empty array, but "[,]" returns a
+   * two-element array equivalent to "[null,null]".
+   */
+  private JSONArray readArray() throws JSONException {
+    JSONArray result = new JSONArray();
+
+    /* to cover input that ends with ",]". */
+    boolean hasTrailingSeparator = false;
+
+    while (true) {
+      switch (nextCleanInternal()) {
+        case -1:
+          throw syntaxError("Unterminated array");
+        case ']':
+          if (hasTrailingSeparator) {
+            result.put(null);
+          }
+          return result;
+        case ',':
+        case ';':
+          /* A separator without a value first means "null". */
+          result.put(null);
+          hasTrailingSeparator = true;
+          continue;
+        default:
+          pos--;
+      }
+
+      result.put(nextValue());
+
+      switch (nextCleanInternal()) {
+        case ']':
+          return result;
+        case ',':
+        case ';':
+          hasTrailingSeparator = true;
+          continue;
+        default:
+          throw syntaxError("Unterminated array");
+      }
     }
-
-    /**
-     * Equivalent to {@code nextTo(String.valueOf(excluded))}.
-     *
-     * @param excluded The limiting character.
-     * @return a possibly-empty string
-     */
-    public String nextTo(char excluded) {
-        return nextToInternal(String.valueOf(excluded)).trim();
+  }
+
+  /**
+   * Returns an exception containing the given message plus the current position and the entire
+   * input string.
+   *
+   * @param message The message we want to include.
+   * @return An exception that we can throw.
+   */
+  public JSONException syntaxError(String message) {
+    return new JSONException(message + this);
+  }
+
+  /**
+   * Returns the current position and the entire input string.
+   */
+  @Override
+  public String toString() {
+    // consistent with the original implementation
+    return " at character " + pos + " of " + in;
+  }
+
+  /*
+   * Legacy APIs.
+   *
+   * None of the methods below are on the critical path of parsing JSON documents. They exist only
+   * because they were exposed by the original implementation and may be used by some clients.
+   */
+
+  /**
+   * Returns true until the input has been exhausted.
+   *
+   * @return true if more input exists.
+   */
+  public boolean more() {
+    return pos < in.length();
+  }
+
+  /**
+   * Returns the next available character, or the null character '\0' if all input has been
+   * exhausted. The return value of this method is ambiguous for JSON strings that contain the
+   * character '\0'.
+   *
+   * @return the next character.
+   */
+  public char next() {
+    return pos < in.length() ? in.charAt(pos++) : '\0';
+  }
+
+  /**
+   * Returns the next available character if it equals {@code c}. Otherwise an exception is thrown.
+   *
+   * @param c The character we are looking for.
+   * @return the next character.
+   * @throws JSONException If the next character isn't {@code c}
+   */
+  public char next(char c) throws JSONException {
+    char result = next();
+    if (result != c) {
+      throw syntaxError("Expected " + c + " but was " + result);
     }
-
-    /**
-     * Advances past all input up to and including the next occurrence of
-     * {@code thru}. If the remaining input doesn't contain {@code thru}, the
-     * input is exhausted.
-     *
-     * @param thru The string to skip over.
-     */
-    public void skipPast(String thru) {
-        int thruStart = in.indexOf(thru, pos);
-        pos = thruStart == -1 ? in.length() : (thruStart + thru.length());
+    return result;
+  }
+
+  /**
+   * Returns the next character that is not whitespace and does not belong to a comment. If the
+   * input is exhausted before such a character can be found, the null character '\0' is returned.
+   * The return value of this method is ambiguous for JSON strings that contain the character '\0'.
+   *
+   * @return The next non-whitespace character.
+   * @throws JSONException Should not be possible.
+   */
+  public char nextClean() throws JSONException {
+    int nextCleanInt = nextCleanInternal();
+    return nextCleanInt == -1 ? '\0' : (char) nextCleanInt;
+  }
+
+  /**
+   * Returns the next {@code length} characters of the input.
+   *
+   * <p>
+   * The returned string shares its backing character array with this tokener's input string. If a
+   * reference to the returned string may be held indefinitely, you should use
+   * {@code new String(result)} to copy it first to avoid memory leaks.
+   *
+   * @param length The desired number of characters to return.
+   * @return The next few characters.
+   * @throws JSONException if the remaining input is not long enough to satisfy this request.
+   */
+  public String next(int length) throws JSONException {
+    if (pos + length > in.length()) {
+      throw syntaxError(length + " is out of bounds");
     }
-
-    /**
-     * Advances past all input up to but not including the next occurrence of
-     * {@code to}. If the remaining input doesn't contain {@code to}, the input
-     * is unchanged.
-     *
-     * @param to The character we want to skip to.
-     * @return The value of {@code to} or null.
-     */
-    public char skipTo(char to) {
-        int index = in.indexOf(to, pos);
-        if (index != -1) {
-            pos = index;
-            return to;
-        } else {
-            return '\0';
-        }
+    String result = in.substring(pos, pos + length);
+    pos += length;
+    return result;
+  }
+
+  /**
+   * Returns the {@link String#trim trimmed} string holding the characters up to but not including
+   * the first of:
+   * <ul>
+   * <li>any character in {@code excluded}
+   * <li>a newline character '\n'
+   * <li>a carriage return '\r'
+   * </ul>
+   *
+   * <p>
+   * The returned string shares its backing character array with this tokener's input string. If a
+   * reference to the returned string may be held indefinitely, you should use
+   * {@code new String(result)} to copy it first to avoid memory leaks.
+   *
+   * @param excluded The limiting string where the search should stop.
+   * @return a possibly-empty string
+   */
+  public String nextTo(String excluded) {
+    if (excluded == null) {
+      throw new NullPointerException("excluded == null");
     }
-
-    /**
-     * Unreads the most recent character of input. If no input characters have
-     * been read, the input is unchanged.
-     */
-    public void back() {
-        if (--pos == -1) {
-            pos = 0;
-        }
+    return nextToInternal(excluded).trim();
+  }
+
+  /**
+   * Equivalent to {@code nextTo(String.valueOf(excluded))}.
+   *
+   * @param excluded The limiting character.
+   * @return a possibly-empty string
+   */
+  public String nextTo(char excluded) {
+    return nextToInternal(String.valueOf(excluded)).trim();
+  }
+
+  /**
+   * Advances past all input up to and including the next occurrence of {@code thru}. If the
+   * remaining input doesn't contain {@code thru}, the input is exhausted.
+   *
+   * @param thru The string to skip over.
+   */
+  public void skipPast(String thru) {
+    int thruStart = in.indexOf(thru, pos);
+    pos = thruStart == -1 ? in.length() : (thruStart + thru.length());
+  }
+
+  /**
+   * Advances past all input up to but not including the next occurrence of {@code to}. If the
+   * remaining input doesn't contain {@code to}, the input is unchanged.
+   *
+   * @param to The character we want to skip to.
+   * @return The value of {@code to} or null.
+   */
+  public char skipTo(char to) {
+    int index = in.indexOf(to, pos);
+    if (index != -1) {
+      pos = index;
+      return to;
+    } else {
+      return '\0';
     }
-
-    /**
-     * Returns the integer [0..15] value for the given hex character, or -1
-     * for non-hex input.
-     *
-     * @param hex a character in the ranges [0-9], [A-F] or [a-f]. Any other
-     *            character will yield a -1 result.
-     * @return The decoded integer.
-     */
-    public static int dehexchar(char hex) {
-        if (hex >= '0' && hex <= '9') {
-            return hex - '0';
-        } else if (hex >= 'A' && hex <= 'F') {
-            return hex - 'A' + 10;
-        } else if (hex >= 'a' && hex <= 'f') {
-            return hex - 'a' + 10;
-        } else {
-            return -1;
-        }
+  }
+
+  /**
+   * Unreads the most recent character of input. If no input characters have been read, the input is
+   * unchanged.
+   */
+  public void back() {
+    if (--pos == -1) {
+      pos = 0;
+    }
+  }
+
+  /**
+   * Returns the integer [0..15] value for the given hex character, or -1 for non-hex input.
+   *
+   * @param hex a character in the ranges [0-9], [A-F] or [a-f]. Any other character will yield a -1
+   *        result.
+   * @return The decoded integer.
+   */
+  public static int dehexchar(char hex) {
+    if (hex >= '0' && hex <= '9') {
+      return hex - '0';
+    } else if (hex >= 'A' && hex <= 'F') {
+      return hex - 'A' + 10;
+    } else if (hex >= 'a' && hex <= 'f') {
+      return hex - 'a' + 10;
+    } else {
+      return -1;
     }
+  }
 }


[2/8] geode git commit: GEODE-2142: Removal of non-compliant org.json implementation.

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/JSONStringer.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONStringer.java b/geode-json/src/main/java/org/json/JSONStringer.java
index 234e174..db1121e 100755
--- a/geode-json/src/main/java/org/json/JSONStringer.java
+++ b/geode-json/src/main/java/org/json/JSONStringer.java
@@ -1,75 +1,470 @@
-package org.json;
-
 /*
- * Copyright (c) 2006 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
  */
 
-import java.io.StringWriter;
+package org.json;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
 
 /**
- * JSONStringer provides a quick and convenient way of producing JSON text. The texts produced
- * strictly conform to JSON syntax rules. No whitespace is added, so the results are ready for
- * transmission or storage. Each instance of JSONStringer can produce one JSON text.
- * <p>
- * A JSONStringer instance provides a <code>value</code> method for appending values to the text,
- * and a <code>key</code> method for adding keys before values in objects. There are
- * <code>array</code> and <code>endArray</code> methods that make and bound array values, and
- * <code>object</code> and <code>endObject</code> methods which make and bound object values. All of
- * these methods return the JSONWriter instance, permitting cascade style. For example,
- * 
- * <pre>
- * myString = new JSONStringer().object().key("JSON").value("Hello, World!").endObject().toString();
- * </pre>
- * 
- * which produces the string
- * 
- * <pre>
- * {"JSON":"Hello, World!"}
- * </pre>
- * <p>
- * The first method called must be <code>array</code> or <code>object</code>. There are no methods
- * for adding commas or colons. JSONStringer adds them for you. Objects and arrays can be nested up
- * to 20 levels deep.
- * <p>
- * This can sometimes be easier than using a JSONObject to build a string.
- * 
- * @author JSON.org
- * @version 2008-09-18
+ * Implements {@link JSONObject#toString} and {@link JSONArray#toString}. Most
+ * application developers should use those methods directly and disregard this
+ * API. For example:<pre>
+ * JSONObject object = ...
+ * String json = object.toString();</pre>
+ *
+ * <p>Stringers only encode well-formed JSON strings. In particular:
+ * <ul>
+ * <li>The stringer must have exactly one top-level array or object.
+ * <li>Lexical scopes must be balanced: every call to {@link #array} must
+ * have a matching call to {@link #endArray} and every call to {@link
+ * #object} must have a matching call to {@link #endObject}.
+ * <li>Arrays may not contain keys (property names).
+ * <li>Objects must alternate keys (property names) and values.
+ * <li>Values are inserted with either literal {@link #value(Object) value}
+ * calls, or by nesting arrays or objects.
+ * </ul>
+ * Calls that would result in a malformed JSON string will fail with a
+ * {@link JSONException}.
+ *
+ * <p>This class provides no facility for pretty-printing (ie. indenting)
+ * output. To encode indented output, use {@link JSONObject#toString(int)} or
+ * {@link JSONArray#toString(int)}.
+ *
+ * <p>Some implementations of the API support at most 20 levels of nesting.
+ * Attempts to create more than 20 levels of nesting may fail with a {@link
+ * JSONException}.
+ *
+ * <p>Each stringer may be used to encode a single top level value. Instances of
+ * this class are not thread safe. Although this class is nonfinal, it was not
+ * designed for inheritance and should not be subclassed. In particular,
+ * self-use by overrideable methods is not specified. See <i>Effective Java</i>
+ * Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * information.
  */
-public class JSONStringer extends JSONWriter {
-  /**
-   * Make a fresh JSONStringer. It can be used to build one JSON text.
-   */
-  public JSONStringer() {
-    super(new StringWriter());
-  }
-
-  /**
-   * Return the JSON text. This method is used to obtain the product of the JSONStringer instance.
-   * It will return <code>null</code> if there was a problem in the construction of the JSON text
-   * (such as the calls to <code>array</code> were not properly balanced with calls to
-   * <code>endArray</code>).
-   * 
-   * @return The JSON text.
-   */
-  public String toString() {
-    return this.mode == 'd' ? this.writer.toString() : null;
-  }
+public class JSONStringer {
+
+    /**
+     * The output data, containing at most one top-level array or object.
+     */
+    final StringBuilder out = new StringBuilder();
+
+    /**
+     * Lexical scoping elements within this stringer, necessary to insert the
+     * appropriate separator characters (ie. commas and colons) and to detect
+     * nesting errors.
+     */
+    enum Scope {
+
+        /**
+         * An array with no elements requires no separators or newlines before
+         * it is closed.
+         */
+        EMPTY_ARRAY,
+
+        /**
+         * A array with at least one value requires a comma and newline before
+         * the next element.
+         */
+        NONEMPTY_ARRAY,
+
+        /**
+         * An object with no keys or values requires no separators or newlines
+         * before it is closed.
+         */
+        EMPTY_OBJECT,
+
+        /**
+         * An object whose most recent element is a key. The next element must
+         * be a value.
+         */
+        DANGLING_KEY,
+
+        /**
+         * An object with at least one name/value pair requires a comma and
+         * newline before the next element.
+         */
+        NONEMPTY_OBJECT,
+
+        /**
+         * A special bracketless array needed by JSONStringer.join() and
+         * JSONObject.quote() only. Not used for JSON encoding.
+         */
+        NULL,
+    }
+
+    /**
+     * Unlike the original implementation, this stack isn't limited to 20
+     * levels of nesting.
+     */
+    private final List<Scope> stack = new ArrayList<Scope>();
+
+    /**
+     * A string containing a full set of spaces for a single level of
+     * indentation, or null for no pretty printing.
+     */
+    private final String indent;
+
+    public JSONStringer() {
+        indent = null;
+    }
+
+    JSONStringer(int indentSpaces) {
+        char[] indentChars = new char[indentSpaces];
+        Arrays.fill(indentChars, ' ');
+        indent = new String(indentChars);
+    }
+
+    /**
+     * Begins encoding a new array. Each call to this method must be paired with
+     * a call to {@link #endArray}.
+     *
+     * @return this stringer.
+     * @throws JSONException On internal errors. Shouldn't happen.
+     */
+    public JSONStringer array() throws JSONException {
+        return open(Scope.EMPTY_ARRAY, "[");
+    }
+
+    /**
+     * Ends encoding the current array.
+     *
+     * @return this stringer.
+     * @throws JSONException On internal errors. Shouldn't happen.
+     */
+    public JSONStringer endArray() throws JSONException {
+        return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]");
+    }
+
+    /**
+     * Begins encoding a new object. Each call to this method must be paired
+     * with a call to {@link #endObject}.
+     *
+     * @return this stringer.
+     * @throws JSONException On internal errors. Shouldn't happen.
+     */
+    public JSONStringer object() throws JSONException {
+        return open(Scope.EMPTY_OBJECT, "{");
+    }
+
+    /**
+     * Ends encoding the current object.
+     *
+     * @return this stringer.
+     * @throws JSONException On internal errors. Shouldn't happen.
+     */
+    public JSONStringer endObject() throws JSONException {
+        return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}");
+    }
+
+    /**
+     * Enters a new scope by appending any necessary whitespace and the given
+     * bracket.
+     */
+    JSONStringer open(Scope empty, String openBracket) throws JSONException {
+        if (stack.isEmpty() && out.length() > 0) {
+            throw new JSONException("Nesting problem: multiple top-level roots");
+        }
+        beforeValue();
+        stack.add(empty);
+        out.append(openBracket);
+        return this;
+    }
+
+    /**
+     * Closes the current scope by appending any necessary whitespace and the
+     * given bracket.
+     */
+    JSONStringer close(Scope empty, Scope nonempty, String closeBracket) throws JSONException {
+        Scope context = peek();
+        if (context != nonempty && context != empty) {
+            throw new JSONException("Nesting problem");
+        }
+
+        stack.remove(stack.size() - 1);
+        if (context == nonempty) {
+            newline();
+        }
+        out.append(closeBracket);
+        return this;
+    }
+
+    /**
+     * Returns the value on the top of the stack.
+     */
+    private Scope peek() throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        return stack.get(stack.size() - 1);
+    }
+
+    /**
+     * Replace the value on the top of the stack with the given value.
+     */
+    private void replaceTop(Scope topOfStack) {
+        stack.set(stack.size() - 1, topOfStack);
+    }
+
+    /**
+     * Encodes {@code value}.
+     *
+     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     *              Integer, Long, Double or null. May not be {@link Double#isNaN() NaNs}
+     *              or {@link Double#isInfinite() infinities}.
+     * @return this stringer.
+     * @throws JSONException On internal errors. Shouldn't happen.
+     */
+    public JSONStringer value(Object value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+
+        if (value instanceof JSONArray) {
+            ((JSONArray) value).writeTo(this);
+            return this;
+
+        } else if (value instanceof JSONObject) {
+            ((JSONObject) value).writeTo(this);
+            return this;
+        }
+
+        beforeValue();
+
+        if (value instanceof JSONString) {
+          out.append(((JSONString) value).toJSONString());
+          return this;
+        }
+
+        if (value == null
+              || value instanceof Boolean
+              || value == JSONObject.NULL) {
+            out.append(value);
+
+        } else if (value instanceof Number) {
+            out.append(JSONObject.numberToString((Number) value));
+
+        } else {
+            // Hack to make it possible that the value is not surrounded by quotes. (Used for JavaScript function calls)
+            // Example: { "name": "testkey", "value": window.myfunction() }
+            if (value.getClass().getSimpleName().contains("JSONFunction")) {
+                // note that no escaping of quotes (or anything else) is done in this case.
+                // that is fine because the only way to get to this point is to
+                // explicitly put a special kind of object into the JSON data structure.
+                out.append(value);
+            } else {
+                string(value.toString());
+            }
+        }
+
+        return this;
+    }
+
+    /**
+     * Encodes {@code value} to this stringer.
+     *
+     * @param value The value to encode.
+     * @return this stringer.
+     * @throws JSONException On internal errors. Shouldn't happen.
+     */
+    public JSONStringer value(boolean value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        beforeValue();
+        out.append(value);
+        return this;
+    }
+
+    /**
+     * Encodes {@code value} to this stringer.
+     *
+     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+     *              {@link Double#isInfinite() infinities}.
+     * @return this stringer.
+     * @throws JSONException On internal errors. Shouldn't happen.
+     */
+    public JSONStringer value(double value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        beforeValue();
+        out.append(JSONObject.numberToString(value));
+        return this;
+    }
+
+    /**
+     * Encodes {@code value} to this stringer.
+     *
+     * @param value The value to encode.
+     * @return this stringer.
+     * @throws JSONException If we have an internal error. Shouldn't happen.
+     */
+    public JSONStringer value(long value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        beforeValue();
+        out.append(value);
+        return this;
+    }
+
+    private void string(String value) {
+        out.append("\"");
+        char currentChar = 0;
+
+        for (int i = 0, length = value.length(); i < length; i++) {
+            char previousChar = currentChar;
+            currentChar = value.charAt(i);
+
+            /*
+             * From RFC 4627, "All Unicode characters may be placed within the
+             * quotation marks except for the characters that must be escaped:
+             * quotation mark, reverse solidus, and the control characters
+             * (U+0000 through U+001F)."
+             */
+            switch (currentChar) {
+                case '"':
+                case '\\':
+                    out.append('\\').append(currentChar);
+                    break;
+
+                case '/':
+                    // it makes life easier for HTML embedding of javascript if we escape </ sequences
+                    if (previousChar == '<') {
+                        out.append('\\');
+                    }
+                    out.append(currentChar);
+                    break;
+
+                case '\t':
+                    out.append("\\t");
+                    break;
+
+                case '\b':
+                    out.append("\\b");
+                    break;
+
+                case '\n':
+                    out.append("\\n");
+                    break;
+
+                case '\r':
+                    out.append("\\r");
+                    break;
+
+                case '\f':
+                    out.append("\\f");
+                    break;
+
+                default:
+                    if (currentChar <= 0x1F) {
+                        out.append(String.format("\\u%04x", (int) currentChar));
+                    } else {
+                        out.append(currentChar);
+                    }
+                    break;
+            }
+
+        }
+        out.append("\"");
+    }
+
+    private void newline() {
+        if (indent == null) {
+            return;
+        }
+
+        out.append("\n");
+        for (int i = 0; i < stack.size(); i++) {
+            out.append(indent);
+        }
+    }
+
+    /**
+     * Encodes the key (property name) to this stringer.
+     *
+     * @param name the name of the forthcoming value. May not be null.
+     * @return this stringer.
+     * @throws JSONException on internal errors, shouldn't happen.
+     */
+    public JSONStringer key(String name) throws JSONException {
+        if (name == null) {
+            throw new JSONException("Names must be non-null");
+        }
+        beforeKey();
+        string(name);
+        return this;
+    }
+
+    /**
+     * Inserts any necessary separators and whitespace before a name. Also
+     * adjusts the stack to expect the key's value.
+     */
+    private void beforeKey() throws JSONException {
+        Scope context = peek();
+        if (context == Scope.NONEMPTY_OBJECT) { // first in object
+            out.append(',');
+        } else if (context != Scope.EMPTY_OBJECT) { // not in an object!
+            throw new JSONException("Nesting problem");
+        }
+        newline();
+        replaceTop(Scope.DANGLING_KEY);
+    }
+
+    /**
+     * Inserts any necessary separators and whitespace before a literal value,
+     * inline array, or inline object. Also adjusts the stack to expect either a
+     * closing bracket or another element.
+     */
+    private void beforeValue() throws JSONException {
+        if (stack.isEmpty()) {
+            return;
+        }
+
+        Scope context = peek();
+        if (context == Scope.EMPTY_ARRAY) { // first in array
+            replaceTop(Scope.NONEMPTY_ARRAY);
+            newline();
+        } else if (context == Scope.NONEMPTY_ARRAY) { // another in array
+            out.append(',');
+            newline();
+        } else if (context == Scope.DANGLING_KEY) { // value for key
+            out.append(indent == null ? ":" : ": ");
+            replaceTop(Scope.NONEMPTY_OBJECT);
+        } else if (context != Scope.NULL) {
+            throw new JSONException("Nesting problem");
+        }
+    }
+
+    /**
+     * Returns the encoded JSON string.
+     *
+     * <p>If invoked with unterminated arrays or unclosed objects, this method's
+     * return value is undefined.
+     *
+     * <p><strong>Warning:</strong> although it contradicts the general contract
+     * of {@link Object#toString}, this method returns null if the stringer
+     * contains no data.
+     */
+    @Override
+    public String toString() {
+        return out.length() == 0 ? null : out.toString();
+    }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/JSONTokener.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONTokener.java b/geode-json/src/main/java/org/json/JSONTokener.java
old mode 100644
new mode 100755
index 4dd2ba2..59eb4bc
--- a/geode-json/src/main/java/org/json/JSONTokener.java
+++ b/geode-json/src/main/java/org/json/JSONTokener.java
@@ -1,437 +1,658 @@
+/*
+ * 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.json;
 
-import java.io.BufferedReader;
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.io.Reader;
-import java.io.StringReader;
-
-/*
- * Copyright (c) 2002 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
 
 /**
- * A JSONTokener takes a source string and extracts characters and tokens from it. It is used by the
- * JSONObject and JSONArray constructors to parse JSON source strings.
- * 
- * @author JSON.org
- * @version 2012-02-16
+ * Parses a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>)
+ * encoded string into the corresponding object. Most clients of
+ * this class will use only need the {@link #JSONTokener(String) constructor}
+ * and {@link #nextValue} method. Example usage: <pre>
+ * String json = "{"
+ *         + "  \"query\": \"Pizza\", "
+ *         + "  \"locations\": [ 94043, 90210 ] "
+ *         + "}";
+ *
+ * JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
+ * String query = object.getString("query");
+ * JSONArray locations = object.getJSONArray("locations");</pre>
+ *
+ * <p>For best interoperability and performance use JSON that complies with
+ * RFC 4627, such as that generated by {@link JSONStringer}. For legacy reasons
+ * this parser is lenient, so a successful parse does not indicate that the
+ * input string was valid JSON. All of the following syntax errors will be
+ * ignored:
+ * <ul>
+ * <li>End of line comments starting with {@code //} or {@code #} and ending
+ * with a newline character.
+ * <li>C-style comments starting with {@code /*} and ending with
+ * {@code *}{@code /}. Such comments may not be nested.
+ * <li>Strings that are unquoted or {@code 'single quoted'}.
+ * <li>Hexadecimal integers prefixed with {@code 0x} or {@code 0X}.
+ * <li>Octal integers prefixed with {@code 0}.
+ * <li>Array elements separated by {@code ;}.
+ * <li>Unnecessary array separators. These are interpreted as if null was the
+ * omitted value.
+ * <li>Key-value pairs separated by {@code =} or {@code =>}.
+ * <li>Key-value pairs separated by {@code ;}.
+ * </ul>
+ *
+ * <p>Each tokener may be used to parse a single JSON string. Instances of this
+ * class are not thread safe. Although this class is nonfinal, it was not
+ * designed for inheritance and should not be subclassed. In particular,
+ * self-use by overrideable methods is not specified. See <i>Effective Java</i>
+ * Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * information.
  */
 public class JSONTokener {
 
-  private long character;
-  private boolean eof;
-  private long index;
-  private long line;
-  private char previous;
-  private Reader reader;
-  private boolean usePrevious;
-
-
-  /**
-   * Construct a JSONTokener from a Reader.
-   *
-   * @param reader A reader.
-   */
-  public JSONTokener(Reader reader) {
-    this.reader = reader.markSupported() ? reader : new BufferedReader(reader);
-    this.eof = false;
-    this.usePrevious = false;
-    this.previous = 0;
-    this.index = 0;
-    this.character = 1;
-    this.line = 1;
-  }
-
-
-  /**
-   * Construct a JSONTokener from an InputStream.
-   */
-  public JSONTokener(InputStream inputStream) throws JSONException {
-    this(new InputStreamReader(inputStream));
-  }
-
-
-  /**
-   * Construct a JSONTokener from a string.
-   *
-   * @param s A source string.
-   */
-  public JSONTokener(String s) {
-    this(new StringReader(s));
-  }
-
-
-  /**
-   * Back up one character. This provides a sort of lookahead capability, so that you can test for a
-   * digit or letter before attempting to parse the next number or identifier.
-   */
-  public void back() throws JSONException {
-    if (this.usePrevious || this.index <= 0) {
-      throw new JSONException("Stepping back two steps is not supported");
-    }
-    this.index -= 1;
-    this.character -= 1;
-    this.usePrevious = true;
-    this.eof = false;
-  }
-
-
-  /**
-   * Get the hex value of a character (base16).
-   * 
-   * @param c A character between '0' and '9' or between 'A' and 'F' or between 'a' and 'f'.
-   * @return An int between 0 and 15, or -1 if c was not a hex digit.
-   */
-  public static int dehexchar(char c) {
-    if (c >= '0' && c <= '9') {
-      return c - '0';
-    }
-    if (c >= 'A' && c <= 'F') {
-      return c - ('A' - 10);
-    }
-    if (c >= 'a' && c <= 'f') {
-      return c - ('a' - 10);
-    }
-    return -1;
-  }
-
-  public boolean end() {
-    return this.eof && !this.usePrevious;
-  }
-
-
-  /**
-   * Determine if the source string still contains characters that next() can consume.
-   * 
-   * @return true if not yet at the end of the source.
-   */
-  public boolean more() throws JSONException {
-    this.next();
-    if (this.end()) {
-      return false;
+    /**
+     * The input JSON.
+     */
+    private final String in;
+
+    /**
+     * The index of the next character to be returned by {@link #next}. When
+     * the input is exhausted, this equals the input's length.
+     */
+    private int pos;
+
+    /**
+     * @param in JSON encoded string. Null is not permitted and will yield a
+     *           tokener that throws {@code NullPointerExceptions} when methods are
+     *           called.
+     */
+    public JSONTokener(String in) {
+        // consume an optional byte order mark (BOM) if it exists
+        if (in != null && in.startsWith("\ufeff")) {
+            in = in.substring(1);
+        }
+        this.in = in;
     }
-    this.back();
-    return true;
-  }
-
-
-  /**
-   * Get the next character in the source string.
-   *
-   * @return The next character, or 0 if past the end of the source string.
-   */
-  public char next() throws JSONException {
-    int c;
-    if (this.usePrevious) {
-      this.usePrevious = false;
-      c = this.previous;
-    } else {
-      try {
-        c = this.reader.read();
-      } catch (IOException exception) {
-        throw new JSONException(exception);
-      }
-
-      if (c <= 0) { // End of stream
-        this.eof = true;
-        c = 0;
-      }
+
+    public JSONTokener(Reader input) throws IOException {
+        StringBuilder s = new StringBuilder();
+        char[] readBuf = new char[102400];
+        int n = input.read(readBuf);
+        while (n >= 0) {
+            s.append(readBuf, 0, n);
+            n = input.read(readBuf);
+        }
+        in = s.toString();
+        pos = 0;
     }
-    this.index += 1;
-    if (this.previous == '\r') {
-      this.line += 1;
-      this.character = c == '\n' ? 0 : 1;
-    } else if (c == '\n') {
-      this.line += 1;
-      this.character = 0;
-    } else {
-      this.character += 1;
+
+    /**
+     * Returns the next value from the input.
+     *
+     * @return a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     * Integer, Long, Double or {@link JSONObject#NULL}.
+     * @throws JSONException if the input is malformed.
+     */
+    public Object nextValue() throws JSONException {
+        int c = nextCleanInternal();
+        switch (c) {
+            case -1:
+                throw syntaxError("End of input");
+
+            case '{':
+                return readObject();
+
+            case '[':
+                return readArray();
+
+            case '\'':
+            case '"':
+                return nextString((char) c);
+
+            default:
+                pos--;
+                return readLiteral();
+        }
     }
-    this.previous = (char) c;
-    return this.previous;
-  }
-
-
-  /**
-   * Consume the next character, and check that it matches a specified character.
-   * 
-   * @param c The character to match.
-   * @return The character.
-   * @throws JSONException if the character does not match.
-   */
-  public char next(char c) throws JSONException {
-    char n = this.next();
-    if (n != c) {
-      throw this.syntaxError("Expected '" + c + "' and instead saw '" + n + "'");
+
+    private int nextCleanInternal() throws JSONException {
+        while (pos < in.length()) {
+            int c = in.charAt(pos++);
+            switch (c) {
+                case '\t':
+                case ' ':
+                case '\n':
+                case '\r':
+                    continue;
+
+                case '/':
+                    if (pos == in.length()) {
+                        return c;
+                    }
+
+                    char peek = in.charAt(pos);
+                    switch (peek) {
+                        case '*':
+                            // skip a /* c-style comment */
+                            pos++;
+                            int commentEnd = in.indexOf("*/", pos);
+                            if (commentEnd == -1) {
+                                throw syntaxError("Unterminated comment");
+                            }
+                            pos = commentEnd + 2;
+                            continue;
+
+                        case '/':
+                            // skip a // end-of-line comment
+                            pos++;
+                            skipToEndOfLine();
+                            continue;
+
+                        default:
+                            return c;
+                    }
+
+                case '#':
+                    /*
+                     * Skip a # hash end-of-line comment. The JSON RFC doesn't
+                     * specify this behavior, but it's required to parse
+                     * existing documents. See http://b/2571423.
+                     */
+                    skipToEndOfLine();
+                    continue;
+
+                default:
+                    return c;
+            }
+        }
+
+        return -1;
     }
-    return n;
-  }
-
-
-  /**
-   * Get the next n characters.
-   *
-   * @param n The number of characters to take.
-   * @return A string of n characters.
-   * @throws JSONException Substring bounds error if there are not n characters remaining in the
-   *         source string.
-   */
-  public String next(int n) throws JSONException {
-    if (n == 0) {
-      return "";
+
+    /**
+     * Advances the position until after the next newline character. If the line
+     * is terminated by "\r\n", the '\n' must be consumed as whitespace by the
+     * caller.
+     */
+    private void skipToEndOfLine() {
+        for (; pos < in.length(); pos++) {
+            char c = in.charAt(pos);
+            if (c == '\r' || c == '\n') {
+                pos++;
+                break;
+            }
+        }
     }
 
-    char[] chars = new char[n];
-    int pos = 0;
+    /**
+     * Returns the string up to but not including {@code quote}, unescaping any
+     * character escape sequences encountered along the way. The opening quote
+     * should have already been read. This consumes the closing quote, but does
+     * not include it in the returned string.
+     *
+     * @param quote either ' or ".
+     * @return The unescaped string.
+     * @throws JSONException if the string isn't terminated by a closing quote correctly.
+     */
+    public String nextString(char quote) throws JSONException {
+        /*
+         * For strings that are free of escape sequences, we can just extract
+         * the result as a substring of the input. But if we encounter an escape
+         * sequence, we need to use a StringBuilder to compose the result.
+         */
+        StringBuilder builder = null;
+
+        /* the index of the first character not yet appended to the builder. */
+        int start = pos;
+
+        while (pos < in.length()) {
+            int c = in.charAt(pos++);
+            if (c == quote) {
+                if (builder == null) {
+                    // a new string avoids leaking memory
+                    //noinspection RedundantStringConstructorCall
+                    return new String(in.substring(start, pos - 1));
+                } else {
+                    builder.append(in, start, pos - 1);
+                    return builder.toString();
+                }
+            }
+
+            if (c == '\\') {
+                if (pos == in.length()) {
+                    throw syntaxError("Unterminated escape sequence");
+                }
+                if (builder == null) {
+                    builder = new StringBuilder();
+                }
+                builder.append(in, start, pos - 1);
+                builder.append(readEscapeCharacter());
+                start = pos;
+            }
+        }
 
-    while (pos < n) {
-      chars[pos] = this.next();
-      if (this.end()) {
-        throw this.syntaxError("Substring bounds error");
-      }
-      pos += 1;
-    }
-    return new String(chars);
-  }
-
-
-  /**
-   * Get the next char in the string, skipping whitespace.
-   * 
-   * @throws JSONException
-   * @return A character, or 0 if there are no more characters.
-   */
-  public char nextClean() throws JSONException {
-    for (;;) {
-      char c = this.next();
-      if (c == 0 || c > ' ') {
-        return c;
-      }
+        throw syntaxError("Unterminated string");
     }
-  }
-
-
-  /**
-   * Return the characters up to the next close quote character. Backslash processing is done. The
-   * formal JSON format does not allow strings in single quotes, but an implementation is allowed to
-   * accept them.
-   * 
-   * @param quote The quoting character, either <code>"</code>&nbsp;<small>(double quote)</small> or
-   *        <code>'</code>&nbsp;<small>(single quote)</small>.
-   * @return A String.
-   * @throws JSONException Unterminated string.
-   */
-  public String nextString(char quote) throws JSONException {
-    char c;
-    StringBuffer sb = new StringBuffer();
-    for (;;) {
-      c = this.next();
-      switch (c) {
-        case 0:
-        case '\n':
-        case '\r':
-          throw this.syntaxError("Unterminated string");
-        case '\\':
-          c = this.next();
-          switch (c) {
-            case 'b':
-              sb.append('\b');
-              break;
+
+    /**
+     * Unescapes the character identified by the character or characters that
+     * immediately follow a backslash. The backslash '\' should have already
+     * been read. This supports both unicode escapes "u000A" and two-character
+     * escapes "\n".
+     */
+    private char readEscapeCharacter() throws JSONException {
+        char escaped = in.charAt(pos++);
+        switch (escaped) {
+            case 'u':
+                if (pos + 4 > in.length()) {
+                    throw syntaxError("Unterminated escape sequence");
+                }
+                String hex = in.substring(pos, pos + 4);
+                pos += 4;
+                try {
+                    return (char) Integer.parseInt(hex, 16);
+                } catch (NumberFormatException nfe) {
+                    throw syntaxError("Invalid escape sequence: " + hex);
+                }
+
             case 't':
-              sb.append('\t');
-              break;
+                return '\t';
+
+            case 'b':
+                return '\b';
+
             case 'n':
-              sb.append('\n');
-              break;
-            case 'f':
-              sb.append('\f');
-              break;
+                return '\n';
+
             case 'r':
-              sb.append('\r');
-              break;
-            case 'u':
-              sb.append((char) Integer.parseInt(this.next(4), 16));
-              break;
-            case '"':
+                return '\r';
+
+            case 'f':
+                return '\f';
+
             case '\'':
+            case '"':
             case '\\':
-            case '/':
-              sb.append(c);
-              break;
             default:
-              throw this.syntaxError("Illegal escape.");
-          }
-          break;
-        default:
-          if (c == quote) {
-            return sb.toString();
-          }
-          sb.append(c);
-      }
+                return escaped;
+        }
+    }
+
+    /**
+     * Reads a null, boolean, numeric or unquoted string literal value. Numeric
+     * values will be returned as an Integer, Long, or Double, in that order of
+     * preference.
+     */
+    private Object readLiteral() throws JSONException {
+        String literal = nextToInternal("{}[]/\\:,=;# \t\f");
+
+        if (literal.length() == 0) {
+            throw syntaxError("Expected literal value");
+        } else if ("null".equalsIgnoreCase(literal)) {
+            return JSONObject.NULL;
+        } else if ("true".equalsIgnoreCase(literal)) {
+            return Boolean.TRUE;
+        } else if ("false".equalsIgnoreCase(literal)) {
+            return Boolean.FALSE;
+        }
+
+        /* try to parse as an integral type... */
+        if (literal.indexOf('.') == -1) {
+            int base = 10;
+            String number = literal;
+            if (number.startsWith("0x") || number.startsWith("0X")) {
+                number = number.substring(2);
+                base = 16;
+            } else if (number.startsWith("0") && number.length() > 1) {
+                number = number.substring(1);
+                base = 8;
+            }
+            try {
+                long longValue = Long.parseLong(number, base);
+                if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
+                    return (int) longValue;
+                } else {
+                    return longValue;
+                }
+            } catch (NumberFormatException e) {
+                /*
+                 * This only happens for integral numbers greater than
+                 * Long.MAX_VALUE, numbers in exponential form (5e-10) and
+                 * unquoted strings. Fall through to try floating point.
+                 */
+            }
+        }
+
+        /* ...next try to parse as a floating point... */
+        try {
+            return Double.valueOf(literal);
+        } catch (NumberFormatException ignored) {
+        }
+
+        /* ... finally give up. We have an unquoted string */
+        //noinspection RedundantStringConstructorCall
+        return new String(literal); // a new string avoids leaking memory
+    }
+
+    /**
+     * Returns the string up to but not including any of the given characters or
+     * a newline character. This does not consume the excluded character.
+     */
+    private String nextToInternal(String excluded) {
+        int start = pos;
+        for (; pos < in.length(); pos++) {
+            char c = in.charAt(pos);
+            if (c == '\r' || c == '\n' || excluded.indexOf(c) != -1) {
+                return in.substring(start, pos);
+            }
+        }
+        return in.substring(start);
     }
-  }
-
-
-  /**
-   * Get the text up but not including the specified character or the end of line, whichever comes
-   * first.
-   * 
-   * @param delimiter A delimiter character.
-   * @return A string.
-   */
-  public String nextTo(char delimiter) throws JSONException {
-    StringBuffer sb = new StringBuffer();
-    for (;;) {
-      char c = this.next();
-      if (c == delimiter || c == 0 || c == '\n' || c == '\r') {
-        if (c != 0) {
-          this.back();
+
+    /**
+     * Reads a sequence of key/value pairs and the trailing closing brace '}' of
+     * an object. The opening brace '{' should have already been read.
+     */
+    private JSONObject readObject() throws JSONException {
+        JSONObject result = new JSONObject();
+
+        /* Peek to see if this is the empty object. */
+        int first = nextCleanInternal();
+        if (first == '}') {
+            return result;
+        } else if (first != -1) {
+            pos--;
+        }
+
+        while (true) {
+            Object name = nextValue();
+            if (!(name instanceof String)) {
+                if (name == null) {
+                    throw syntaxError("Names cannot be null");
+                } else {
+                    throw syntaxError("Names must be strings, but " + name
+                            + " is of type " + name.getClass().getName());
+                }
+            }
+
+            /*
+             * Expect the name/value separator to be either a colon ':', an
+             * equals sign '=', or an arrow "=>". The last two are bogus but we
+             * include them because that's what the original implementation did.
+             */
+            int separator = nextCleanInternal();
+            if (separator != ':' && separator != '=') {
+                throw syntaxError("Expected ':' after " + name);
+            }
+            if (pos < in.length() && in.charAt(pos) == '>') {
+                pos++;
+            }
+
+            result.put((String) name, nextValue());
+
+            switch (nextCleanInternal()) {
+                case '}':
+                    return result;
+                case ';':
+                case ',':
+                    continue;
+                default:
+                    throw syntaxError("Unterminated object");
+            }
         }
-        return sb.toString().trim();
-      }
-      sb.append(c);
     }
-  }
-
-
-  /**
-   * Get the text up but not including one of the specified delimiter characters or the end of line,
-   * whichever comes first.
-   * 
-   * @param delimiters A set of delimiter characters.
-   * @return A string, trimmed.
-   */
-  public String nextTo(String delimiters) throws JSONException {
-    char c;
-    StringBuffer sb = new StringBuffer();
-    for (;;) {
-      c = this.next();
-      if (delimiters.indexOf(c) >= 0 || c == 0 || c == '\n' || c == '\r') {
-        if (c != 0) {
-          this.back();
+
+    /**
+     * Reads a sequence of values and the trailing closing brace ']' of an
+     * array. The opening brace '[' should have already been read. Note that
+     * "[]" yields an empty array, but "[,]" returns a two-element array
+     * equivalent to "[null,null]".
+     */
+    private JSONArray readArray() throws JSONException {
+        JSONArray result = new JSONArray();
+
+        /* to cover input that ends with ",]". */
+        boolean hasTrailingSeparator = false;
+
+        while (true) {
+            switch (nextCleanInternal()) {
+                case -1:
+                    throw syntaxError("Unterminated array");
+                case ']':
+                    if (hasTrailingSeparator) {
+                        result.put(null);
+                    }
+                    return result;
+                case ',':
+                case ';':
+                    /* A separator without a value first means "null". */
+                    result.put(null);
+                    hasTrailingSeparator = true;
+                    continue;
+                default:
+                    pos--;
+            }
+
+            result.put(nextValue());
+
+            switch (nextCleanInternal()) {
+                case ']':
+                    return result;
+                case ',':
+                case ';':
+                    hasTrailingSeparator = true;
+                    continue;
+                default:
+                    throw syntaxError("Unterminated array");
+            }
         }
-        return sb.toString().trim();
-      }
-      sb.append(c);
     }
-  }
-
-
-  /**
-   * Get the next value. The value can be a Boolean, Double, Integer, JSONArray, JSONObject, Long,
-   * or String, or the JSONObject.NULL object.
-   * 
-   * @throws JSONException If syntax error.
-   *
-   * @return An object.
-   */
-  public Object nextValue() throws JSONException {
-    char c = this.nextClean();
-    String string;
-
-    switch (c) {
-      case '"':
-      case '\'':
-        return this.nextString(c);
-      case '{':
-        this.back();
-        return new JSONObject(this);
-      case '[':
-        this.back();
-        return new JSONArray(this);
+
+    /**
+     * Returns an exception containing the given message plus the current
+     * position and the entire input string.
+     *
+     * @param message The message we want to include.
+     * @return An exception that we can throw.
+     */
+    public JSONException syntaxError(String message) {
+        return new JSONException(message + this);
+    }
+
+    /**
+     * Returns the current position and the entire input string.
+     */
+    @Override
+    public String toString() {
+        // consistent with the original implementation
+        return " at character " + pos + " of " + in;
     }
 
     /*
-     * Handle unquoted text. This could be the values true, false, or null, or it can be a number.
-     * An implementation (such as this one) is allowed to also accept non-standard forms.
+     * Legacy APIs.
      *
-     * Accumulate characters until we reach the end of the text or a formatting character.
+     * None of the methods below are on the critical path of parsing JSON
+     * documents. They exist only because they were exposed by the original
+     * implementation and may be used by some clients.
      */
 
-    StringBuffer sb = new StringBuffer();
-    while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
-      sb.append(c);
-      c = this.next();
+    /**
+     * Returns true until the input has been exhausted.
+     *
+     * @return true if more input exists.
+     */
+    public boolean more() {
+        return pos < in.length();
     }
-    this.back();
 
-    string = sb.toString().trim();
-    if ("".equals(string)) {
-      throw this.syntaxError("Missing value");
+    /**
+     * Returns the next available character, or the null character '\0' if all
+     * input has been exhausted. The return value of this method is ambiguous
+     * for JSON strings that contain the character '\0'.
+     *
+     * @return the next character.
+     */
+    public char next() {
+        return pos < in.length() ? in.charAt(pos++) : '\0';
     }
-    return JSONObject.stringToValue(string);
-  }
-
-
-  /**
-   * Skip characters until the next character is the requested character. If the requested character
-   * is not found, no characters are skipped.
-   * 
-   * @param to A character to skip to.
-   * @return The requested character, or zero if the requested character is not found.
-   */
-  public char skipTo(char to) throws JSONException {
-    char c;
-    try {
-      long startIndex = this.index;
-      long startCharacter = this.character;
-      long startLine = this.line;
-      this.reader.mark(1000000);
-      do {
-        c = this.next();
-        if (c == 0) {
-          this.reader.reset();
-          this.index = startIndex;
-          this.character = startCharacter;
-          this.line = startLine;
-          return c;
+
+    /**
+     * Returns the next available character if it equals {@code c}. Otherwise an
+     * exception is thrown.
+     *
+     * @param c The character we are looking for.
+     * @return the next character.
+     * @throws JSONException If the next character isn't {@code c}
+     */
+    public char next(char c) throws JSONException {
+        char result = next();
+        if (result != c) {
+            throw syntaxError("Expected " + c + " but was " + result);
         }
-      } while (c != to);
-    } catch (IOException exc) {
-      throw new JSONException(exc);
+        return result;
+    }
+
+    /**
+     * Returns the next character that is not whitespace and does not belong to
+     * a comment. If the input is exhausted before such a character can be
+     * found, the null character '\0' is returned. The return value of this
+     * method is ambiguous for JSON strings that contain the character '\0'.
+     *
+     * @return The next non-whitespace character.
+     * @throws JSONException Should not be possible.
+     */
+    public char nextClean() throws JSONException {
+        int nextCleanInt = nextCleanInternal();
+        return nextCleanInt == -1 ? '\0' : (char) nextCleanInt;
     }
 
-    this.back();
-    return c;
-  }
-
-
-  /**
-   * Make a JSONException to signal a syntax error.
-   *
-   * @param message The error message.
-   * @return A JSONException object, suitable for throwing
-   */
-  public JSONException syntaxError(String message) {
-    return new JSONException(message + this.toString());
-  }
-
-
-  /**
-   * Make a printable string of this JSONTokener.
-   *
-   * @return " at {index} [character {character} line {line}]"
-   */
-  public String toString() {
-    return " at " + this.index + " [character " + this.character + " line " + this.line + "]";
-  }
+    /**
+     * Returns the next {@code length} characters of the input.
+     *
+     * <p>The returned string shares its backing character array with this
+     * tokener's input string. If a reference to the returned string may be held
+     * indefinitely, you should use {@code new String(result)} to copy it first
+     * to avoid memory leaks.
+     *
+     * @param length The desired number of characters to return.
+     * @return The next few characters.
+     * @throws JSONException if the remaining input is not long enough to
+     *                       satisfy this request.
+     */
+    public String next(int length) throws JSONException {
+        if (pos + length > in.length()) {
+            throw syntaxError(length + " is out of bounds");
+        }
+        String result = in.substring(pos, pos + length);
+        pos += length;
+        return result;
+    }
+
+    /**
+     * Returns the {@link String#trim trimmed} string holding the characters up
+     * to but not including the first of:
+     * <ul>
+     * <li>any character in {@code excluded}
+     * <li>a newline character '\n'
+     * <li>a carriage return '\r'
+     * </ul>
+     *
+     * <p>The returned string shares its backing character array with this
+     * tokener's input string. If a reference to the returned string may be held
+     * indefinitely, you should use {@code new String(result)} to copy it first
+     * to avoid memory leaks.
+     *
+     * @param excluded The limiting string where the search should stop.
+     * @return a possibly-empty string
+     */
+    public String nextTo(String excluded) {
+        if (excluded == null) {
+            throw new NullPointerException("excluded == null");
+        }
+        return nextToInternal(excluded).trim();
+    }
+
+    /**
+     * Equivalent to {@code nextTo(String.valueOf(excluded))}.
+     *
+     * @param excluded The limiting character.
+     * @return a possibly-empty string
+     */
+    public String nextTo(char excluded) {
+        return nextToInternal(String.valueOf(excluded)).trim();
+    }
+
+    /**
+     * Advances past all input up to and including the next occurrence of
+     * {@code thru}. If the remaining input doesn't contain {@code thru}, the
+     * input is exhausted.
+     *
+     * @param thru The string to skip over.
+     */
+    public void skipPast(String thru) {
+        int thruStart = in.indexOf(thru, pos);
+        pos = thruStart == -1 ? in.length() : (thruStart + thru.length());
+    }
+
+    /**
+     * Advances past all input up to but not including the next occurrence of
+     * {@code to}. If the remaining input doesn't contain {@code to}, the input
+     * is unchanged.
+     *
+     * @param to The character we want to skip to.
+     * @return The value of {@code to} or null.
+     */
+    public char skipTo(char to) {
+        int index = in.indexOf(to, pos);
+        if (index != -1) {
+            pos = index;
+            return to;
+        } else {
+            return '\0';
+        }
+    }
+
+    /**
+     * Unreads the most recent character of input. If no input characters have
+     * been read, the input is unchanged.
+     */
+    public void back() {
+        if (--pos == -1) {
+            pos = 0;
+        }
+    }
+
+    /**
+     * Returns the integer [0..15] value for the given hex character, or -1
+     * for non-hex input.
+     *
+     * @param hex a character in the ranges [0-9], [A-F] or [a-f]. Any other
+     *            character will yield a -1 result.
+     * @return The decoded integer.
+     */
+    public static int dehexchar(char hex) {
+        if (hex >= '0' && hex <= '9') {
+            return hex - '0';
+        } else if (hex >= 'A' && hex <= 'F') {
+            return hex - 'A' + 10;
+        } else if (hex >= 'a' && hex <= 'f') {
+            return hex - 'a' + 10;
+        } else {
+            return -1;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/JSONWriter.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONWriter.java b/geode-json/src/main/java/org/json/JSONWriter.java
deleted file mode 100755
index 7d4704b..0000000
--- a/geode-json/src/main/java/org/json/JSONWriter.java
+++ /dev/null
@@ -1,321 +0,0 @@
-package org.json;
-
-import java.io.IOException;
-import java.io.Writer;
-
-/*
- * Copyright (c) 2006 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * JSONWriter provides a quick and convenient way of producing JSON text. The texts produced
- * strictly conform to JSON syntax rules. No whitespace is added, so the results are ready for
- * transmission or storage. Each instance of JSONWriter can produce one JSON text.
- * <p>
- * A JSONWriter instance provides a <code>value</code> method for appending values to the text, and
- * a <code>key</code> method for adding keys before values in objects. There are <code>array</code>
- * and <code>endArray</code> methods that make and bound array values, and <code>object</code> and
- * <code>endObject</code> methods which make and bound object values. All of these methods return
- * the JSONWriter instance, permitting a cascade style. For example,
- * 
- * <pre>
- * new JSONWriter(myWriter).object().key("JSON").value("Hello, World!").endObject();
- * </pre>
- * 
- * which writes
- * 
- * <pre>
- * {"JSON":"Hello, World!"}
- * </pre>
- * <p>
- * The first method called must be <code>array</code> or <code>object</code>. There are no methods
- * for adding commas or colons. JSONWriter adds them for you. Objects and arrays can be nested up to
- * 20 levels deep.
- * <p>
- * This can sometimes be easier than using a JSONObject to build a string.
- * 
- * @author JSON.org
- * @version 2011-11-24
- */
-public class JSONWriter {
-  private static final int maxdepth = 200;
-
-  /**
-   * The comma flag determines if a comma should be output before the next value.
-   */
-  private boolean comma;
-
-  /**
-   * The current mode. Values: 'a' (array), 'd' (done), 'i' (initial), 'k' (key), 'o' (object).
-   */
-  protected char mode;
-
-  /**
-   * The object/array stack.
-   */
-  private final JSONObject stack[];
-
-  /**
-   * The stack top index. A value of 0 indicates that the stack is empty.
-   */
-  private int top;
-
-  /**
-   * The writer that will receive the output.
-   */
-  protected Writer writer;
-
-  /**
-   * Make a fresh JSONWriter. It can be used to build one JSON text.
-   */
-  public JSONWriter(Writer w) {
-    this.comma = false;
-    this.mode = 'i';
-    this.stack = new JSONObject[maxdepth];
-    this.top = 0;
-    this.writer = w;
-  }
-
-  /**
-   * Append a value.
-   * 
-   * @param string A string value.
-   * @return this
-   * @throws JSONException If the value is out of sequence.
-   */
-  private JSONWriter append(String string) throws JSONException {
-    if (string == null) {
-      throw new JSONException("Null pointer");
-    }
-    if (this.mode == 'o' || this.mode == 'a') {
-      try {
-        if (this.comma && this.mode == 'a') {
-          this.writer.write(',');
-        }
-        this.writer.write(string);
-      } catch (IOException e) {
-        throw new JSONException(e);
-      }
-      if (this.mode == 'o') {
-        this.mode = 'k';
-      }
-      this.comma = true;
-      return this;
-    }
-    throw new JSONException("Value out of sequence.");
-  }
-
-  /**
-   * Begin appending a new array. All values until the balancing <code>endArray</code> will be
-   * appended to this array. The <code>endArray</code> method must be called to mark the array's
-   * end.
-   * 
-   * @return this
-   * @throws JSONException If the nesting is too deep, or if the object is started in the wrong
-   *         place (for example as a key or after the end of the outermost array or object).
-   */
-  public JSONWriter array() throws JSONException {
-    if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
-      this.push(null);
-      this.append("[");
-      this.comma = false;
-      return this;
-    }
-    throw new JSONException("Misplaced array.");
-  }
-
-  /**
-   * End something.
-   * 
-   * @param mode Mode
-   * @param c Closing character
-   * @return this
-   * @throws JSONException If unbalanced.
-   */
-  private JSONWriter end(char mode, char c) throws JSONException {
-    if (this.mode != mode) {
-      throw new JSONException(mode == 'a' ? "Misplaced endArray." : "Misplaced endObject.");
-    }
-    this.pop(mode);
-    try {
-      this.writer.write(c);
-    } catch (IOException e) {
-      throw new JSONException(e);
-    }
-    this.comma = true;
-    return this;
-  }
-
-  /**
-   * End an array. This method most be called to balance calls to <code>array</code>.
-   * 
-   * @return this
-   * @throws JSONException If incorrectly nested.
-   */
-  public JSONWriter endArray() throws JSONException {
-    return this.end('a', ']');
-  }
-
-  /**
-   * End an object. This method most be called to balance calls to <code>object</code>.
-   * 
-   * @return this
-   * @throws JSONException If incorrectly nested.
-   */
-  public JSONWriter endObject() throws JSONException {
-    return this.end('k', '}');
-  }
-
-  /**
-   * Append a key. The key will be associated with the next value. In an object, every value must be
-   * preceded by a key.
-   * 
-   * @param string A key string.
-   * @return this
-   * @throws JSONException If the key is out of place. For example, keys do not belong in arrays or
-   *         if the key is null.
-   */
-  public JSONWriter key(String string) throws JSONException {
-    if (string == null) {
-      throw new JSONException("Null key.");
-    }
-    if (this.mode == 'k') {
-      try {
-        this.stack[this.top - 1].putOnce(string, Boolean.TRUE);
-        if (this.comma) {
-          this.writer.write(',');
-        }
-        this.writer.write(JSONObject.quote(string));
-        this.writer.write(':');
-        this.comma = false;
-        this.mode = 'o';
-        return this;
-      } catch (IOException e) {
-        throw new JSONException(e);
-      }
-    }
-    throw new JSONException("Misplaced key.");
-  }
-
-
-  /**
-   * Begin appending a new object. All keys and values until the balancing <code>endObject</code>
-   * will be appended to this object. The <code>endObject</code> method must be called to mark the
-   * object's end.
-   * 
-   * @return this
-   * @throws JSONException If the nesting is too deep, or if the object is started in the wrong
-   *         place (for example as a key or after the end of the outermost array or object).
-   */
-  public JSONWriter object() throws JSONException {
-    if (this.mode == 'i') {
-      this.mode = 'o';
-    }
-    if (this.mode == 'o' || this.mode == 'a') {
-      this.append("{");
-      this.push(new JSONObject());
-      this.comma = false;
-      return this;
-    }
-    throw new JSONException("Misplaced object.");
-
-  }
-
-
-  /**
-   * Pop an array or object scope.
-   * 
-   * @param c The scope to close.
-   * @throws JSONException If nesting is wrong.
-   */
-  private void pop(char c) throws JSONException {
-    if (this.top <= 0) {
-      throw new JSONException("Nesting error.");
-    }
-    char m = this.stack[this.top - 1] == null ? 'a' : 'k';
-    if (m != c) {
-      throw new JSONException("Nesting error.");
-    }
-    this.top -= 1;
-    this.mode = this.top == 0 ? 'd' : this.stack[this.top - 1] == null ? 'a' : 'k';
-  }
-
-  /**
-   * Push an array or object scope.
-   * 
-   * @param jo The scope to open.
-   * @throws JSONException If nesting is too deep.
-   */
-  private void push(JSONObject jo) throws JSONException {
-    if (this.top >= maxdepth) {
-      throw new JSONException("Nesting too deep.");
-    }
-    this.stack[this.top] = jo;
-    this.mode = jo == null ? 'a' : 'k';
-    this.top += 1;
-  }
-
-
-  /**
-   * Append either the value <code>true</code> or the value <code>false</code>.
-   * 
-   * @param b A boolean.
-   * @return this
-   * @throws JSONException
-   */
-  public JSONWriter value(boolean b) throws JSONException {
-    return this.append(b ? "true" : "false");
-  }
-
-  /**
-   * Append a double value.
-   * 
-   * @param d A double.
-   * @return this
-   * @throws JSONException If the number is not finite.
-   */
-  public JSONWriter value(double d) throws JSONException {
-    return this.value(new Double(d));
-  }
-
-  /**
-   * Append a long value.
-   * 
-   * @param l A long.
-   * @return this
-   * @throws JSONException
-   */
-  public JSONWriter value(long l) throws JSONException {
-    return this.append(Long.toString(l));
-  }
-
-
-  /**
-   * Append an object value.
-   * 
-   * @param object The object to append. It can be null, or a Boolean, Number, String, JSONObject,
-   *        or JSONArray, or an object that implements JSONString.
-   * @return this
-   * @throws JSONException If the value is out of sequence.
-   */
-  public JSONWriter value(Object object) throws JSONException {
-    return this.append(JSONObject.valueToString(object));
-  }
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/XML.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/XML.java b/geode-json/src/main/java/org/json/XML.java
deleted file mode 100755
index ae6d61a..0000000
--- a/geode-json/src/main/java/org/json/XML.java
+++ /dev/null
@@ -1,504 +0,0 @@
-package org.json;
-
-/*
- * Copyright (c) 2002 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-import java.util.Iterator;
-
-
-/**
- * This provides static methods to convert an XML text into a JSONObject, and to covert a JSONObject
- * into an XML text.
- * 
- * @author JSON.org
- * @version 2011-02-11
- */
-public class XML {
-
-  /** The Character '&'. */
-  public static final Character AMP = new Character('&');
-
-  /** The Character '''. */
-  public static final Character APOS = new Character('\'');
-
-  /** The Character '!'. */
-  public static final Character BANG = new Character('!');
-
-  /** The Character '='. */
-  public static final Character EQ = new Character('=');
-
-  /** The Character '>'. */
-  public static final Character GT = new Character('>');
-
-  /** The Character '<'. */
-  public static final Character LT = new Character('<');
-
-  /** The Character '?'. */
-  public static final Character QUEST = new Character('?');
-
-  /** The Character '"'. */
-  public static final Character QUOT = new Character('"');
-
-  /** The Character '/'. */
-  public static final Character SLASH = new Character('/');
-
-  /**
-   * Replace special characters with XML escapes:
-   * 
-   * <pre>
-   * &amp; <small>(ampersand)</small> is replaced by &amp;amp;
-   * &lt; <small>(less than)</small> is replaced by &amp;lt;
-   * &gt; <small>(greater than)</small> is replaced by &amp;gt;
-   * &quot; <small>(double quote)</small> is replaced by &amp;quot;
-   * </pre>
-   * 
-   * @param string The string to be escaped.
-   * @return The escaped string.
-   */
-  public static String escape(String string) {
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0, length = string.length(); i < length; i++) {
-      char c = string.charAt(i);
-      switch (c) {
-        case '&':
-          sb.append("&amp;");
-          break;
-        case '<':
-          sb.append("&lt;");
-          break;
-        case '>':
-          sb.append("&gt;");
-          break;
-        case '"':
-          sb.append("&quot;");
-          break;
-        case '\'':
-          sb.append("&apos;");
-          break;
-        default:
-          sb.append(c);
-      }
-    }
-    return sb.toString();
-  }
-
-  /**
-   * Throw an exception if the string contains whitespace. Whitespace is not allowed in tagNames and
-   * attributes.
-   * 
-   * @param string
-   * @throws JSONException
-   */
-  public static void noSpace(String string) throws JSONException {
-    int i, length = string.length();
-    if (length == 0) {
-      throw new JSONException("Empty string.");
-    }
-    for (i = 0; i < length; i += 1) {
-      if (Character.isWhitespace(string.charAt(i))) {
-        throw new JSONException("'" + string + "' contains a space character.");
-      }
-    }
-  }
-
-  /**
-   * Scan the content following the named tag, attaching it to the context.
-   * 
-   * @param x The XMLTokener containing the source string.
-   * @param context The JSONObject that will include the new material.
-   * @param name The tag name.
-   * @return true if the close tag is processed.
-   * @throws JSONException
-   */
-  private static boolean parse(XMLTokener x, JSONObject context, String name) throws JSONException {
-    char c;
-    int i;
-    JSONObject jsonobject = null;
-    String string;
-    String tagName;
-    Object token;
-
-    // Test for and skip past these forms:
-    // <!-- ... -->
-    // <! ... >
-    // <![ ... ]]>
-    // <? ... ?>
-    // Report errors for these forms:
-    // <>
-    // <=
-    // <<
-
-    token = x.nextToken();
-
-    // <!
-
-    if (token == BANG) {
-      c = x.next();
-      if (c == '-') {
-        if (x.next() == '-') {
-          x.skipPast("-->");
-          return false;
-        }
-        x.back();
-      } else if (c == '[') {
-        token = x.nextToken();
-        if ("CDATA".equals(token)) {
-          if (x.next() == '[') {
-            string = x.nextCDATA();
-            if (string.length() > 0) {
-              context.accumulate("content", string);
-            }
-            return false;
-          }
-        }
-        throw x.syntaxError("Expected 'CDATA['");
-      }
-      i = 1;
-      do {
-        token = x.nextMeta();
-        if (token == null) {
-          throw x.syntaxError("Missing '>' after '<!'.");
-        } else if (token == LT) {
-          i += 1;
-        } else if (token == GT) {
-          i -= 1;
-        }
-      } while (i > 0);
-      return false;
-    } else if (token == QUEST) {
-
-      // <?
-
-      x.skipPast("?>");
-      return false;
-    } else if (token == SLASH) {
-
-      // Close tag </
-
-      token = x.nextToken();
-      if (name == null) {
-        throw x.syntaxError("Mismatched close tag " + token);
-      }
-      if (!token.equals(name)) {
-        throw x.syntaxError("Mismatched " + name + " and " + token);
-      }
-      if (x.nextToken() != GT) {
-        throw x.syntaxError("Misshaped close tag");
-      }
-      return true;
-
-    } else if (token instanceof Character) {
-      throw x.syntaxError("Misshaped tag");
-
-      // Open tag <
-
-    } else {
-      tagName = (String) token;
-      token = null;
-      jsonobject = new JSONObject();
-      for (;;) {
-        if (token == null) {
-          token = x.nextToken();
-        }
-
-        // attribute = value
-
-        if (token instanceof String) {
-          string = (String) token;
-          token = x.nextToken();
-          if (token == EQ) {
-            token = x.nextToken();
-            if (!(token instanceof String)) {
-              throw x.syntaxError("Missing value");
-            }
-            jsonobject.accumulate(string, XML.stringToValue((String) token));
-            token = null;
-          } else {
-            jsonobject.accumulate(string, "");
-          }
-
-          // Empty tag <.../>
-
-        } else if (token == SLASH) {
-          if (x.nextToken() != GT) {
-            throw x.syntaxError("Misshaped tag");
-          }
-          if (jsonobject.length() > 0) {
-            context.accumulate(tagName, jsonobject);
-          } else {
-            context.accumulate(tagName, "");
-          }
-          return false;
-
-          // Content, between <...> and </...>
-
-        } else if (token == GT) {
-          for (;;) {
-            token = x.nextContent();
-            if (token == null) {
-              if (tagName != null) {
-                throw x.syntaxError("Unclosed tag " + tagName);
-              }
-              return false;
-            } else if (token instanceof String) {
-              string = (String) token;
-              if (string.length() > 0) {
-                jsonobject.accumulate("content", XML.stringToValue(string));
-              }
-
-              // Nested element
-
-            } else if (token == LT) {
-              if (parse(x, jsonobject, tagName)) {
-                if (jsonobject.length() == 0) {
-                  context.accumulate(tagName, "");
-                } else if (jsonobject.length() == 1 && jsonobject.opt("content") != null) {
-                  context.accumulate(tagName, jsonobject.opt("content"));
-                } else {
-                  context.accumulate(tagName, jsonobject);
-                }
-                return false;
-              }
-            }
-          }
-        } else {
-          throw x.syntaxError("Misshaped tag");
-        }
-      }
-    }
-  }
-
-
-  /**
-   * Try to convert a string into a number, boolean, or null. If the string can't be converted,
-   * return the string. This is much less ambitious than JSONObject.stringToValue, especially
-   * because it does not attempt to convert plus forms, octal forms, hex forms, or E forms lacking
-   * decimal points.
-   * 
-   * @param string A String.
-   * @return A simple JSON value.
-   */
-  public static Object stringToValue(String string) {
-    if ("".equals(string)) {
-      return string;
-    }
-    if ("true".equalsIgnoreCase(string)) {
-      return Boolean.TRUE;
-    }
-    if ("false".equalsIgnoreCase(string)) {
-      return Boolean.FALSE;
-    }
-    if ("null".equalsIgnoreCase(string)) {
-      return JSONObject.NULL;
-    }
-    if ("0".equals(string)) {
-      return new Integer(0);
-    }
-
-    // If it might be a number, try converting it. If that doesn't work,
-    // return the string.
-
-    try {
-      char initial = string.charAt(0);
-      boolean negative = false;
-      if (initial == '-') {
-        initial = string.charAt(1);
-        negative = true;
-      }
-      if (initial == '0' && string.charAt(negative ? 2 : 1) == '0') {
-        return string;
-      }
-      if ((initial >= '0' && initial <= '9')) {
-        if (string.indexOf('.') >= 0) {
-          return Double.valueOf(string);
-        } else if (string.indexOf('e') < 0 && string.indexOf('E') < 0) {
-          Long myLong = new Long(string);
-          if (myLong.longValue() == myLong.intValue()) {
-            return new Integer(myLong.intValue());
-          } else {
-            return myLong;
-          }
-        }
-      }
-    } catch (Exception ignore) {
-    }
-    return string;
-  }
-
-
-  /**
-   * Convert a well-formed (but not necessarily valid) XML string into a JSONObject. Some
-   * information may be lost in this transformation because JSON is a data format and XML is a
-   * document format. XML uses elements, attributes, and content text, while JSON uses unordered
-   * collections of name/value pairs and arrays of values. JSON does not does not like to
-   * distinguish between elements and attributes. Sequences of similar elements are represented as
-   * JSONArrays. Content text may be placed in a "content" member. Comments, prologs, DTDs, and
-   * <code>&lt;[ [ ]]></code> are ignored.
-   * 
-   * @param string The source string.
-   * @return A JSONObject containing the structured data from the XML string.
-   * @throws JSONException
-   */
-  public static JSONObject toJSONObject(String string) throws JSONException {
-    JSONObject jo = new JSONObject();
-    XMLTokener x = new XMLTokener(string);
-    while (x.more() && x.skipPast("<")) {
-      parse(x, jo, null);
-    }
-    return jo;
-  }
-
-
-  /**
-   * Convert a JSONObject into a well-formed, element-normal XML string.
-   * 
-   * @param object A JSONObject.
-   * @return A string.
-   * @throws JSONException
-   */
-  public static String toString(Object object) throws JSONException {
-    return toString(object, null);
-  }
-
-
-  /**
-   * Convert a JSONObject into a well-formed, element-normal XML string.
-   * 
-   * @param object A JSONObject.
-   * @param tagName The optional name of the enclosing tag.
-   * @return A string.
-   * @throws JSONException
-   */
-  public static String toString(Object object, String tagName) throws JSONException {
-    StringBuffer sb = new StringBuffer();
-    int i;
-    JSONArray ja;
-    JSONObject jo;
-    String key;
-    Iterator keys;
-    int length;
-    String string;
-    Object value;
-    if (object instanceof JSONObject) {
-
-      // Emit <tagName>
-
-      if (tagName != null) {
-        sb.append('<');
-        sb.append(tagName);
-        sb.append('>');
-      }
-
-      // Loop thru the keys.
-
-      jo = (JSONObject) object;
-      keys = jo.keys();
-      while (keys.hasNext()) {
-        key = keys.next().toString();
-        value = jo.opt(key);
-        if (value == null) {
-          value = "";
-        }
-        if (value instanceof String) {
-          string = (String) value;
-        } else {
-          string = null;
-        }
-
-        // Emit content in body
-
-        if ("content".equals(key)) {
-          if (value instanceof JSONArray) {
-            ja = (JSONArray) value;
-            length = ja.length();
-            for (i = 0; i < length; i += 1) {
-              if (i > 0) {
-                sb.append('\n');
-              }
-              sb.append(escape(ja.get(i).toString()));
-            }
-          } else {
-            sb.append(escape(value.toString()));
-          }
-
-          // Emit an array of similar keys
-
-        } else if (value instanceof JSONArray) {
-          ja = (JSONArray) value;
-          length = ja.length();
-          for (i = 0; i < length; i += 1) {
-            value = ja.get(i);
-            if (value instanceof JSONArray) {
-              sb.append('<');
-              sb.append(key);
-              sb.append('>');
-              sb.append(toString(value));
-              sb.append("</");
-              sb.append(key);
-              sb.append('>');
-            } else {
-              sb.append(toString(value, key));
-            }
-          }
-        } else if ("".equals(value)) {
-          sb.append('<');
-          sb.append(key);
-          sb.append("/>");
-
-          // Emit a new tag <k>
-
-        } else {
-          sb.append(toString(value, key));
-        }
-      }
-      if (tagName != null) {
-
-        // Emit the </tagname> close tag
-
-        sb.append("</");
-        sb.append(tagName);
-        sb.append('>');
-      }
-      return sb.toString();
-
-      // XML does not have good support for arrays. If an array appears in a place
-      // where XML is lacking, synthesize an <array> element.
-
-    } else {
-      if (object.getClass().isArray()) {
-        object = new JSONArray(object);
-      }
-      if (object instanceof JSONArray) {
-        ja = (JSONArray) object;
-        length = ja.length();
-        for (i = 0; i < length; i += 1) {
-          sb.append(toString(ja.opt(i), tagName == null ? "array" : tagName));
-        }
-        return sb.toString();
-      } else {
-        string = (object == null) ? "null" : escape(object.toString());
-        return (tagName == null) ? "\"" + string + "\""
-            : (string.length() == 0) ? "<" + tagName + "/>"
-                : "<" + tagName + ">" + string + "</" + tagName + ">";
-      }
-    }
-  }
-}


[4/8] geode git commit: GEODE-2142: Removal of non-compliant org.json implementation.

Posted by ud...@apache.org.
http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/JSONArray.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONArray.java b/geode-json/src/main/java/org/json/JSONArray.java
old mode 100644
new mode 100755
index edaefa4..074624d
--- a/geode-json/src/main/java/org/json/JSONArray.java
+++ b/geode-json/src/main/java/org/json/JSONArray.java
@@ -1,868 +1,759 @@
-package org.json;
-
 /*
- * Copyright (c) 2002 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
  */
 
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
+package org.json;
+
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
+import java.util.List;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
 
 /**
- * A JSONArray is an ordered sequence of values. Its external text form is a string wrapped in
- * square brackets with commas separating the values. The internal form is an object having
- * <code>get</code> and <code>opt</code> methods for accessing the values by index, and
- * <code>put</code> methods for adding or replacing values. The values can be any of these types:
- * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>, <code>Number</code>,
- * <code>String</code>, or the <code>JSONObject.NULL object</code>.
- * <p>
- * The constructor can convert a JSON text into a Java object. The <code>toString</code> method
- * converts to JSON text.
- * <p>
- * A <code>get</code> method returns a value if one can be found, and throws an exception if one
- * cannot be found. An <code>opt</code> method returns a default value instead of throwing an
- * exception, and so is useful for obtaining optional values.
- * <p>
- * The generic <code>get()</code> and <code>opt()</code> methods return an object which you can cast
- * or query for type. There are also typed <code>get</code> and <code>opt</code> methods that do
- * type checking and type coercion for you.
- * <p>
- * The texts produced by the <code>toString</code> methods strictly conform to JSON syntax rules.
- * The constructors are more forgiving in the texts they will accept:
- * <ul>
- * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just before the closing
- * bracket.</li>
- * <li>The <code>null</code> value will be inserted when there is <code>,</code>
- * &nbsp;<small>(comma)</small> elision.</li>
- * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single quote)</small>.</li>
- * <li>Strings do not need to be quoted at all if they do not begin with a quote or single quote,
- * and if they do not contain leading or trailing spaces, and if they do not contain any of these
- * characters: <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers and if they
- * are not the reserved words <code>true</code>, <code>false</code>, or <code>null</code>.</li>
- * <li>Values can be separated by <code>;</code> <small>(semicolon)</small> as well as by
- * <code>,</code> <small>(comma)</small>.</li>
- * </ul>
+ * A dense indexed sequence of values. Values may be any mix of
+ * {@link JSONObject JSONObjects}, other {@link JSONArray JSONArrays}, Strings,
+ * Booleans, Integers, Longs, Doubles, {@code null} or {@link JSONObject#NULL}.
+ * Values may not be {@link Double#isNaN() NaNs}, {@link Double#isInfinite()
+ * infinities}, or of any type not listed here.
+ *
+ * {@code JSONArray} has the same type coercion behavior and
+ * optional/mandatory accessors as {@link JSONObject}. See that class'
+ * documentation for details.
  *
- * @author JSON.org
- * @version 2012-04-20
+ * <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, {@code get} fails if the requested index
+ * holds the null reference, but succeeds if it holds {@code JSONObject.NULL}.
+ *
+ * Instances of this class are not thread safe. Although this class is
+ * non-final, it was not designed for inheritance and should not be subclassed.
+ * In particular, self-use by overridable methods is not specified. See
+ * <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
+ * prohibit it" for further information.
  */
 public class JSONArray {
 
+    private final List<Object> values;
+
+    /**
+     * Creates a {@code JSONArray} with no values.
+     */
+    public JSONArray() {
+        values = new ArrayList<Object>();
+    }
+
+    /**
+     * Creates a new {@code JSONArray} by copying all values from the given
+     * collection.
+     *
+     * @param copyFrom a collection whose values are of supported types.
+     *                 Unsupported values are not permitted and will yield an array in an
+     *                 inconsistent state.
+     */
+    /* Accept a raw type for API compatibility */
+    public JSONArray(Collection<?> copyFrom) {
+        this();
+        if (copyFrom != null) {
+            for (Object aCopyFrom : copyFrom) {
+                put(JSONObject.wrap(aCopyFrom));
+            }
+        }
+    }
+
+    /**
+     * Creates a new {@code JSONArray} with values from the next array in the
+     * tokener.
+     *
+     * @param readFrom a tokener whose nextValue() method will yield a
+     *                 {@code JSONArray}.
+     * @throws JSONException if the parse fails or doesn't yield a
+     *                       {@code JSONArray}.
+     */
+    public JSONArray(JSONTokener readFrom) throws JSONException {
+        /*
+         * Getting the parser to populate this could get tricky. Instead, just
+         * parse to temporary JSONArray and then steal the data from that.
+         */
+        Object object = readFrom.nextValue();
+        if (object instanceof JSONArray) {
+            values = ((JSONArray) object).values;
+        } else {
+            throw JSON.typeMismatch(object, "JSONArray");
+        }
+    }
+
+    /**
+     * Creates a new {@code JSONArray} with values from the JSON string.
+     *
+     * @param json a JSON-encoded string containing an array.
+     * @throws JSONException if the parse fails or doesn't yield a {@code
+     *                       JSONArray}.
+     */
+    public JSONArray(String json) throws JSONException {
+        this(new JSONTokener(json));
+    }
+
+    /**
+     * Creates a new {@code JSONArray} with values from the given primitive array.
+     *
+     * @param array The values to use.
+     * @throws JSONException if any of the values are non-finite double values (i.e. NaN or infinite)
+     */
+    public JSONArray(Object array) throws JSONException {
+        if (!array.getClass().isArray()) {
+            throw new JSONException("Not a primitive array: " + array.getClass());
+        }
+        final int length = Array.getLength(array);
+        values = new ArrayList<Object>(length);
+        for (int i = 0; i < length; ++i) {
+            put(JSONObject.wrap(Array.get(array, i)));
+        }
+    }
+
+    /**
+     * @return Returns the number of values in this array.
+     */
+    public int length() {
+        return values.size();
+    }
+
+    /**
+     * Appends {@code value} to the end of this array.
+     *
+     * @param value The value to append.
+     * @return this array.
+     */
+    public JSONArray put(boolean value) {
+        values.add(value);
+        return this;
+    }
+
+    /**
+     * Appends {@code value} to the end of this array.
+     *
+     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+     *              {@link Double#isInfinite() infinities}.
+     * @return this array.
+     * @throws JSONException If the value is unacceptable.
+     */
+    public JSONArray put(double value) throws JSONException {
+        values.add(JSON.checkDouble(value));
+        return this;
+    }
+
+    /**
+     * Appends {@code value} to the end of this array.
+     *
+     * @param value The value to append.
+     * @return this array.
+     */
+    public JSONArray put(int value) {
+        values.add(value);
+        return this;
+    }
+
+    /**
+     * Appends {@code value} to the end of this array.
+     *
+     * @param value The value to append.
+     * @return this array.
+     */
+    public JSONArray put(long value) {
+        values.add(value);
+        return this;
+    }
+
+    /**
+     * Appends {@code value} wrapped by {@link JSONArray} to the end of this array.
+     *
+     * @param value any collection.
+     * @return this array.
+     */
+    public JSONArray put(Collection<?> value) {
+        if (value == null) {
+            return put((Object)null);
+        }
+        values.add(new JSONArray(value));
+        return this;
+    }
+
+    /**
+     * Appends {@code value} to the end of this array.
+     *
+     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     *              Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
+     *              not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
+     *              infinities}. Unsupported values are not permitted and will cause the
+     *              array to be in an inconsistent state.
+     * @return this array.
+     */
+    public JSONArray put(Object value) {
+        values.add(value);
+        return this;
+    }
+
+    /**
+     * Same as {@link #put}, with added validity checks.
+     *
+     * @param value The value to append.
+     */
+    void checkedPut(Object value) throws JSONException {
+        if (value instanceof Number) {
+            JSON.checkDouble(((Number) value).doubleValue());
+        }
+
+        put(value);
+    }
+
+    /**
+     * Sets the value at {@code index} to {@code value}, null padding this array
+     * to the required length if necessary. If a value already exists at {@code
+     * index}, it will be replaced.
+     *
+     * @param index Where to put the value.
+     * @param value The value to set.
+     * @return this array.
+     * @throws JSONException This should never happen.
+     */
+    public JSONArray put(int index, boolean value) throws JSONException {
+        return put(index, (Boolean) value);
+    }
+
+    /**
+     * Sets the value at {@code index} to {@code value}, null padding this array
+     * to the required length if necessary. If a value already exists at {@code
+     * index}, it will be replaced.
+     *
+     * @param index Where to put the value.
+     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+     *              {@link Double#isInfinite() infinities}.
+     * @return this array.
+     * @throws JSONException If the value is not a finite value.
+     */
+    public JSONArray put(int index, double value) throws JSONException {
+        return put(index, (Double) value);
+    }
+
+    /**
+     * Sets the value at {@code index} to {@code value}, null padding this array
+     * to the required length if necessary. If a value already exists at {@code
+     * index}, it will be replaced.
+     *
+     * @param index Where to put the value.
+     * @param value The value to set.
+     * @return this array.
+     * @throws JSONException Should never actually happen.
+     */
+    public JSONArray put(int index, int value) throws JSONException {
+        return put(index, (Integer) value);
+    }
+
+    /**
+     * Sets the value at {@code index} to {@code value}, null padding this array
+     * to the required length if necessary. If a value already exists at {@code
+     * index}, it will be replaced.
+     *
+     * @param index Where to put the value.
+     * @param value The value to set.
+     * @return this array.
+     * @throws JSONException Should never actually happen.
+     */
+    public JSONArray put(int index, long value) throws JSONException {
+        return put(index, (Long) value);
+    }
+
+    /**
+     * Sets the value at {@code index} to {@code value} wrapped into {@link JSONArray},
+     * null padding this array to the required length if necessary. If a value already
+     * exists at {@code index}, it will be replaced.
+     *
+     * @param index Where to put the value.
+     * @param value The value to set.
+     * @return this array.
+     * @throws JSONException Should never actually happen.
+     */
+    public JSONArray put(int index, Collection<?> value) throws JSONException {
+        if (value == null) {
+            return put(index, (Object)null);
+        }
+        return put(index, new JSONArray(value));
+    }
+
+    /**
+     * Sets the value at {@code index} to {@code value}, null padding this array
+     * to the required length if necessary. If a value already exists at {@code
+     * index}, it will be replaced.
+     *
+     * @param index Where to put the value.
+     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     *              Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
+     *              not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
+     *              infinities}.
+     * @return this array.
+     * @throws JSONException If the value cannot be represented as a finite double value.
+     */
+    public JSONArray put(int index, Object value) throws JSONException {
+        if (value instanceof Number) {
+            // deviate from the original by checking all Numbers, not just floats & doubles
+            JSON.checkDouble(((Number) value).doubleValue());
+        }
+        while (values.size() <= index) {
+            values.add(null);
+        }
+        values.set(index, value);
+        return this;
+    }
+
+    /**
+     * Returns true if this array has no value at {@code index}, or if its value
+     * is the {@code null} reference or {@link JSONObject#NULL}.
+     *
+     * @param index Which value to check.
+     * @return true if the value is null.
+     */
+    public boolean isNull(int index) {
+        Object value = opt(index);
+        return value == null || value == JSONObject.NULL;
+    }
+
+    /**
+     * Returns the value at {@code index}.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     * @throws JSONException if this array has no value at {@code index}, or if
+     *                       that value is the {@code null} reference. This method returns
+     *                       normally if the value is {@code JSONObject#NULL}.
+     */
+    public Object get(int index) throws JSONException {
+        try {
+            Object value = values.get(index);
+            if (value == null) {
+                throw new JSONException("Value at " + index + " is null.");
+            }
+            return value;
+        } catch (IndexOutOfBoundsException e) {
+            throw new JSONException("Index " + index + " out of range [0.." + values.size() + ")");
+        }
+    }
+
+    /**
+     * Returns the value at {@code index}, or null if the array has no value
+     * at {@code index}.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     */
+    public Object opt(int index) {
+        if (index < 0 || index >= values.size()) {
+            return null;
+        }
+        return values.get(index);
+    }
+
+    /**
+     * Removes and returns the value at {@code index}, or null if the array has no value
+     * at {@code index}.
+     *
+     * @param index Which value to remove.
+     * @return The value previously at the specified location.
+     */
+    public Object remove(int index) {
+        if (index < 0 || index >= values.size()) {
+            return null;
+        }
+        return values.remove(index);
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a boolean or can
+     * be coerced to a boolean.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     * @throws JSONException if the value at {@code index} doesn't exist or
+     *                       cannot be coerced to a boolean.
+     */
+    public boolean getBoolean(int index) throws JSONException {
+        Object object = get(index);
+        Boolean result = JSON.toBoolean(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "boolean");
+        }
+        return result;
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a boolean or can
+     * be coerced to a boolean. Returns false otherwise.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     */
+    public boolean optBoolean(int index) {
+        return optBoolean(index, false);
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a boolean or can
+     * be coerced to a boolean. Returns {@code fallback} otherwise.
+     *
+     * @param index    Which value to get.
+     * @param fallback the fallback value to return if no value exists.
+     * @return the value at the specified location or the fallback value.
+     */
+    public boolean optBoolean(int index, boolean fallback) {
+        Object object = opt(index);
+        Boolean result = JSON.toBoolean(object);
+        return result != null ? result : fallback;
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a double or can
+     * be coerced to a double.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     * @throws JSONException if the value at {@code index} doesn't exist or
+     *                       cannot be coerced to a double.
+     */
+    public double getDouble(int index) throws JSONException {
+        Object object = get(index);
+        Double result = JSON.toDouble(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "double");
+        }
+        return result;
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a double or can
+     * be coerced to a double. Returns {@code NaN} otherwise.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     */
+    public double optDouble(int index) {
+        return optDouble(index, Double.NaN);
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a double or can
+     * be coerced to a double. Returns {@code fallback} otherwise.
+     *
+     * @param index    Which value to get.
+     * @param fallback The fallback value to use if no value is at the specified location.
+     * @return the value at the specified location or the fallback value.
+     */
+    public double optDouble(int index, double fallback) {
+        Object object = opt(index);
+        Double result = JSON.toDouble(object);
+        return result != null ? result : fallback;
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is an int or
+     * can be coerced to an int.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     * @throws JSONException if the value at {@code index} doesn't exist or
+     *                       cannot be coerced to a int.
+     */
+    public int getInt(int index) throws JSONException {
+        Object object = get(index);
+        Integer result = JSON.toInteger(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "int");
+        }
+        return result;
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is an int or
+     * can be coerced to an int. Returns 0 otherwise.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     */
+    public int optInt(int index) {
+        return optInt(index, 0);
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is an int or
+     * can be coerced to an int. Returns {@code fallback} otherwise.
+     *
+     * @param index    Which value to get.
+     * @param fallback The fallback value to use if no value is at the specified location.
+     * @return the value at the specified location or the fallback value.
+     */
+    public int optInt(int index, int fallback) {
+        Object object = opt(index);
+        Integer result = JSON.toInteger(object);
+        return result != null ? result : fallback;
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a long or
+     * can be coerced to a long.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     * @throws JSONException if the value at {@code index} doesn't exist or
+     *                       cannot be coerced to a long.
+     */
+    public long getLong(int index) throws JSONException {
+        Object object = get(index);
+        Long result = JSON.toLong(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "long");
+        }
+        return result;
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a long or
+     * can be coerced to a long. Returns 0 otherwise.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     */
+    public long optLong(int index) {
+        return optLong(index, 0L);
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a long or
+     * can be coerced to a long. Returns {@code fallback} otherwise.
+     *
+     * @param index    Which value to get.
+     * @param fallback The fallback value to use if no value is at the specified location.
+     * @return the value at the specified location or the fallback value.
+     */
+    public long optLong(int index, long fallback) {
+        Object object = opt(index);
+        Long result = JSON.toLong(object);
+        return result != null ? result : fallback;
+    }
 
-  /**
-   * The arrayList where the JSONArray's properties are kept.
-   */
-  private final ArrayList myArrayList;
-
-
-  /**
-   * Construct an empty JSONArray.
-   */
-  public JSONArray() {
-    this.myArrayList = new ArrayList();
-  }
-
-  /**
-   * Construct a JSONArray from a JSONTokener.
-   * 
-   * @param x A JSONTokener
-   * @throws JSONException If there is a syntax error.
-   */
-  public JSONArray(JSONTokener x) throws JSONException {
-    this();
-    if (x.nextClean() != '[') {
-      throw x.syntaxError("A JSONArray text must start with '['");
-    }
-    if (x.nextClean() != ']') {
-      x.back();
-      for (;;) {
-        if (x.nextClean() == ',') {
-          x.back();
-          this.myArrayList.add(JSONObject.NULL);
+    /**
+     * Returns the value at {@code index} if it exists, coercing it if
+     * necessary.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     * @throws JSONException if no such value exists.
+     */
+    public String getString(int index) throws JSONException {
+        Object object = get(index);
+        String result = JSON.toString(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "String");
+        }
+        return result;
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists, coercing it if
+     * necessary. Returns the empty string if no such value exists.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     */
+    public String optString(int index) {
+        return optString(index, "");
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists, coercing it if
+     * necessary. Returns {@code fallback} if no such value exists.
+     *
+     * @param index    Which value to get.
+     * @param fallback The fallback value to use if no value is at the specified location.
+     * @return the value at the specified location or the fallback value.
+     */
+    public String optString(int index, String fallback) {
+        Object object = opt(index);
+        String result = JSON.toString(object);
+        return result != null ? result : fallback;
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a {@code
+     * JSONArray}.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     * @throws JSONException if the value doesn't exist or is not a {@code
+     *                       JSONArray}.
+     */
+    public JSONArray getJSONArray(int index) throws JSONException {
+        Object object = get(index);
+        if (object instanceof JSONArray) {
+            return (JSONArray) object;
         } else {
-          x.back();
-          this.myArrayList.add(x.nextValue());
+            throw JSON.typeMismatch(index, object, "JSONArray");
         }
-        switch (x.nextClean()) {
-          case ';':
-          case ',':
-            if (x.nextClean() == ']') {
-              return;
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a {@code
+     * JSONArray}. Returns null otherwise.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     */
+    public JSONArray optJSONArray(int index) {
+        Object object = opt(index);
+        return object instanceof JSONArray ? (JSONArray) object : null;
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a {@code
+     * JSONObject}.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     * @throws JSONException if the value doesn't exist or is not a {@code
+     *                       JSONObject}.
+     */
+    public JSONObject getJSONObject(int index) throws JSONException {
+        Object object = get(index);
+        if (object instanceof JSONObject) {
+            return (JSONObject) object;
+        } else {
+            throw JSON.typeMismatch(index, object, "JSONObject");
+        }
+    }
+
+    /**
+     * Returns the value at {@code index} if it exists and is a {@code
+     * JSONObject}. Returns null otherwise.
+     *
+     * @param index Which value to get.
+     * @return the value at the specified location.
+     */
+    public JSONObject optJSONObject(int index) {
+        Object object = opt(index);
+        return object instanceof JSONObject ? (JSONObject) object : null;
+    }
+
+    /**
+     * Returns a new object whose values are the values in this array, and whose
+     * names are the values in {@code names}. Names and values are paired up by
+     * index from 0 through to the shorter array's length. Names that are not
+     * strings will be coerced to strings. This method returns null if either
+     * array is empty.
+     *
+     * @param names The names to apply to the returned values.
+     * @return the newly constructed object.
+     * @throws JSONException Should not be possible.
+     */
+    public JSONObject toJSONObject(JSONArray names) throws JSONException {
+        JSONObject result = new JSONObject();
+        int length = Math.min(names.length(), values.size());
+        if (length == 0) {
+            return null;
+        }
+        for (int i = 0; i < length; i++) {
+            String name = JSON.toString(names.opt(i));
+            result.put(name, opt(i));
+        }
+        return result;
+    }
+
+    /**
+     * Returns a new string by alternating this array's values with {@code
+     * separator}. This array's string values are quoted and have their special
+     * characters escaped. For example, the array containing the strings '12"
+     * pizza', 'taco' and 'soda' joined on '+' returns this:
+     * <pre>"12\" pizza"+"taco"+"soda"</pre>
+     *
+     * @param separator The string used to separate the returned values.
+     * @return the conjoined values.
+     * @throws JSONException Only if there is a coding error.
+     */
+    public String join(String separator) throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.open(JSONStringer.Scope.NULL, "");
+        for (int i = 0, size = values.size(); i < size; i++) {
+            if (i > 0) {
+                stringer.out.append(separator);
             }
-            x.back();
-            break;
-          case ']':
-            return;
-          default:
-            throw x.syntaxError("Expected a ',' or ']'");
+            stringer.value(values.get(i));
         }
-      }
-    }
-  }
-
-
-  /**
-   * Construct a JSONArray from a source JSON text.
-   * 
-   * @param source A string that begins with <code>[</code>&nbsp;<small>(left bracket)</small> and
-   *        ends with <code>]</code>&nbsp;<small>(right bracket)</small>.
-   * @throws JSONException If there is a syntax error.
-   */
-  public JSONArray(String source) throws JSONException {
-    this(new JSONTokener(source));
-  }
-
-
-  /**
-   * Construct a JSONArray from a Collection.
-   * 
-   * @param collection A Collection.
-   */
-  public JSONArray(Collection collection) {
-    this.myArrayList = new ArrayList();
-    if (collection != null) {
-      Iterator iter = collection.iterator();
-      while (iter.hasNext()) {
-        this.myArrayList.add(JSONObject.wrap(iter.next()));
-      }
-    }
-  }
-
-
-  /**
-   * Construct a JSONArray from an array
-   * 
-   * @throws JSONException If not an array.
-   */
-  public JSONArray(Object array) throws JSONException {
-    this();
-    if (array.getClass().isArray()) {
-      int length = Array.getLength(array);
-      for (int i = 0; i < length; i += 1) {
-        this.put(JSONObject.wrap(Array.get(array, i)));
-      }
-    } else {
-      throw new JSONException("JSONArray initial value should be a string or collection or array.");
-    }
-  }
-
-
-  /**
-   * Get the object value associated with an index.
-   * 
-   * @param index The index must be between 0 and length() - 1.
-   * @return An object value.
-   * @throws JSONException If there is no value for the index.
-   */
-  public Object get(int index) throws JSONException {
-    Object object = this.opt(index);
-    if (object == null) {
-      throw new JSONException("JSONArray[" + index + "] not found.");
-    }
-    return object;
-  }
-
-
-  /**
-   * Get the boolean value associated with an index. The string values "true" and "false" are
-   * converted to boolean.
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @return The truth.
-   * @throws JSONException If there is no value for the index or if the value is not convertible to
-   *         boolean.
-   */
-  public boolean getBoolean(int index) throws JSONException {
-    Object object = this.get(index);
-    if (object.equals(Boolean.FALSE)
-        || (object instanceof String && ((String) object).equalsIgnoreCase("false"))) {
-      return false;
-    } else if (object.equals(Boolean.TRUE)
-        || (object instanceof String && ((String) object).equalsIgnoreCase("true"))) {
-      return true;
-    }
-    throw new JSONException("JSONArray[" + index + "] is not a boolean.");
-  }
-
-
-  /**
-   * Get the double value associated with an index.
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @return The value.
-   * @throws JSONException If the key is not found or if the value cannot be converted to a number.
-   */
-  public double getDouble(int index) throws JSONException {
-    Object object = this.get(index);
-    try {
-      return object instanceof Number ? ((Number) object).doubleValue()
-          : Double.parseDouble((String) object);
-    } catch (Exception e) {
-      throw new JSONException("JSONArray[" + index + "] is not a number.");
-    }
-  }
-
-
-  /**
-   * Get the int value associated with an index.
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @return The value.
-   * @throws JSONException If the key is not found or if the value is not a number.
-   */
-  public int getInt(int index) throws JSONException {
-    Object object = this.get(index);
-    try {
-      return object instanceof Number ? ((Number) object).intValue()
-          : Integer.parseInt((String) object);
-    } catch (Exception e) {
-      throw new JSONException("JSONArray[" + index + "] is not a number.");
-    }
-  }
-
-
-  /**
-   * Get the JSONArray associated with an index.
-   * 
-   * @param index The index must be between 0 and length() - 1.
-   * @return A JSONArray value.
-   * @throws JSONException If there is no value for the index. or if the value is not a JSONArray
-   */
-  public JSONArray getJSONArray(int index) throws JSONException {
-    Object object = this.get(index);
-    if (object instanceof JSONArray) {
-      return (JSONArray) object;
-    }
-    throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
-  }
-
-
-  /**
-   * Get the JSONObject associated with an index.
-   * 
-   * @param index subscript
-   * @return A JSONObject value.
-   * @throws JSONException If there is no value for the index or if the value is not a JSONObject
-   */
-  public JSONObject getJSONObject(int index) throws JSONException {
-    Object object = this.get(index);
-    if (object instanceof JSONObject) {
-      return (JSONObject) object;
-    }
-    throw new JSONException("JSONArray[" + index + "] is not a JSONObject.");
-  }
-
-
-  /**
-   * Get the long value associated with an index.
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @return The value.
-   * @throws JSONException If the key is not found or if the value cannot be converted to a number.
-   */
-  public long getLong(int index) throws JSONException {
-    Object object = this.get(index);
-    try {
-      return object instanceof Number ? ((Number) object).longValue()
-          : Long.parseLong((String) object);
-    } catch (Exception e) {
-      throw new JSONException("JSONArray[" + index + "] is not a number.");
-    }
-  }
-
-
-  /**
-   * Get the string associated with an index.
-   * 
-   * @param index The index must be between 0 and length() - 1.
-   * @return A string value.
-   * @throws JSONException If there is no string value for the index.
-   */
-  public String getString(int index) throws JSONException {
-    Object object = this.get(index);
-    if (object instanceof String) {
-      return (String) object;
-    }
-    throw new JSONException("JSONArray[" + index + "] not a string.");
-  }
-
-
-  /**
-   * Determine if the value is null.
-   * 
-   * @param index The index must be between 0 and length() - 1.
-   * @return true if the value at the index is null, or if there is no value.
-   */
-  public boolean isNull(int index) {
-    return JSONObject.NULL.equals(this.opt(index));
-  }
-
-
-  /**
-   * Make a string from the contents of this JSONArray. The <code>separator</code> string is
-   * inserted between each element. Warning: This method assumes that the data structure is
-   * acyclical.
-   * 
-   * @param separator A string that will be inserted between the elements.
-   * @return a string.
-   * @throws JSONException If the array contains an invalid number.
-   */
-  public String join(String separator) throws JSONException {
-    int len = this.length();
-    StringBuffer sb = new StringBuffer();
-
-    for (int i = 0; i < len; i += 1) {
-      if (i > 0) {
-        sb.append(separator);
-      }
-      sb.append(JSONObject.valueToString(this.myArrayList.get(i)));
-    }
-    return sb.toString();
-  }
-
-
-  /**
-   * Get the number of elements in the JSONArray, included nulls.
-   *
-   * @return The length (or size).
-   */
-  public int length() {
-    return this.myArrayList.size();
-  }
-
-
-  /**
-   * Get the optional object value associated with an index.
-   * 
-   * @param index The index must be between 0 and length() - 1.
-   * @return An object value, or null if there is no object at that index.
-   */
-  public Object opt(int index) {
-    return (index < 0 || index >= this.length()) ? null : this.myArrayList.get(index);
-  }
-
-
-  /**
-   * Get the optional boolean value associated with an index. It returns false if there is no value
-   * at that index, or if the value is not Boolean.TRUE or the String "true".
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @return The truth.
-   */
-  public boolean optBoolean(int index) {
-    return this.optBoolean(index, false);
-  }
-
-
-  /**
-   * Get the optional boolean value associated with an index. It returns the defaultValue if there
-   * is no value at that index or if it is not a Boolean or the String "true" or "false" (case
-   * insensitive).
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @param defaultValue A boolean default.
-   * @return The truth.
-   */
-  public boolean optBoolean(int index, boolean defaultValue) {
-    try {
-      return this.getBoolean(index);
-    } catch (Exception e) {
-      return defaultValue;
-    }
-  }
-
-
-  /**
-   * Get the optional double value associated with an index. NaN is returned if there is no value
-   * for the index, or if the value is not a number and cannot be converted to a number.
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @return The value.
-   */
-  public double optDouble(int index) {
-    return this.optDouble(index, Double.NaN);
-  }
-
-
-  /**
-   * Get the optional double value associated with an index. The defaultValue is returned if there
-   * is no value for the index, or if the value is not a number and cannot be converted to a number.
-   *
-   * @param index subscript
-   * @param defaultValue The default value.
-   * @return The value.
-   */
-  public double optDouble(int index, double defaultValue) {
-    try {
-      return this.getDouble(index);
-    } catch (Exception e) {
-      return defaultValue;
-    }
-  }
-
-
-  /**
-   * Get the optional int value associated with an index. Zero is returned if there is no value for
-   * the index, or if the value is not a number and cannot be converted to a number.
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @return The value.
-   */
-  public int optInt(int index) {
-    return this.optInt(index, 0);
-  }
-
-
-  /**
-   * Get the optional int value associated with an index. The defaultValue is returned if there is
-   * no value for the index, or if the value is not a number and cannot be converted to a number.
-   * 
-   * @param index The index must be between 0 and length() - 1.
-   * @param defaultValue The default value.
-   * @return The value.
-   */
-  public int optInt(int index, int defaultValue) {
-    try {
-      return this.getInt(index);
-    } catch (Exception e) {
-      return defaultValue;
-    }
-  }
-
-
-  /**
-   * Get the optional JSONArray associated with an index.
-   * 
-   * @param index subscript
-   * @return A JSONArray value, or null if the index has no value, or if the value is not a
-   *         JSONArray.
-   */
-  public JSONArray optJSONArray(int index) {
-    Object o = this.opt(index);
-    return o instanceof JSONArray ? (JSONArray) o : null;
-  }
-
-
-  /**
-   * Get the optional JSONObject associated with an index. Null is returned if the key is not found,
-   * or null if the index has no value, or if the value is not a JSONObject.
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @return A JSONObject value.
-   */
-  public JSONObject optJSONObject(int index) {
-    Object o = this.opt(index);
-    return o instanceof JSONObject ? (JSONObject) o : null;
-  }
-
-
-  /**
-   * Get the optional long value associated with an index. Zero is returned if there is no value for
-   * the index, or if the value is not a number and cannot be converted to a number.
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @return The value.
-   */
-  public long optLong(int index) {
-    return this.optLong(index, 0);
-  }
-
-
-  /**
-   * Get the optional long value associated with an index. The defaultValue is returned if there is
-   * no value for the index, or if the value is not a number and cannot be converted to a number.
-   * 
-   * @param index The index must be between 0 and length() - 1.
-   * @param defaultValue The default value.
-   * @return The value.
-   */
-  public long optLong(int index, long defaultValue) {
-    try {
-      return this.getLong(index);
-    } catch (Exception e) {
-      return defaultValue;
-    }
-  }
-
-
-  /**
-   * Get the optional string value associated with an index. It returns an empty string if there is
-   * no value at that index. If the value is not a string and is not null, then it is coverted to a
-   * string.
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @return A String value.
-   */
-  public String optString(int index) {
-    return this.optString(index, "");
-  }
-
-
-  /**
-   * Get the optional string associated with an index. The defaultValue is returned if the key is
-   * not found.
-   *
-   * @param index The index must be between 0 and length() - 1.
-   * @param defaultValue The default value.
-   * @return A String value.
-   */
-  public String optString(int index, String defaultValue) {
-    Object object = this.opt(index);
-    return JSONObject.NULL.equals(object) ? defaultValue : object.toString();
-  }
-
-
-  /**
-   * Append a boolean value. This increases the array's length by one.
-   *
-   * @param value A boolean value.
-   * @return this.
-   */
-  public JSONArray put(boolean value) {
-    this.put(value ? Boolean.TRUE : Boolean.FALSE);
-    return this;
-  }
-
-
-  /**
-   * Put a value in the JSONArray, where the value will be a JSONArray which is produced from a
-   * Collection.
-   * 
-   * @param value A Collection value.
-   * @return this.
-   */
-  public JSONArray put(Collection value) {
-    this.put(new JSONArray(value));
-    return this;
-  }
-
-
-  /**
-   * Append a double value. This increases the array's length by one.
-   *
-   * @param value A double value.
-   * @throws JSONException if the value is not finite.
-   * @return this.
-   */
-  public JSONArray put(double value) throws JSONException {
-    Double d = new Double(value);
-    JSONObject.testValidity(d);
-    this.put(d);
-    return this;
-  }
-
-
-  /**
-   * Append an int value. This increases the array's length by one.
-   *
-   * @param value An int value.
-   * @return this.
-   */
-  public JSONArray put(int value) {
-    this.put(new Integer(value));
-    return this;
-  }
-
-
-  /**
-   * Append an long value. This increases the array's length by one.
-   *
-   * @param value A long value.
-   * @return this.
-   */
-  public JSONArray put(long value) {
-    this.put(new Long(value));
-    return this;
-  }
-
-
-  /**
-   * Put a value in the JSONArray, where the value will be a JSONObject which is produced from a
-   * Map.
-   * 
-   * @param value A Map value.
-   * @return this.
-   */
-  public JSONArray put(Map value) {
-    this.put(new JSONObject(value));
-    return this;
-  }
-
-
-  /**
-   * Append an object value. This increases the array's length by one.
-   * 
-   * @param value An object value. The value should be a Boolean, Double, Integer, JSONArray,
-   *        JSONObject, Long, or String, or the JSONObject.NULL object.
-   * @return this.
-   */
-  public JSONArray put(Object value) {
-    this.myArrayList.add(value);
-    return this;
-  }
-
-
-  /**
-   * Put or replace a boolean value in the JSONArray. If the index is greater than the length of the
-   * JSONArray, then null elements will be added as necessary to pad it out.
-   * 
-   * @param index The subscript.
-   * @param value A boolean value.
-   * @return this.
-   * @throws JSONException If the index is negative.
-   */
-  public JSONArray put(int index, boolean value) throws JSONException {
-    this.put(index, value ? Boolean.TRUE : Boolean.FALSE);
-    return this;
-  }
-
-
-  /**
-   * Put a value in the JSONArray, where the value will be a JSONArray which is produced from a
-   * Collection.
-   * 
-   * @param index The subscript.
-   * @param value A Collection value.
-   * @return this.
-   * @throws JSONException If the index is negative or if the value is not finite.
-   */
-  public JSONArray put(int index, Collection value) throws JSONException {
-    this.put(index, new JSONArray(value));
-    return this;
-  }
-
-
-  /**
-   * Put or replace a double value. If the index is greater than the length of the JSONArray, then
-   * null elements will be added as necessary to pad it out.
-   * 
-   * @param index The subscript.
-   * @param value A double value.
-   * @return this.
-   * @throws JSONException If the index is negative or if the value is not finite.
-   */
-  public JSONArray put(int index, double value) throws JSONException {
-    this.put(index, new Double(value));
-    return this;
-  }
-
-
-  /**
-   * Put or replace an int value. If the index is greater than the length of the JSONArray, then
-   * null elements will be added as necessary to pad it out.
-   * 
-   * @param index The subscript.
-   * @param value An int value.
-   * @return this.
-   * @throws JSONException If the index is negative.
-   */
-  public JSONArray put(int index, int value) throws JSONException {
-    this.put(index, new Integer(value));
-    return this;
-  }
-
-
-  /**
-   * Put or replace a long value. If the index is greater than the length of the JSONArray, then
-   * null elements will be added as necessary to pad it out.
-   * 
-   * @param index The subscript.
-   * @param value A long value.
-   * @return this.
-   * @throws JSONException If the index is negative.
-   */
-  public JSONArray put(int index, long value) throws JSONException {
-    this.put(index, new Long(value));
-    return this;
-  }
-
-
-  /**
-   * Put a value in the JSONArray, where the value will be a JSONObject that is produced from a Map.
-   * 
-   * @param index The subscript.
-   * @param value The Map value.
-   * @return this.
-   * @throws JSONException If the index is negative or if the the value is an invalid number.
-   */
-  public JSONArray put(int index, Map value) throws JSONException {
-    this.put(index, new JSONObject(value));
-    return this;
-  }
-
-
-  /**
-   * Put or replace an object value in the JSONArray. If the index is greater than the length of the
-   * JSONArray, then null elements will be added as necessary to pad it out.
-   * 
-   * @param index The subscript.
-   * @param value The value to put into the array. The value should be a Boolean, Double, Integer,
-   *        JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
-   * @return this.
-   * @throws JSONException If the index is negative or if the the value is an invalid number.
-   */
-  public JSONArray put(int index, Object value) throws JSONException {
-    JSONObject.testValidity(value);
-    if (index < 0) {
-      throw new JSONException("JSONArray[" + index + "] not found.");
-    }
-    if (index < this.length()) {
-      this.myArrayList.set(index, value);
-    } else {
-      while (index != this.length()) {
-        this.put(JSONObject.NULL);
-      }
-      this.put(value);
-    }
-    return this;
-  }
-
-
-  /**
-   * Remove an index and close the hole.
-   * 
-   * @param index The index of the element to be removed.
-   * @return The value that was associated with the index, or null if there was no value.
-   */
-  public Object remove(int index) {
-    Object o = this.opt(index);
-    this.myArrayList.remove(index);
-    return o;
-  }
-
-
-  /**
-   * Produce a JSONObject by combining a JSONArray of names with the values of this JSONArray.
-   * 
-   * @param names A JSONArray containing a list of key strings. These will be paired with the
-   *        values.
-   * @return A JSONObject, or null if there are no names or if this JSONArray has no values.
-   * @throws JSONException If any of the names are null.
-   */
-  public JSONObject toJSONObject(JSONArray names) throws JSONException {
-    if (names == null || names.length() == 0 || this.length() == 0) {
-      return null;
-    }
-    JSONObject jo = new JSONObject();
-    for (int i = 0; i < names.length(); i += 1) {
-      jo.put(names.getString(i), this.opt(i));
-    }
-    return jo;
-  }
-
-
-  /**
-   * Make a JSON text of this JSONArray. For compactness, no unnecessary whitespace is added. If it
-   * is not possible to produce a syntactically correct JSON text then null will be returned
-   * instead. This could occur if the array contains an invalid number.
-   * <p>
-   * Warning: This method assumes that the data structure is acyclical.
-   *
-   * @return a printable, displayable, transmittable representation of the array.
-   */
-  public String toString() {
-    try {
-      return '[' + this.join(",") + ']';
-    } catch (Exception e) {
-      return null;
-    }
-  }
-
-
-  /**
-   * Make a prettyprinted JSON text of this JSONArray. Warning: This method assumes that the data
-   * structure is acyclical.
-   * 
-   * @param indentFactor The number of spaces to add to each level of indentation.
-   * @return a printable, displayable, transmittable representation of the object, beginning with
-   *         <code>[</code>&nbsp;<small>(left bracket)</small> and ending with
-   *         <code>]</code>&nbsp;<small>(right bracket)</small>.
-   * @throws JSONException
-   */
-  public String toString(int indentFactor) throws JSONException {
-    StringWriter sw = new StringWriter();
-    synchronized (sw.getBuffer()) {
-      return this.write(sw, indentFactor, 0).toString();
-    }
-  }
-
-  /**
-   * Write the contents of the JSONArray as JSON text to a writer. For compactness, no whitespace is
-   * added.
-   * <p>
-   * Warning: This method assumes that the data structure is acyclical.
-   *
-   * @return The writer.
-   * @throws JSONException
-   */
-  public Writer write(Writer writer) throws JSONException {
-    return this.write(writer, 0, 0);
-  }
-
-  /**
-   * Write the contents of the JSONArray as JSON text to a writer. For compactness, no whitespace is
-   * added.
-   * <p>
-   * Warning: This method assumes that the data structure is acyclical.
-   *
-   * @param indentFactor The number of spaces to add to each level of indentation.
-   * @param indent The indention of the top level.
-   * @return The writer.
-   * @throws JSONException
-   */
-  Writer write(Writer writer, int indentFactor, int indent) throws JSONException {
-    try {
-      boolean commanate = false;
-      int length = this.length();
-      writer.write('[');
-
-      if (length == 1) {
-        JSONObject.writeValue(writer, this.myArrayList.get(0), indentFactor, indent);
-      } else if (length != 0) {
-        final int newindent = indent + indentFactor;
-
-        for (int i = 0; i < length; i += 1) {
-          if (commanate) {
-            writer.write(',');
-          }
-          if (indentFactor > 0) {
-            writer.write('\n');
-          }
-          JSONObject.indent(writer, newindent);
-          JSONObject.writeValue(writer, this.myArrayList.get(i), indentFactor, newindent);
-          commanate = true;
+        stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
+        return stringer.out.toString();
+    }
+
+    /**
+     * Encodes this array as a compact JSON string, such as:
+     * <pre>[94043,90210]</pre>
+     *
+     * @return The string form of this array.
+     */
+    @Override
+    public String toString() {
+        try {
+            JSONStringer stringer = new JSONStringer();
+            writeTo(stringer);
+            return stringer.toString();
+        } catch (JSONException e) {
+            return null;
         }
-        if (indentFactor > 0) {
-          writer.write('\n');
+    }
+
+    /**
+     * Encodes this array as a human readable JSON string for debugging, such
+     * as:
+     * <pre>
+     * [
+     *     94043,
+     *     90210
+     * ]</pre>
+     *
+     * @param indentSpaces the number of spaces to indent for each level of
+     *                     nesting.
+     * @return The string form of this array.
+     * @throws JSONException Only if there is a coding error.
+     */
+    public String toString(int indentSpaces) throws JSONException {
+        JSONStringer stringer = new JSONStringer(indentSpaces);
+        writeTo(stringer);
+        return stringer.toString();
+    }
+
+    void writeTo(JSONStringer stringer) throws JSONException {
+        stringer.array();
+        for (Object value : values) {
+            stringer.value(value);
         }
-        JSONObject.indent(writer, indent);
-      }
-      writer.write(']');
-      return writer;
-    } catch (IOException e) {
-      throw new JSONException(e);
-    }
-  }
+        stringer.endArray();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o instanceof JSONArray && ((JSONArray) o).values.equals(values);
+    }
+
+    @Override
+    public int hashCode() {
+        // diverge from the original, which doesn't implement hashCode
+        return values.hashCode();
+    }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/JSONException.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONException.java b/geode-json/src/main/java/org/json/JSONException.java
index b65efe2..1292e86 100755
--- a/geode-json/src/main/java/org/json/JSONException.java
+++ b/geode-json/src/main/java/org/json/JSONException.java
@@ -1,30 +1,57 @@
+/*
+ * 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.json;
 
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
 /**
- * The JSONException is thrown by the JSON.org classes when things are amiss.
- * 
- * @author JSON.org
- * @version 2010-12-24
+ * Thrown to indicate a problem with the JSON API. Such problems include:
+ * <ul>
+ *   <li>Attempts to parse or construct malformed documents
+ *   <li>Use of null as a name
+ *   <li>Use of numeric types not available to JSON, such as {@link
+ *       Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
+ *   <li>Lookups using an out of range index or nonexistent name
+ *   <li>Type mismatches on lookups
+ * </ul>
+ *
+ * <p>Although this is a checked exception, it is rarely recoverable. Most
+ * callers should simply wrap this exception in an unchecked exception and
+ * rethrow:
+ * <pre>  public JSONArray toJSONObject() {
+ *     try {
+ *         JSONObject result = new JSONObject();
+ *         ...
+ *     } catch (JSONException e) {
+ *         throw new RuntimeException(e);
+ *     }
+ * }</pre>
  */
-public class JSONException extends Exception {
-  private static final long serialVersionUID = 0;
-  private Throwable cause;
+public class JSONException extends RuntimeException {
 
-  /**
-   * Constructs a JSONException with an explanatory message.
-   * 
-   * @param message Detail about the reason for the exception.
-   */
-  public JSONException(String message) {
-    super(message);
-  }
+    public JSONException(String s) {
+        super(s);
+    }
 
-  public JSONException(Throwable cause) {
-    super(cause.getMessage());
-    this.cause = cause;
-  }
+    public JSONException(Throwable cause) {
+        super(cause);
+    }
 
-  public Throwable getCause() {
-    return this.cause;
-  }
+    public JSONException(String message, Throwable cause) {
+        super(message, cause);
+    }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/b3ec80bc/geode-json/src/main/java/org/json/JSONML.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONML.java b/geode-json/src/main/java/org/json/JSONML.java
deleted file mode 100755
index b535614..0000000
--- a/geode-json/src/main/java/org/json/JSONML.java
+++ /dev/null
@@ -1,454 +0,0 @@
-package org.json;
-
-/*
- * Copyright (c) 2008 JSON.org
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
- * associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- * 
- * The Software shall be used for Good, not Evil.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
- * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-import java.util.Iterator;
-
-
-/**
- * This provides static methods to convert an XML text into a JSONArray or JSONObject, and to covert
- * a JSONArray or JSONObject into an XML text using the JsonML transform.
- * 
- * @author JSON.org
- * @version 2012-03-28
- */
-public class JSONML {
-
-  /**
-   * Parse XML values and store them in a JSONArray.
-   * 
-   * @param x The XMLTokener containing the source string.
-   * @param arrayForm true if array form, false if object form.
-   * @param ja The JSONArray that is containing the current tag or null if we are at the outermost
-   *        level.
-   * @return A JSONArray if the value is the outermost tag, otherwise null.
-   * @throws JSONException
-   */
-  private static Object parse(XMLTokener x, boolean arrayForm, JSONArray ja) throws JSONException {
-    String attribute;
-    char c;
-    String closeTag = null;
-    int i;
-    JSONArray newja = null;
-    JSONObject newjo = null;
-    Object token;
-    String tagName = null;
-
-    // Test for and skip past these forms:
-    // <!-- ... -->
-    // <![ ... ]]>
-    // <! ... >
-    // <? ... ?>
-
-    while (true) {
-      if (!x.more()) {
-        throw x.syntaxError("Bad XML");
-      }
-      token = x.nextContent();
-      if (token == XML.LT) {
-        token = x.nextToken();
-        if (token instanceof Character) {
-          if (token == XML.SLASH) {
-
-            // Close tag </
-
-            token = x.nextToken();
-            if (!(token instanceof String)) {
-              throw new JSONException("Expected a closing name instead of '" + token + "'.");
-            }
-            if (x.nextToken() != XML.GT) {
-              throw x.syntaxError("Misshaped close tag");
-            }
-            return token;
-          } else if (token == XML.BANG) {
-
-            // <!
-
-            c = x.next();
-            if (c == '-') {
-              if (x.next() == '-') {
-                x.skipPast("-->");
-              } else {
-                x.back();
-              }
-            } else if (c == '[') {
-              token = x.nextToken();
-              if (token.equals("CDATA") && x.next() == '[') {
-                if (ja != null) {
-                  ja.put(x.nextCDATA());
-                }
-              } else {
-                throw x.syntaxError("Expected 'CDATA['");
-              }
-            } else {
-              i = 1;
-              do {
-                token = x.nextMeta();
-                if (token == null) {
-                  throw x.syntaxError("Missing '>' after '<!'.");
-                } else if (token == XML.LT) {
-                  i += 1;
-                } else if (token == XML.GT) {
-                  i -= 1;
-                }
-              } while (i > 0);
-            }
-          } else if (token == XML.QUEST) {
-
-            // <?
-
-            x.skipPast("?>");
-          } else {
-            throw x.syntaxError("Misshaped tag");
-          }
-
-          // Open tag <
-
-        } else {
-          if (!(token instanceof String)) {
-            throw x.syntaxError("Bad tagName '" + token + "'.");
-          }
-          tagName = (String) token;
-          newja = new JSONArray();
-          newjo = new JSONObject();
-          if (arrayForm) {
-            newja.put(tagName);
-            if (ja != null) {
-              ja.put(newja);
-            }
-          } else {
-            newjo.put("tagName", tagName);
-            if (ja != null) {
-              ja.put(newjo);
-            }
-          }
-          token = null;
-          for (;;) {
-            if (token == null) {
-              token = x.nextToken();
-            }
-            if (token == null) {
-              throw x.syntaxError("Misshaped tag");
-            }
-            if (!(token instanceof String)) {
-              break;
-            }
-
-            // attribute = value
-
-            attribute = (String) token;
-            if (!arrayForm && ("tagName".equals(attribute) || "childNode".equals(attribute))) {
-              throw x.syntaxError("Reserved attribute.");
-            }
-            token = x.nextToken();
-            if (token == XML.EQ) {
-              token = x.nextToken();
-              if (!(token instanceof String)) {
-                throw x.syntaxError("Missing value");
-              }
-              newjo.accumulate(attribute, XML.stringToValue((String) token));
-              token = null;
-            } else {
-              newjo.accumulate(attribute, "");
-            }
-          }
-          if (arrayForm && newjo.length() > 0) {
-            newja.put(newjo);
-          }
-
-          // Empty tag <.../>
-
-          if (token == XML.SLASH) {
-            if (x.nextToken() != XML.GT) {
-              throw x.syntaxError("Misshaped tag");
-            }
-            if (ja == null) {
-              if (arrayForm) {
-                return newja;
-              } else {
-                return newjo;
-              }
-            }
-
-            // Content, between <...> and </...>
-
-          } else {
-            if (token != XML.GT) {
-              throw x.syntaxError("Misshaped tag");
-            }
-            closeTag = (String) parse(x, arrayForm, newja);
-            if (closeTag != null) {
-              if (!closeTag.equals(tagName)) {
-                throw x.syntaxError("Mismatched '" + tagName + "' and '" + closeTag + "'");
-              }
-              tagName = null;
-              if (!arrayForm && newja.length() > 0) {
-                newjo.put("childNodes", newja);
-              }
-              if (ja == null) {
-                if (arrayForm) {
-                  return newja;
-                } else {
-                  return newjo;
-                }
-              }
-            }
-          }
-        }
-      } else {
-        if (ja != null) {
-          ja.put(token instanceof String ? XML.stringToValue((String) token) : token);
-        }
-      }
-    }
-  }
-
-
-  /**
-   * Convert a well-formed (but not necessarily valid) XML string into a JSONArray using the JsonML
-   * transform. Each XML tag is represented as a JSONArray in which the first element is the tag
-   * name. If the tag has attributes, then the second element will be JSONObject containing the
-   * name/value pairs. If the tag contains children, then strings and JSONArrays will represent the
-   * child tags. Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
-   * 
-   * @param string The source string.
-   * @return A JSONArray containing the structured data from the XML string.
-   * @throws JSONException
-   */
-  public static JSONArray toJSONArray(String string) throws JSONException {
-    return toJSONArray(new XMLTokener(string));
-  }
-
-
-  /**
-   * Convert a well-formed (but not necessarily valid) XML string into a JSONArray using the JsonML
-   * transform. Each XML tag is represented as a JSONArray in which the first element is the tag
-   * name. If the tag has attributes, then the second element will be JSONObject containing the
-   * name/value pairs. If the tag contains children, then strings and JSONArrays will represent the
-   * child content and tags. Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
-   * 
-   * @param x An XMLTokener.
-   * @return A JSONArray containing the structured data from the XML string.
-   * @throws JSONException
-   */
-  public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
-    return (JSONArray) parse(x, true, null);
-  }
-
-
-  /**
-   * Convert a well-formed (but not necessarily valid) XML string into a JSONObject using the JsonML
-   * transform. Each XML tag is represented as a JSONObject with a "tagName" property. If the tag
-   * has attributes, then the attributes will be in the JSONObject as properties. If the tag
-   * contains children, the object will have a "childNodes" property which will be an array of
-   * strings and JsonML JSONObjects.
-   * 
-   * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
-   * 
-   * @param x An XMLTokener of the XML source text.
-   * @return A JSONObject containing the structured data from the XML string.
-   * @throws JSONException
-   */
-  public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
-    return (JSONObject) parse(x, false, null);
-  }
-
-
-  /**
-   * Convert a well-formed (but not necessarily valid) XML string into a JSONObject using the JsonML
-   * transform. Each XML tag is represented as a JSONObject with a "tagName" property. If the tag
-   * has attributes, then the attributes will be in the JSONObject as properties. If the tag
-   * contains children, the object will have a "childNodes" property which will be an array of
-   * strings and JsonML JSONObjects.
-   * 
-   * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
-   * 
-   * @param string The XML source text.
-   * @return A JSONObject containing the structured data from the XML string.
-   * @throws JSONException
-   */
-  public static JSONObject toJSONObject(String string) throws JSONException {
-    return toJSONObject(new XMLTokener(string));
-  }
-
-
-  /**
-   * Reverse the JSONML transformation, making an XML text from a JSONArray.
-   * 
-   * @param ja A JSONArray.
-   * @return An XML string.
-   * @throws JSONException
-   */
-  public static String toString(JSONArray ja) throws JSONException {
-    int i;
-    JSONObject jo;
-    String key;
-    Iterator keys;
-    int length;
-    Object object;
-    StringBuffer sb = new StringBuffer();
-    String tagName;
-    String value;
-
-    // Emit <tagName
-
-    tagName = ja.getString(0);
-    XML.noSpace(tagName);
-    tagName = XML.escape(tagName);
-    sb.append('<');
-    sb.append(tagName);
-
-    object = ja.opt(1);
-    if (object instanceof JSONObject) {
-      i = 2;
-      jo = (JSONObject) object;
-
-      // Emit the attributes
-
-      keys = jo.keys();
-      while (keys.hasNext()) {
-        key = keys.next().toString();
-        XML.noSpace(key);
-        value = jo.optString(key);
-        if (value != null) {
-          sb.append(' ');
-          sb.append(XML.escape(key));
-          sb.append('=');
-          sb.append('"');
-          sb.append(XML.escape(value));
-          sb.append('"');
-        }
-      }
-    } else {
-      i = 1;
-    }
-
-    // Emit content in body
-
-    length = ja.length();
-    if (i >= length) {
-      sb.append('/');
-      sb.append('>');
-    } else {
-      sb.append('>');
-      do {
-        object = ja.get(i);
-        i += 1;
-        if (object != null) {
-          if (object instanceof String) {
-            sb.append(XML.escape(object.toString()));
-          } else if (object instanceof JSONObject) {
-            sb.append(toString((JSONObject) object));
-          } else if (object instanceof JSONArray) {
-            sb.append(toString((JSONArray) object));
-          }
-        }
-      } while (i < length);
-      sb.append('<');
-      sb.append('/');
-      sb.append(tagName);
-      sb.append('>');
-    }
-    return sb.toString();
-  }
-
-  /**
-   * Reverse the JSONML transformation, making an XML text from a JSONObject. The JSONObject must
-   * contain a "tagName" property. If it has children, then it must have a "childNodes" property
-   * containing an array of objects. The other properties are attributes with string values.
-   * 
-   * @param jo A JSONObject.
-   * @return An XML string.
-   * @throws JSONException
-   */
-  public static String toString(JSONObject jo) throws JSONException {
-    StringBuffer sb = new StringBuffer();
-    int i;
-    JSONArray ja;
-    String key;
-    Iterator keys;
-    int length;
-    Object object;
-    String tagName;
-    String value;
-
-    // Emit <tagName
-
-    tagName = jo.optString("tagName");
-    if (tagName == null) {
-      return XML.escape(jo.toString());
-    }
-    XML.noSpace(tagName);
-    tagName = XML.escape(tagName);
-    sb.append('<');
-    sb.append(tagName);
-
-    // Emit the attributes
-
-    keys = jo.keys();
-    while (keys.hasNext()) {
-      key = keys.next().toString();
-      if (!"tagName".equals(key) && !"childNodes".equals(key)) {
-        XML.noSpace(key);
-        value = jo.optString(key);
-        if (value != null) {
-          sb.append(' ');
-          sb.append(XML.escape(key));
-          sb.append('=');
-          sb.append('"');
-          sb.append(XML.escape(value));
-          sb.append('"');
-        }
-      }
-    }
-
-    // Emit content in body
-
-    ja = jo.optJSONArray("childNodes");
-    if (ja == null) {
-      sb.append('/');
-      sb.append('>');
-    } else {
-      sb.append('>');
-      length = ja.length();
-      for (i = 0; i < length; i += 1) {
-        object = ja.get(i);
-        if (object != null) {
-          if (object instanceof String) {
-            sb.append(XML.escape(object.toString()));
-          } else if (object instanceof JSONObject) {
-            sb.append(toString((JSONObject) object));
-          } else if (object instanceof JSONArray) {
-            sb.append(toString((JSONArray) object));
-          } else {
-            sb.append(object.toString());
-          }
-        }
-      }
-      sb.append('<');
-      sb.append('/');
-      sb.append(tagName);
-      sb.append('>');
-    }
-    return sb.toString();
-  }
-}


[8/8] geode git commit: GEODE-2142: Spotless

Posted by ud...@apache.org.
GEODE-2142: Spotless


Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/2e3a88f7
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/2e3a88f7
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/2e3a88f7

Branch: refs/heads/develop
Commit: 2e3a88f7bc61796042140aa92b44390b9970b53e
Parents: b3ec80b
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Fri Feb 17 13:00:29 2017 -0800
Committer: Udo Kohlmeyer <uk...@pivotal.io>
Committed: Fri Feb 17 13:00:29 2017 -0800

----------------------------------------------------------------------
 .../cli/functions/ExportConfigFunction.java     |    2 +-
 .../internal/cli/json/GfJsonObject.java         |   36 +-
 .../internal/cli/result/AbstractResultData.java |    7 +-
 .../cli/commands/CliCommandTestBase.java        |    2 +-
 geode-json/src/main/java/org/json/JSON.java     |  176 ++-
 .../src/main/java/org/json/JSONArray.java       | 1458 +++++++++---------
 .../src/main/java/org/json/JSONException.java   |   59 +-
 .../src/main/java/org/json/JSONObject.java      |  416 ++---
 .../src/main/java/org/json/JSONString.java      |   17 +-
 .../src/main/java/org/json/JSONStringer.java    |  779 +++++-----
 .../src/main/java/org/json/JSONTokener.java     | 1149 +++++++-------
 11 files changed, 2040 insertions(+), 2061 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
index 64bc374..4e92623 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportConfigFunction.java
@@ -95,7 +95,7 @@ public class ExportConfigFunction implements Function, InternalEntity {
       }
       CliFunctionResult result = new CliFunctionResult(memberId,
           new String[] {xmlWriter.toString(), propStringBuf.toString()});
-      System.err.println("ExportConfigFunction.execute CLI function result: "+result);
+      System.err.println("ExportConfigFunction.execute CLI function result: " + result);
       context.getResultSender().lastResult(result);
     } catch (CacheClosedException cce) {
       CliFunctionResult result = new CliFunctionResult(memberId, false, null);

http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
index 9137f72..8b7e004 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/json/GfJsonObject.java
@@ -72,9 +72,9 @@ public class GfJsonObject {
     }
   }
 
-//  public GfJsonObject(Object bean, String[] paramNames) {
-//    this.jsonObject = new JSONObject(bean, paramNames);
-//  }
+  // public GfJsonObject(Object bean, String[] paramNames) {
+  // this.jsonObject = new JSONObject(bean, paramNames);
+  // }
 
   /**
    * 
@@ -237,21 +237,21 @@ public class GfJsonObject {
     return this;
   }
 
-//  /**
-//   *
-//   * @param key
-//   * @param value
-//   * @return this GfJsonObject
-//   * @throws GfJsonException if the key is a duplicate
-//   */
-//  public GfJsonObject putOnce(String key, Object value) throws GfJsonException {
-//    try {
-//      jsonObject.putOnce(key, value);
-//    } catch (JSONException e) {
-//      throw new GfJsonException(e.getMessage());
-//    }
-//    return this;
-//  }
+  // /**
+  // *
+  // * @param key
+  // * @param value
+  // * @return this GfJsonObject
+  // * @throws GfJsonException if the key is a duplicate
+  // */
+  // public GfJsonObject putOnce(String key, Object value) throws GfJsonException {
+  // try {
+  // jsonObject.putOnce(key, value);
+  // } catch (JSONException e) {
+  // throw new GfJsonException(e.getMessage());
+  // }
+  // return this;
+  // }
 
   /**
    * 

http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
index 81ab511..f453ec6 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/result/AbstractResultData.java
@@ -175,8 +175,9 @@ public abstract class AbstractResultData implements ResultData {
       sectionData.put(FILE_TYPE_FIELD, fileType);
       sectionData.put(FILE_MESSAGE, message);
       DeflaterInflaterData deflaterInflaterData = CliUtil.compressBytes(data);
-      sectionData.put(FILE_DATA_FIELD, Base64.getEncoder().encodeToString(deflaterInflaterData.getData()));
-      sectionData.put(DATA_LENGTH_FIELD,deflaterInflaterData.getDataLength());
+      sectionData.put(FILE_DATA_FIELD,
+          Base64.getEncoder().encodeToString(deflaterInflaterData.getData()));
+      sectionData.put(DATA_LENGTH_FIELD, deflaterInflaterData.getDataLength());
     } catch (GfJsonException e) {
       throw new ResultDataException(e.getMessage());
     }
@@ -231,7 +232,7 @@ public abstract class AbstractResultData implements ResultData {
       String fileDataString = (String) object.get(FILE_DATA_FIELD);
       int fileDataLength = (int) object.get(DATA_LENGTH_FIELD);
       byte[] byteArray = Base64.getDecoder().decode(fileDataString);
-      byte[] uncompressBytes = CliUtil.uncompressBytes(byteArray,fileDataLength).getData();
+      byte[] uncompressBytes = CliUtil.uncompressBytes(byteArray, fileDataLength).getData();
 
       boolean isGfshVM = CliUtil.isGfshVM();
       File fileToDumpData = new File(fileName);

http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
index 239810b..662ff4d 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/CliCommandTestBase.java
@@ -365,7 +365,7 @@ public abstract class CliCommandTestBase extends JUnit4CacheTestCase {
         System.err.println("result1 = " + result1);
       }
       result = (CommandResult) result1; // TODO: this can result in ClassCastException if
-                                                  // command resulted in error
+                                        // command resulted in error
     } catch (InterruptedException ex) {
       error("shell received InterruptedException");
     }

http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/geode-json/src/main/java/org/json/JSON.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSON.java b/geode-json/src/main/java/org/json/JSON.java
index 1b32e69..7105cab 100755
--- a/geode-json/src/main/java/org/json/JSON.java
+++ b/geode-json/src/main/java/org/json/JSON.java
@@ -1,116 +1,112 @@
 /*
  * 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
+ * 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
+ * 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.
+ * 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.json;
 
 class JSON {
-    /**
-     * Returns the input if it is a JSON-permissible value; throws otherwise.
-     */
-    static double checkDouble(double d) throws JSONException {
-        if (Double.isInfinite(d) || Double.isNaN(d)) {
-            throw new JSONException("Forbidden numeric value: " + d);
-        }
-        return d;
+  /**
+   * Returns the input if it is a JSON-permissible value; throws otherwise.
+   */
+  static double checkDouble(double d) throws JSONException {
+    if (Double.isInfinite(d) || Double.isNaN(d)) {
+      throw new JSONException("Forbidden numeric value: " + d);
     }
+    return d;
+  }
 
-    static Boolean toBoolean(Object value) {
-        if (value instanceof Boolean) {
-            return (Boolean) value;
-        } else if (value instanceof String) {
-            String stringValue = (String) value;
-            if ("true".equalsIgnoreCase(stringValue)) {
-                return true;
-            } else if ("false".equalsIgnoreCase(stringValue)) {
-                return false;
-            }
-        }
-        return null;
+  static Boolean toBoolean(Object value) {
+    if (value instanceof Boolean) {
+      return (Boolean) value;
+    } else if (value instanceof String) {
+      String stringValue = (String) value;
+      if ("true".equalsIgnoreCase(stringValue)) {
+        return true;
+      } else if ("false".equalsIgnoreCase(stringValue)) {
+        return false;
+      }
     }
+    return null;
+  }
 
-    static Double toDouble(Object value) {
-        if (value instanceof Double) {
-            return (Double) value;
-        } else if (value instanceof Number) {
-            return ((Number) value).doubleValue();
-        } else if (value instanceof String) {
-            try {
-                return Double.valueOf((String) value);
-            } catch (NumberFormatException ignored) {
-            }
-        }
-        return null;
+  static Double toDouble(Object value) {
+    if (value instanceof Double) {
+      return (Double) value;
+    } else if (value instanceof Number) {
+      return ((Number) value).doubleValue();
+    } else if (value instanceof String) {
+      try {
+        return Double.valueOf((String) value);
+      } catch (NumberFormatException ignored) {
+      }
     }
+    return null;
+  }
 
-    static Integer toInteger(Object value) {
-        if (value instanceof Integer) {
-            return (Integer) value;
-        } else if (value instanceof Number) {
-            return ((Number) value).intValue();
-        } else if (value instanceof String) {
-            try {
-                return (int) Double.parseDouble((String) value);
-            } catch (NumberFormatException ignored) {
-            }
-        }
-        return null;
+  static Integer toInteger(Object value) {
+    if (value instanceof Integer) {
+      return (Integer) value;
+    } else if (value instanceof Number) {
+      return ((Number) value).intValue();
+    } else if (value instanceof String) {
+      try {
+        return (int) Double.parseDouble((String) value);
+      } catch (NumberFormatException ignored) {
+      }
     }
+    return null;
+  }
 
-    static Long toLong(Object value) {
-        if (value instanceof Long) {
-            return (Long) value;
-        } else if (value instanceof Number) {
-            return ((Number) value).longValue();
-        } else if (value instanceof String) {
-            try {
-                return (long) Double.parseDouble((String) value);
-            } catch (NumberFormatException ignored) {
-            }
-        }
-        return null;
+  static Long toLong(Object value) {
+    if (value instanceof Long) {
+      return (Long) value;
+    } else if (value instanceof Number) {
+      return ((Number) value).longValue();
+    } else if (value instanceof String) {
+      try {
+        return (long) Double.parseDouble((String) value);
+      } catch (NumberFormatException ignored) {
+      }
     }
+    return null;
+  }
 
-    static String toString(Object value) {
-        if (value instanceof String) {
-            return (String) value;
-        } else if (value != null) {
-            return String.valueOf(value);
-        }
-        return null;
+  static String toString(Object value) {
+    if (value instanceof String) {
+      return (String) value;
+    } else if (value != null) {
+      return String.valueOf(value);
     }
+    return null;
+  }
 
-    public static JSONException typeMismatch(Object indexOrName, Object actual,
-            String requiredType) throws JSONException {
-        if (actual == null) {
-            throw new JSONException("Value at " + indexOrName + " is null.");
-        } else {
-            throw new JSONException("Value " + actual + " at " + indexOrName
-                    + " of type " + actual.getClass().getName()
-                    + " cannot be converted to " + requiredType);
-        }
+  public static JSONException typeMismatch(Object indexOrName, Object actual, String requiredType)
+      throws JSONException {
+    if (actual == null) {
+      throw new JSONException("Value at " + indexOrName + " is null.");
+    } else {
+      throw new JSONException("Value " + actual + " at " + indexOrName + " of type "
+          + actual.getClass().getName() + " cannot be converted to " + requiredType);
     }
+  }
 
-    public static JSONException typeMismatch(Object actual, String requiredType)
-            throws JSONException {
-        if (actual == null) {
-            throw new JSONException("Value is null.");
-        } else {
-            throw new JSONException("Value " + actual
-                    + " of type " + actual.getClass().getName()
-                    + " cannot be converted to " + requiredType);
-        }
+  public static JSONException typeMismatch(Object actual, String requiredType)
+      throws JSONException {
+    if (actual == null) {
+      throw new JSONException("Value is null.");
+    } else {
+      throw new JSONException("Value " + actual + " of type " + actual.getClass().getName()
+          + " cannot be converted to " + requiredType);
     }
+  }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/geode-json/src/main/java/org/json/JSONArray.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONArray.java b/geode-json/src/main/java/org/json/JSONArray.java
index 074624d..c961139 100755
--- a/geode-json/src/main/java/org/json/JSONArray.java
+++ b/geode-json/src/main/java/org/json/JSONArray.java
@@ -1,17 +1,15 @@
 /*
  * 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
+ * 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
+ * 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.
+ * 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.json;
@@ -24,736 +22,726 @@ import java.util.List;
 // Note: this class was written without inspecting the non-free org.json sourcecode.
 
 /**
- * A dense indexed sequence of values. Values may be any mix of
- * {@link JSONObject JSONObjects}, other {@link JSONArray JSONArrays}, Strings,
- * Booleans, Integers, Longs, Doubles, {@code null} or {@link JSONObject#NULL}.
- * Values may not be {@link Double#isNaN() NaNs}, {@link Double#isInfinite()
- * infinities}, or of any type not listed here.
+ * A dense indexed sequence of values. Values may be any mix of {@link JSONObject JSONObjects},
+ * other {@link JSONArray JSONArrays}, Strings, Booleans, Integers, Longs, Doubles, {@code null} or
+ * {@link JSONObject#NULL}. Values may not be {@link Double#isNaN() NaNs},
+ * {@link Double#isInfinite() infinities}, or of any type not listed here.
  *
- * {@code JSONArray} has the same type coercion behavior and
- * optional/mandatory accessors as {@link JSONObject}. See that class'
- * documentation for details.
+ * {@code JSONArray} has the same type coercion behavior and optional/mandatory accessors as
+ * {@link JSONObject}. See that class' documentation for details.
  *
- * <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, {@code get} fails if the requested index
- * holds the null reference, but succeeds if it holds {@code JSONObject.NULL}.
+ * <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,
+ * {@code get} fails if the requested index holds the null reference, but succeeds if it holds
+ * {@code JSONObject.NULL}.
  *
- * Instances of this class are not thread safe. Although this class is
- * non-final, it was not designed for inheritance and should not be subclassed.
- * In particular, self-use by overridable methods is not specified. See
- * <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
- * prohibit it" for further information.
+ * Instances of this class are not thread safe. Although this class is non-final, it was not
+ * designed for inheritance and should not be subclassed. In particular, self-use by overridable
+ * methods is not specified. See <i>Effective Java</i> Item 17, "Design and Document or inheritance
+ * or else prohibit it" for further information.
  */
 public class JSONArray {
 
-    private final List<Object> values;
-
-    /**
-     * Creates a {@code JSONArray} with no values.
-     */
-    public JSONArray() {
-        values = new ArrayList<Object>();
-    }
-
-    /**
-     * Creates a new {@code JSONArray} by copying all values from the given
-     * collection.
-     *
-     * @param copyFrom a collection whose values are of supported types.
-     *                 Unsupported values are not permitted and will yield an array in an
-     *                 inconsistent state.
-     */
-    /* Accept a raw type for API compatibility */
-    public JSONArray(Collection<?> copyFrom) {
-        this();
-        if (copyFrom != null) {
-            for (Object aCopyFrom : copyFrom) {
-                put(JSONObject.wrap(aCopyFrom));
-            }
-        }
-    }
-
-    /**
-     * Creates a new {@code JSONArray} with values from the next array in the
-     * tokener.
-     *
-     * @param readFrom a tokener whose nextValue() method will yield a
-     *                 {@code JSONArray}.
-     * @throws JSONException if the parse fails or doesn't yield a
-     *                       {@code JSONArray}.
-     */
-    public JSONArray(JSONTokener readFrom) throws JSONException {
-        /*
-         * Getting the parser to populate this could get tricky. Instead, just
-         * parse to temporary JSONArray and then steal the data from that.
-         */
-        Object object = readFrom.nextValue();
-        if (object instanceof JSONArray) {
-            values = ((JSONArray) object).values;
-        } else {
-            throw JSON.typeMismatch(object, "JSONArray");
-        }
-    }
-
-    /**
-     * Creates a new {@code JSONArray} with values from the JSON string.
-     *
-     * @param json a JSON-encoded string containing an array.
-     * @throws JSONException if the parse fails or doesn't yield a {@code
-     *                       JSONArray}.
-     */
-    public JSONArray(String json) throws JSONException {
-        this(new JSONTokener(json));
-    }
-
-    /**
-     * Creates a new {@code JSONArray} with values from the given primitive array.
-     *
-     * @param array The values to use.
-     * @throws JSONException if any of the values are non-finite double values (i.e. NaN or infinite)
-     */
-    public JSONArray(Object array) throws JSONException {
-        if (!array.getClass().isArray()) {
-            throw new JSONException("Not a primitive array: " + array.getClass());
-        }
-        final int length = Array.getLength(array);
-        values = new ArrayList<Object>(length);
-        for (int i = 0; i < length; ++i) {
-            put(JSONObject.wrap(Array.get(array, i)));
-        }
-    }
-
-    /**
-     * @return Returns the number of values in this array.
-     */
-    public int length() {
-        return values.size();
-    }
-
-    /**
-     * Appends {@code value} to the end of this array.
-     *
-     * @param value The value to append.
-     * @return this array.
-     */
-    public JSONArray put(boolean value) {
-        values.add(value);
-        return this;
-    }
-
-    /**
-     * Appends {@code value} to the end of this array.
-     *
-     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
-     *              {@link Double#isInfinite() infinities}.
-     * @return this array.
-     * @throws JSONException If the value is unacceptable.
-     */
-    public JSONArray put(double value) throws JSONException {
-        values.add(JSON.checkDouble(value));
-        return this;
-    }
-
-    /**
-     * Appends {@code value} to the end of this array.
-     *
-     * @param value The value to append.
-     * @return this array.
-     */
-    public JSONArray put(int value) {
-        values.add(value);
-        return this;
-    }
-
-    /**
-     * Appends {@code value} to the end of this array.
-     *
-     * @param value The value to append.
-     * @return this array.
-     */
-    public JSONArray put(long value) {
-        values.add(value);
-        return this;
-    }
-
-    /**
-     * Appends {@code value} wrapped by {@link JSONArray} to the end of this array.
-     *
-     * @param value any collection.
-     * @return this array.
-     */
-    public JSONArray put(Collection<?> value) {
-        if (value == null) {
-            return put((Object)null);
-        }
-        values.add(new JSONArray(value));
-        return this;
-    }
-
-    /**
-     * Appends {@code value} to the end of this array.
-     *
-     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
-     *              Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
-     *              not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
-     *              infinities}. Unsupported values are not permitted and will cause the
-     *              array to be in an inconsistent state.
-     * @return this array.
-     */
-    public JSONArray put(Object value) {
-        values.add(value);
-        return this;
-    }
-
-    /**
-     * Same as {@link #put}, with added validity checks.
-     *
-     * @param value The value to append.
-     */
-    void checkedPut(Object value) throws JSONException {
-        if (value instanceof Number) {
-            JSON.checkDouble(((Number) value).doubleValue());
-        }
-
-        put(value);
-    }
-
-    /**
-     * Sets the value at {@code index} to {@code value}, null padding this array
-     * to the required length if necessary. If a value already exists at {@code
-     * index}, it will be replaced.
-     *
-     * @param index Where to put the value.
-     * @param value The value to set.
-     * @return this array.
-     * @throws JSONException This should never happen.
-     */
-    public JSONArray put(int index, boolean value) throws JSONException {
-        return put(index, (Boolean) value);
-    }
-
-    /**
-     * Sets the value at {@code index} to {@code value}, null padding this array
-     * to the required length if necessary. If a value already exists at {@code
-     * index}, it will be replaced.
-     *
-     * @param index Where to put the value.
-     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
-     *              {@link Double#isInfinite() infinities}.
-     * @return this array.
-     * @throws JSONException If the value is not a finite value.
-     */
-    public JSONArray put(int index, double value) throws JSONException {
-        return put(index, (Double) value);
-    }
-
-    /**
-     * Sets the value at {@code index} to {@code value}, null padding this array
-     * to the required length if necessary. If a value already exists at {@code
-     * index}, it will be replaced.
-     *
-     * @param index Where to put the value.
-     * @param value The value to set.
-     * @return this array.
-     * @throws JSONException Should never actually happen.
-     */
-    public JSONArray put(int index, int value) throws JSONException {
-        return put(index, (Integer) value);
-    }
-
-    /**
-     * Sets the value at {@code index} to {@code value}, null padding this array
-     * to the required length if necessary. If a value already exists at {@code
-     * index}, it will be replaced.
-     *
-     * @param index Where to put the value.
-     * @param value The value to set.
-     * @return this array.
-     * @throws JSONException Should never actually happen.
-     */
-    public JSONArray put(int index, long value) throws JSONException {
-        return put(index, (Long) value);
-    }
-
-    /**
-     * Sets the value at {@code index} to {@code value} wrapped into {@link JSONArray},
-     * null padding this array to the required length if necessary. If a value already
-     * exists at {@code index}, it will be replaced.
-     *
-     * @param index Where to put the value.
-     * @param value The value to set.
-     * @return this array.
-     * @throws JSONException Should never actually happen.
-     */
-    public JSONArray put(int index, Collection<?> value) throws JSONException {
-        if (value == null) {
-            return put(index, (Object)null);
-        }
-        return put(index, new JSONArray(value));
-    }
-
-    /**
-     * Sets the value at {@code index} to {@code value}, null padding this array
-     * to the required length if necessary. If a value already exists at {@code
-     * index}, it will be replaced.
-     *
-     * @param index Where to put the value.
-     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
-     *              Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
-     *              not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
-     *              infinities}.
-     * @return this array.
-     * @throws JSONException If the value cannot be represented as a finite double value.
-     */
-    public JSONArray put(int index, Object value) throws JSONException {
-        if (value instanceof Number) {
-            // deviate from the original by checking all Numbers, not just floats & doubles
-            JSON.checkDouble(((Number) value).doubleValue());
-        }
-        while (values.size() <= index) {
-            values.add(null);
-        }
-        values.set(index, value);
-        return this;
-    }
-
-    /**
-     * Returns true if this array has no value at {@code index}, or if its value
-     * is the {@code null} reference or {@link JSONObject#NULL}.
-     *
-     * @param index Which value to check.
-     * @return true if the value is null.
-     */
-    public boolean isNull(int index) {
-        Object value = opt(index);
-        return value == null || value == JSONObject.NULL;
-    }
-
-    /**
-     * Returns the value at {@code index}.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     * @throws JSONException if this array has no value at {@code index}, or if
-     *                       that value is the {@code null} reference. This method returns
-     *                       normally if the value is {@code JSONObject#NULL}.
-     */
-    public Object get(int index) throws JSONException {
-        try {
-            Object value = values.get(index);
-            if (value == null) {
-                throw new JSONException("Value at " + index + " is null.");
-            }
-            return value;
-        } catch (IndexOutOfBoundsException e) {
-            throw new JSONException("Index " + index + " out of range [0.." + values.size() + ")");
-        }
-    }
-
-    /**
-     * Returns the value at {@code index}, or null if the array has no value
-     * at {@code index}.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     */
-    public Object opt(int index) {
-        if (index < 0 || index >= values.size()) {
-            return null;
-        }
-        return values.get(index);
-    }
-
-    /**
-     * Removes and returns the value at {@code index}, or null if the array has no value
-     * at {@code index}.
-     *
-     * @param index Which value to remove.
-     * @return The value previously at the specified location.
-     */
-    public Object remove(int index) {
-        if (index < 0 || index >= values.size()) {
-            return null;
-        }
-        return values.remove(index);
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a boolean or can
-     * be coerced to a boolean.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     * @throws JSONException if the value at {@code index} doesn't exist or
-     *                       cannot be coerced to a boolean.
-     */
-    public boolean getBoolean(int index) throws JSONException {
-        Object object = get(index);
-        Boolean result = JSON.toBoolean(object);
-        if (result == null) {
-            throw JSON.typeMismatch(index, object, "boolean");
-        }
-        return result;
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a boolean or can
-     * be coerced to a boolean. Returns false otherwise.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     */
-    public boolean optBoolean(int index) {
-        return optBoolean(index, false);
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a boolean or can
-     * be coerced to a boolean. Returns {@code fallback} otherwise.
-     *
-     * @param index    Which value to get.
-     * @param fallback the fallback value to return if no value exists.
-     * @return the value at the specified location or the fallback value.
-     */
-    public boolean optBoolean(int index, boolean fallback) {
-        Object object = opt(index);
-        Boolean result = JSON.toBoolean(object);
-        return result != null ? result : fallback;
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a double or can
-     * be coerced to a double.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     * @throws JSONException if the value at {@code index} doesn't exist or
-     *                       cannot be coerced to a double.
-     */
-    public double getDouble(int index) throws JSONException {
-        Object object = get(index);
-        Double result = JSON.toDouble(object);
-        if (result == null) {
-            throw JSON.typeMismatch(index, object, "double");
-        }
-        return result;
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a double or can
-     * be coerced to a double. Returns {@code NaN} otherwise.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     */
-    public double optDouble(int index) {
-        return optDouble(index, Double.NaN);
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a double or can
-     * be coerced to a double. Returns {@code fallback} otherwise.
-     *
-     * @param index    Which value to get.
-     * @param fallback The fallback value to use if no value is at the specified location.
-     * @return the value at the specified location or the fallback value.
-     */
-    public double optDouble(int index, double fallback) {
-        Object object = opt(index);
-        Double result = JSON.toDouble(object);
-        return result != null ? result : fallback;
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is an int or
-     * can be coerced to an int.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     * @throws JSONException if the value at {@code index} doesn't exist or
-     *                       cannot be coerced to a int.
-     */
-    public int getInt(int index) throws JSONException {
-        Object object = get(index);
-        Integer result = JSON.toInteger(object);
-        if (result == null) {
-            throw JSON.typeMismatch(index, object, "int");
-        }
-        return result;
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is an int or
-     * can be coerced to an int. Returns 0 otherwise.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     */
-    public int optInt(int index) {
-        return optInt(index, 0);
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is an int or
-     * can be coerced to an int. Returns {@code fallback} otherwise.
-     *
-     * @param index    Which value to get.
-     * @param fallback The fallback value to use if no value is at the specified location.
-     * @return the value at the specified location or the fallback value.
-     */
-    public int optInt(int index, int fallback) {
-        Object object = opt(index);
-        Integer result = JSON.toInteger(object);
-        return result != null ? result : fallback;
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a long or
-     * can be coerced to a long.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     * @throws JSONException if the value at {@code index} doesn't exist or
-     *                       cannot be coerced to a long.
-     */
-    public long getLong(int index) throws JSONException {
-        Object object = get(index);
-        Long result = JSON.toLong(object);
-        if (result == null) {
-            throw JSON.typeMismatch(index, object, "long");
-        }
-        return result;
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a long or
-     * can be coerced to a long. Returns 0 otherwise.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     */
-    public long optLong(int index) {
-        return optLong(index, 0L);
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a long or
-     * can be coerced to a long. Returns {@code fallback} otherwise.
-     *
-     * @param index    Which value to get.
-     * @param fallback The fallback value to use if no value is at the specified location.
-     * @return the value at the specified location or the fallback value.
-     */
-    public long optLong(int index, long fallback) {
-        Object object = opt(index);
-        Long result = JSON.toLong(object);
-        return result != null ? result : fallback;
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists, coercing it if
-     * necessary.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     * @throws JSONException if no such value exists.
-     */
-    public String getString(int index) throws JSONException {
-        Object object = get(index);
-        String result = JSON.toString(object);
-        if (result == null) {
-            throw JSON.typeMismatch(index, object, "String");
-        }
-        return result;
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists, coercing it if
-     * necessary. Returns the empty string if no such value exists.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     */
-    public String optString(int index) {
-        return optString(index, "");
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists, coercing it if
-     * necessary. Returns {@code fallback} if no such value exists.
-     *
-     * @param index    Which value to get.
-     * @param fallback The fallback value to use if no value is at the specified location.
-     * @return the value at the specified location or the fallback value.
-     */
-    public String optString(int index, String fallback) {
-        Object object = opt(index);
-        String result = JSON.toString(object);
-        return result != null ? result : fallback;
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a {@code
-     * JSONArray}.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     * @throws JSONException if the value doesn't exist or is not a {@code
-     *                       JSONArray}.
-     */
-    public JSONArray getJSONArray(int index) throws JSONException {
-        Object object = get(index);
-        if (object instanceof JSONArray) {
-            return (JSONArray) object;
-        } else {
-            throw JSON.typeMismatch(index, object, "JSONArray");
-        }
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a {@code
-     * JSONArray}. Returns null otherwise.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     */
-    public JSONArray optJSONArray(int index) {
-        Object object = opt(index);
-        return object instanceof JSONArray ? (JSONArray) object : null;
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a {@code
-     * JSONObject}.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     * @throws JSONException if the value doesn't exist or is not a {@code
-     *                       JSONObject}.
-     */
-    public JSONObject getJSONObject(int index) throws JSONException {
-        Object object = get(index);
-        if (object instanceof JSONObject) {
-            return (JSONObject) object;
-        } else {
-            throw JSON.typeMismatch(index, object, "JSONObject");
-        }
-    }
-
-    /**
-     * Returns the value at {@code index} if it exists and is a {@code
-     * JSONObject}. Returns null otherwise.
-     *
-     * @param index Which value to get.
-     * @return the value at the specified location.
-     */
-    public JSONObject optJSONObject(int index) {
-        Object object = opt(index);
-        return object instanceof JSONObject ? (JSONObject) object : null;
-    }
-
-    /**
-     * Returns a new object whose values are the values in this array, and whose
-     * names are the values in {@code names}. Names and values are paired up by
-     * index from 0 through to the shorter array's length. Names that are not
-     * strings will be coerced to strings. This method returns null if either
-     * array is empty.
-     *
-     * @param names The names to apply to the returned values.
-     * @return the newly constructed object.
-     * @throws JSONException Should not be possible.
-     */
-    public JSONObject toJSONObject(JSONArray names) throws JSONException {
-        JSONObject result = new JSONObject();
-        int length = Math.min(names.length(), values.size());
-        if (length == 0) {
-            return null;
-        }
-        for (int i = 0; i < length; i++) {
-            String name = JSON.toString(names.opt(i));
-            result.put(name, opt(i));
-        }
-        return result;
-    }
-
-    /**
-     * Returns a new string by alternating this array's values with {@code
-     * separator}. This array's string values are quoted and have their special
-     * characters escaped. For example, the array containing the strings '12"
-     * pizza', 'taco' and 'soda' joined on '+' returns this:
-     * <pre>"12\" pizza"+"taco"+"soda"</pre>
-     *
-     * @param separator The string used to separate the returned values.
-     * @return the conjoined values.
-     * @throws JSONException Only if there is a coding error.
-     */
-    public String join(String separator) throws JSONException {
-        JSONStringer stringer = new JSONStringer();
-        stringer.open(JSONStringer.Scope.NULL, "");
-        for (int i = 0, size = values.size(); i < size; i++) {
-            if (i > 0) {
-                stringer.out.append(separator);
-            }
-            stringer.value(values.get(i));
-        }
-        stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
-        return stringer.out.toString();
-    }
-
-    /**
-     * Encodes this array as a compact JSON string, such as:
-     * <pre>[94043,90210]</pre>
-     *
-     * @return The string form of this array.
-     */
-    @Override
-    public String toString() {
-        try {
-            JSONStringer stringer = new JSONStringer();
-            writeTo(stringer);
-            return stringer.toString();
-        } catch (JSONException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Encodes this array as a human readable JSON string for debugging, such
-     * as:
-     * <pre>
-     * [
-     *     94043,
-     *     90210
-     * ]</pre>
-     *
-     * @param indentSpaces the number of spaces to indent for each level of
-     *                     nesting.
-     * @return The string form of this array.
-     * @throws JSONException Only if there is a coding error.
-     */
-    public String toString(int indentSpaces) throws JSONException {
-        JSONStringer stringer = new JSONStringer(indentSpaces);
-        writeTo(stringer);
-        return stringer.toString();
-    }
-
-    void writeTo(JSONStringer stringer) throws JSONException {
-        stringer.array();
-        for (Object value : values) {
-            stringer.value(value);
-        }
-        stringer.endArray();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        return o instanceof JSONArray && ((JSONArray) o).values.equals(values);
-    }
-
-    @Override
-    public int hashCode() {
-        // diverge from the original, which doesn't implement hashCode
-        return values.hashCode();
-    }
+  private final List<Object> values;
+
+  /**
+   * Creates a {@code JSONArray} with no values.
+   */
+  public JSONArray() {
+    values = new ArrayList<Object>();
+  }
+
+  /**
+   * Creates a new {@code JSONArray} by copying all values from the given collection.
+   *
+   * @param copyFrom a collection whose values are of supported types. Unsupported values are not
+   *        permitted and will yield an array in an inconsistent state.
+   */
+  /* Accept a raw type for API compatibility */
+  public JSONArray(Collection<?> copyFrom) {
+    this();
+    if (copyFrom != null) {
+      for (Object aCopyFrom : copyFrom) {
+        put(JSONObject.wrap(aCopyFrom));
+      }
+    }
+  }
+
+  /**
+   * Creates a new {@code JSONArray} with values from the next array in the tokener.
+   *
+   * @param readFrom a tokener whose nextValue() method will yield a {@code JSONArray}.
+   * @throws JSONException if the parse fails or doesn't yield a {@code JSONArray}.
+   */
+  public JSONArray(JSONTokener readFrom) throws JSONException {
+    /*
+     * Getting the parser to populate this could get tricky. Instead, just parse to temporary
+     * JSONArray and then steal the data from that.
+     */
+    Object object = readFrom.nextValue();
+    if (object instanceof JSONArray) {
+      values = ((JSONArray) object).values;
+    } else {
+      throw JSON.typeMismatch(object, "JSONArray");
+    }
+  }
+
+  /**
+   * Creates a new {@code JSONArray} with values from the JSON string.
+   *
+   * @param json a JSON-encoded string containing an array.
+   * @throws JSONException if the parse fails or doesn't yield a {@code
+   *                       JSONArray}.
+   */
+  public JSONArray(String json) throws JSONException {
+    this(new JSONTokener(json));
+  }
+
+  /**
+   * Creates a new {@code JSONArray} with values from the given primitive array.
+   *
+   * @param array The values to use.
+   * @throws JSONException if any of the values are non-finite double values (i.e. NaN or infinite)
+   */
+  public JSONArray(Object array) throws JSONException {
+    if (!array.getClass().isArray()) {
+      throw new JSONException("Not a primitive array: " + array.getClass());
+    }
+    final int length = Array.getLength(array);
+    values = new ArrayList<Object>(length);
+    for (int i = 0; i < length; ++i) {
+      put(JSONObject.wrap(Array.get(array, i)));
+    }
+  }
+
+  /**
+   * @return Returns the number of values in this array.
+   */
+  public int length() {
+    return values.size();
+  }
+
+  /**
+   * Appends {@code value} to the end of this array.
+   *
+   * @param value The value to append.
+   * @return this array.
+   */
+  public JSONArray put(boolean value) {
+    values.add(value);
+    return this;
+  }
+
+  /**
+   * Appends {@code value} to the end of this array.
+   *
+   * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+   *        {@link Double#isInfinite() infinities}.
+   * @return this array.
+   * @throws JSONException If the value is unacceptable.
+   */
+  public JSONArray put(double value) throws JSONException {
+    values.add(JSON.checkDouble(value));
+    return this;
+  }
+
+  /**
+   * Appends {@code value} to the end of this array.
+   *
+   * @param value The value to append.
+   * @return this array.
+   */
+  public JSONArray put(int value) {
+    values.add(value);
+    return this;
+  }
+
+  /**
+   * Appends {@code value} to the end of this array.
+   *
+   * @param value The value to append.
+   * @return this array.
+   */
+  public JSONArray put(long value) {
+    values.add(value);
+    return this;
+  }
+
+  /**
+   * Appends {@code value} wrapped by {@link JSONArray} to the end of this array.
+   *
+   * @param value any collection.
+   * @return this array.
+   */
+  public JSONArray put(Collection<?> value) {
+    if (value == null) {
+      return put((Object) null);
+    }
+    values.add(new JSONArray(value));
+    return this;
+  }
+
+  /**
+   * Appends {@code value} to the end of this array.
+   *
+   * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double,
+   *        {@link JSONObject#NULL}, or {@code null}. May not be {@link Double#isNaN() NaNs} or
+   *        {@link Double#isInfinite() infinities}. Unsupported values are not permitted and will
+   *        cause the array to be in an inconsistent state.
+   * @return this array.
+   */
+  public JSONArray put(Object value) {
+    values.add(value);
+    return this;
+  }
+
+  /**
+   * Same as {@link #put}, with added validity checks.
+   *
+   * @param value The value to append.
+   */
+  void checkedPut(Object value) throws JSONException {
+    if (value instanceof Number) {
+      JSON.checkDouble(((Number) value).doubleValue());
+    }
+
+    put(value);
+  }
+
+  /**
+   * Sets the value at {@code index} to {@code value}, null padding this array to the required
+   * length if necessary. If a value already exists at {@code
+   * index}, it will be replaced.
+   *
+   * @param index Where to put the value.
+   * @param value The value to set.
+   * @return this array.
+   * @throws JSONException This should never happen.
+   */
+  public JSONArray put(int index, boolean value) throws JSONException {
+    return put(index, (Boolean) value);
+  }
+
+  /**
+   * Sets the value at {@code index} to {@code value}, null padding this array to the required
+   * length if necessary. If a value already exists at {@code
+   * index}, it will be replaced.
+   *
+   * @param index Where to put the value.
+   * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+   *        {@link Double#isInfinite() infinities}.
+   * @return this array.
+   * @throws JSONException If the value is not a finite value.
+   */
+  public JSONArray put(int index, double value) throws JSONException {
+    return put(index, (Double) value);
+  }
+
+  /**
+   * Sets the value at {@code index} to {@code value}, null padding this array to the required
+   * length if necessary. If a value already exists at {@code
+   * index}, it will be replaced.
+   *
+   * @param index Where to put the value.
+   * @param value The value to set.
+   * @return this array.
+   * @throws JSONException Should never actually happen.
+   */
+  public JSONArray put(int index, int value) throws JSONException {
+    return put(index, (Integer) value);
+  }
+
+  /**
+   * Sets the value at {@code index} to {@code value}, null padding this array to the required
+   * length if necessary. If a value already exists at {@code
+   * index}, it will be replaced.
+   *
+   * @param index Where to put the value.
+   * @param value The value to set.
+   * @return this array.
+   * @throws JSONException Should never actually happen.
+   */
+  public JSONArray put(int index, long value) throws JSONException {
+    return put(index, (Long) value);
+  }
+
+  /**
+   * Sets the value at {@code index} to {@code value} wrapped into {@link JSONArray}, null padding
+   * this array to the required length if necessary. If a value already exists at {@code index}, it
+   * will be replaced.
+   *
+   * @param index Where to put the value.
+   * @param value The value to set.
+   * @return this array.
+   * @throws JSONException Should never actually happen.
+   */
+  public JSONArray put(int index, Collection<?> value) throws JSONException {
+    if (value == null) {
+      return put(index, (Object) null);
+    }
+    return put(index, new JSONArray(value));
+  }
+
+  /**
+   * Sets the value at {@code index} to {@code value}, null padding this array to the required
+   * length if necessary. If a value already exists at {@code
+   * index}, it will be replaced.
+   *
+   * @param index Where to put the value.
+   * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, Double,
+   *        {@link JSONObject#NULL}, or {@code null}. May not be {@link Double#isNaN() NaNs} or
+   *        {@link Double#isInfinite() infinities}.
+   * @return this array.
+   * @throws JSONException If the value cannot be represented as a finite double value.
+   */
+  public JSONArray put(int index, Object value) throws JSONException {
+    if (value instanceof Number) {
+      // deviate from the original by checking all Numbers, not just floats & doubles
+      JSON.checkDouble(((Number) value).doubleValue());
+    }
+    while (values.size() <= index) {
+      values.add(null);
+    }
+    values.set(index, value);
+    return this;
+  }
+
+  /**
+   * Returns true if this array has no value at {@code index}, or if its value is the {@code null}
+   * reference or {@link JSONObject#NULL}.
+   *
+   * @param index Which value to check.
+   * @return true if the value is null.
+   */
+  public boolean isNull(int index) {
+    Object value = opt(index);
+    return value == null || value == JSONObject.NULL;
+  }
+
+  /**
+   * Returns the value at {@code index}.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   * @throws JSONException if this array has no value at {@code index}, or if that value is the
+   *         {@code null} reference. This method returns normally if the value is
+   *         {@code JSONObject#NULL}.
+   */
+  public Object get(int index) throws JSONException {
+    try {
+      Object value = values.get(index);
+      if (value == null) {
+        throw new JSONException("Value at " + index + " is null.");
+      }
+      return value;
+    } catch (IndexOutOfBoundsException e) {
+      throw new JSONException("Index " + index + " out of range [0.." + values.size() + ")");
+    }
+  }
+
+  /**
+   * Returns the value at {@code index}, or null if the array has no value at {@code index}.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   */
+  public Object opt(int index) {
+    if (index < 0 || index >= values.size()) {
+      return null;
+    }
+    return values.get(index);
+  }
+
+  /**
+   * Removes and returns the value at {@code index}, or null if the array has no value at
+   * {@code index}.
+   *
+   * @param index Which value to remove.
+   * @return The value previously at the specified location.
+   */
+  public Object remove(int index) {
+    if (index < 0 || index >= values.size()) {
+      return null;
+    }
+    return values.remove(index);
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a boolean or can be coerced to a
+   * boolean.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   * @throws JSONException if the value at {@code index} doesn't exist or cannot be coerced to a
+   *         boolean.
+   */
+  public boolean getBoolean(int index) throws JSONException {
+    Object object = get(index);
+    Boolean result = JSON.toBoolean(object);
+    if (result == null) {
+      throw JSON.typeMismatch(index, object, "boolean");
+    }
+    return result;
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a boolean or can be coerced to a
+   * boolean. Returns false otherwise.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   */
+  public boolean optBoolean(int index) {
+    return optBoolean(index, false);
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a boolean or can be coerced to a
+   * boolean. Returns {@code fallback} otherwise.
+   *
+   * @param index Which value to get.
+   * @param fallback the fallback value to return if no value exists.
+   * @return the value at the specified location or the fallback value.
+   */
+  public boolean optBoolean(int index, boolean fallback) {
+    Object object = opt(index);
+    Boolean result = JSON.toBoolean(object);
+    return result != null ? result : fallback;
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a double or can be coerced to a double.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   * @throws JSONException if the value at {@code index} doesn't exist or cannot be coerced to a
+   *         double.
+   */
+  public double getDouble(int index) throws JSONException {
+    Object object = get(index);
+    Double result = JSON.toDouble(object);
+    if (result == null) {
+      throw JSON.typeMismatch(index, object, "double");
+    }
+    return result;
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a double or can be coerced to a double.
+   * Returns {@code NaN} otherwise.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   */
+  public double optDouble(int index) {
+    return optDouble(index, Double.NaN);
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a double or can be coerced to a double.
+   * Returns {@code fallback} otherwise.
+   *
+   * @param index Which value to get.
+   * @param fallback The fallback value to use if no value is at the specified location.
+   * @return the value at the specified location or the fallback value.
+   */
+  public double optDouble(int index, double fallback) {
+    Object object = opt(index);
+    Double result = JSON.toDouble(object);
+    return result != null ? result : fallback;
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is an int or can be coerced to an int.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   * @throws JSONException if the value at {@code index} doesn't exist or cannot be coerced to a
+   *         int.
+   */
+  public int getInt(int index) throws JSONException {
+    Object object = get(index);
+    Integer result = JSON.toInteger(object);
+    if (result == null) {
+      throw JSON.typeMismatch(index, object, "int");
+    }
+    return result;
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is an int or can be coerced to an int.
+   * Returns 0 otherwise.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   */
+  public int optInt(int index) {
+    return optInt(index, 0);
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is an int or can be coerced to an int.
+   * Returns {@code fallback} otherwise.
+   *
+   * @param index Which value to get.
+   * @param fallback The fallback value to use if no value is at the specified location.
+   * @return the value at the specified location or the fallback value.
+   */
+  public int optInt(int index, int fallback) {
+    Object object = opt(index);
+    Integer result = JSON.toInteger(object);
+    return result != null ? result : fallback;
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a long or can be coerced to a long.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   * @throws JSONException if the value at {@code index} doesn't exist or cannot be coerced to a
+   *         long.
+   */
+  public long getLong(int index) throws JSONException {
+    Object object = get(index);
+    Long result = JSON.toLong(object);
+    if (result == null) {
+      throw JSON.typeMismatch(index, object, "long");
+    }
+    return result;
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a long or can be coerced to a long.
+   * Returns 0 otherwise.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   */
+  public long optLong(int index) {
+    return optLong(index, 0L);
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a long or can be coerced to a long.
+   * Returns {@code fallback} otherwise.
+   *
+   * @param index Which value to get.
+   * @param fallback The fallback value to use if no value is at the specified location.
+   * @return the value at the specified location or the fallback value.
+   */
+  public long optLong(int index, long fallback) {
+    Object object = opt(index);
+    Long result = JSON.toLong(object);
+    return result != null ? result : fallback;
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists, coercing it if necessary.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   * @throws JSONException if no such value exists.
+   */
+  public String getString(int index) throws JSONException {
+    Object object = get(index);
+    String result = JSON.toString(object);
+    if (result == null) {
+      throw JSON.typeMismatch(index, object, "String");
+    }
+    return result;
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists, coercing it if necessary. Returns the empty
+   * string if no such value exists.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   */
+  public String optString(int index) {
+    return optString(index, "");
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists, coercing it if necessary. Returns
+   * {@code fallback} if no such value exists.
+   *
+   * @param index Which value to get.
+   * @param fallback The fallback value to use if no value is at the specified location.
+   * @return the value at the specified location or the fallback value.
+   */
+  public String optString(int index, String fallback) {
+    Object object = opt(index);
+    String result = JSON.toString(object);
+    return result != null ? result : fallback;
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a {@code
+   * JSONArray}.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   * @throws JSONException if the value doesn't exist or is not a {@code
+   *                       JSONArray}.
+   */
+  public JSONArray getJSONArray(int index) throws JSONException {
+    Object object = get(index);
+    if (object instanceof JSONArray) {
+      return (JSONArray) object;
+    } else {
+      throw JSON.typeMismatch(index, object, "JSONArray");
+    }
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a {@code
+   * JSONArray}. Returns null otherwise.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   */
+  public JSONArray optJSONArray(int index) {
+    Object object = opt(index);
+    return object instanceof JSONArray ? (JSONArray) object : null;
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a {@code
+   * JSONObject}.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   * @throws JSONException if the value doesn't exist or is not a {@code
+   *                       JSONObject}.
+   */
+  public JSONObject getJSONObject(int index) throws JSONException {
+    Object object = get(index);
+    if (object instanceof JSONObject) {
+      return (JSONObject) object;
+    } else {
+      throw JSON.typeMismatch(index, object, "JSONObject");
+    }
+  }
+
+  /**
+   * Returns the value at {@code index} if it exists and is a {@code
+   * JSONObject}. Returns null otherwise.
+   *
+   * @param index Which value to get.
+   * @return the value at the specified location.
+   */
+  public JSONObject optJSONObject(int index) {
+    Object object = opt(index);
+    return object instanceof JSONObject ? (JSONObject) object : null;
+  }
+
+  /**
+   * Returns a new object whose values are the values in this array, and whose names are the values
+   * in {@code names}. Names and values are paired up by index from 0 through to the shorter array's
+   * length. Names that are not strings will be coerced to strings. This method returns null if
+   * either array is empty.
+   *
+   * @param names The names to apply to the returned values.
+   * @return the newly constructed object.
+   * @throws JSONException Should not be possible.
+   */
+  public JSONObject toJSONObject(JSONArray names) throws JSONException {
+    JSONObject result = new JSONObject();
+    int length = Math.min(names.length(), values.size());
+    if (length == 0) {
+      return null;
+    }
+    for (int i = 0; i < length; i++) {
+      String name = JSON.toString(names.opt(i));
+      result.put(name, opt(i));
+    }
+    return result;
+  }
+
+  /**
+   * Returns a new string by alternating this array's values with {@code
+   * separator}. This array's string values are quoted and have their special characters escaped.
+   * For example, the array containing the strings '12" pizza', 'taco' and 'soda' joined on '+'
+   * returns this:
+   * 
+   * <pre>
+   * "12\" pizza" + "taco" + "soda"
+   * </pre>
+   *
+   * @param separator The string used to separate the returned values.
+   * @return the conjoined values.
+   * @throws JSONException Only if there is a coding error.
+   */
+  public String join(String separator) throws JSONException {
+    JSONStringer stringer = new JSONStringer();
+    stringer.open(JSONStringer.Scope.NULL, "");
+    for (int i = 0, size = values.size(); i < size; i++) {
+      if (i > 0) {
+        stringer.out.append(separator);
+      }
+      stringer.value(values.get(i));
+    }
+    stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
+    return stringer.out.toString();
+  }
+
+  /**
+   * Encodes this array as a compact JSON string, such as:
+   * 
+   * <pre>
+   * [94043,90210]
+   * </pre>
+   *
+   * @return The string form of this array.
+   */
+  @Override
+  public String toString() {
+    try {
+      JSONStringer stringer = new JSONStringer();
+      writeTo(stringer);
+      return stringer.toString();
+    } catch (JSONException e) {
+      return null;
+    }
+  }
+
+  /**
+   * Encodes this array as a human readable JSON string for debugging, such as:
+   * 
+   * <pre>
+   * [
+   *     94043,
+   *     90210
+   * ]
+   * </pre>
+   *
+   * @param indentSpaces the number of spaces to indent for each level of nesting.
+   * @return The string form of this array.
+   * @throws JSONException Only if there is a coding error.
+   */
+  public String toString(int indentSpaces) throws JSONException {
+    JSONStringer stringer = new JSONStringer(indentSpaces);
+    writeTo(stringer);
+    return stringer.toString();
+  }
+
+  void writeTo(JSONStringer stringer) throws JSONException {
+    stringer.array();
+    for (Object value : values) {
+      stringer.value(value);
+    }
+    stringer.endArray();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    return o instanceof JSONArray && ((JSONArray) o).values.equals(values);
+  }
+
+  @Override
+  public int hashCode() {
+    // diverge from the original, which doesn't implement hashCode
+    return values.hashCode();
+  }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/2e3a88f7/geode-json/src/main/java/org/json/JSONException.java
----------------------------------------------------------------------
diff --git a/geode-json/src/main/java/org/json/JSONException.java b/geode-json/src/main/java/org/json/JSONException.java
index 1292e86..83fb4b8 100755
--- a/geode-json/src/main/java/org/json/JSONException.java
+++ b/geode-json/src/main/java/org/json/JSONException.java
@@ -1,17 +1,15 @@
 /*
  * 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
+ * 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
+ * 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.
+ * 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.json;
@@ -21,37 +19,40 @@ package org.json;
 /**
  * Thrown to indicate a problem with the JSON API. Such problems include:
  * <ul>
- *   <li>Attempts to parse or construct malformed documents
- *   <li>Use of null as a name
- *   <li>Use of numeric types not available to JSON, such as {@link
- *       Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
- *   <li>Lookups using an out of range index or nonexistent name
- *   <li>Type mismatches on lookups
+ * <li>Attempts to parse or construct malformed documents
+ * <li>Use of null as a name
+ * <li>Use of numeric types not available to JSON, such as {@link Double#isNaN() NaNs} or
+ * {@link Double#isInfinite() infinities}.
+ * <li>Lookups using an out of range index or nonexistent name
+ * <li>Type mismatches on lookups
  * </ul>
  *
- * <p>Although this is a checked exception, it is rarely recoverable. Most
- * callers should simply wrap this exception in an unchecked exception and
- * rethrow:
- * <pre>  public JSONArray toJSONObject() {
+ * <p>
+ * Although this is a checked exception, it is rarely recoverable. Most callers should simply wrap
+ * this exception in an unchecked exception and rethrow:
+ * 
+ * <pre>
+ *   public JSONArray toJSONObject() {
  *     try {
  *         JSONObject result = new JSONObject();
  *         ...
  *     } catch (JSONException e) {
  *         throw new RuntimeException(e);
  *     }
- * }</pre>
+ * }
+ * </pre>
  */
 public class JSONException extends RuntimeException {
 
-    public JSONException(String s) {
-        super(s);
-    }
+  public JSONException(String s) {
+    super(s);
+  }
 
-    public JSONException(Throwable cause) {
-        super(cause);
-    }
+  public JSONException(Throwable cause) {
+    super(cause);
+  }
 
-    public JSONException(String message, Throwable cause) {
-        super(message, cause);
-    }
+  public JSONException(String message, Throwable cause) {
+    super(message, cause);
+  }
 }