Coverage Report - net.sf.json.JSONArray
 
Classes in this File Line Coverage Branch Coverage Complexity
JSONArray
0%
0/944
0%
0/552
3.78
JSONArray$JSONArrayListIterator
0%
0/45
0%
0/10
3.78
 
 1  
 /*
 2  
  * Copyright 2002-2009 the original author or authors.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package net.sf.json;
 17  
 
 18  
 import java.io.IOException;
 19  
 import java.io.Writer;
 20  
 import java.lang.reflect.Array;
 21  
 import java.util.ArrayList;
 22  
 import java.util.Collection;
 23  
 import java.util.ConcurrentModificationException;
 24  
 import java.util.HashSet;
 25  
 import java.util.Iterator;
 26  
 import java.util.List;
 27  
 import java.util.ListIterator;
 28  
 import java.util.Map;
 29  
 import java.util.NoSuchElementException;
 30  
 import java.util.Set;
 31  
 
 32  
 import net.sf.ezmorph.Morpher;
 33  
 import net.sf.ezmorph.object.IdentityObjectMorpher;
 34  
 import net.sf.json.processors.JsonValueProcessor;
 35  
 import net.sf.json.processors.JsonVerifier;
 36  
 import net.sf.json.util.JSONTokener;
 37  
 import net.sf.json.util.JSONUtils;
 38  
 
 39  
 import org.apache.commons.lang.StringUtils;
 40  
 
 41  
 /**
 42  
  * A JSONArray is an ordered sequence of values. Its external text form is a
 43  
  * string wrapped in square brackets with commas separating the values. The
 44  
  * internal form is an object having <code>get</code> and <code>opt</code>
 45  
  * methods for accessing the values by index, and <code>element</code> methods
 46  
  * for adding or replacing values. The values can be any of these types:
 47  
  * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
 48  
  * <code>Number</code>, <code>String</code>, or the
 49  
  * <code>JSONNull object</code>.
 50  
  * <p>
 51  
  * The constructor can convert a JSON text into a Java object. The
 52  
  * <code>toString</code> method converts to JSON text.
 53  
  * <p>
 54  
  * A <code>get</code> method returns a value if one can be found, and throws
 55  
  * an exception if one cannot be found. An <code>opt</code> method returns a
 56  
  * default value instead of throwing an exception, and so is useful for
 57  
  * obtaining optional values.
 58  
  * <p>
 59  
  * The generic <code>get()</code> and <code>opt()</code> methods return an
 60  
  * object which you can cast or query for type. There are also typed
 61  
  * <code>get</code> and <code>opt</code> methods that do type checking and
 62  
  * type coersion for you.
 63  
  * <p>
 64  
  * The texts produced by the <code>toString</code> methods strictly conform to
 65  
  * JSON syntax rules. The constructors are more forgiving in the texts they will
 66  
  * accept:
 67  
  * <ul>
 68  
  * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just
 69  
  * before the closing bracket.</li>
 70  
  * <li>The <code>null</code> value will be inserted when there is
 71  
  * <code>,</code>&nbsp;<small>(comma)</small> elision.</li>
 72  
  * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single quote)</small>.</li>
 73  
  * <li>Strings do not need to be quoted at all if they do not begin with a
 74  
  * quote or single quote, and if they do not contain leading or trailing spaces,
 75  
  * and if they do not contain any of these characters:
 76  
  * <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers and
 77  
  * if they are not the reserved words <code>true</code>, <code>false</code>,
 78  
  * or <code>null</code>.</li>
 79  
  * <li>Values can be separated by <code>;</code> <small>(semicolon)</small>
 80  
  * as well as by <code>,</code> <small>(comma)</small>.</li>
 81  
  * <li>Numbers may have the <code>0-</code> <small>(octal)</small> or
 82  
  * <code>0x-</code> <small>(hex)</small> prefix.</li>
 83  
  * <li>Comments written in the slashshlash, slashstar, and hash conventions
 84  
  * will be ignored.</li>
 85  
  * </ul>
 86  
  *
 87  
  * @author JSON.org
 88  
  */
 89  
 public final class JSONArray extends AbstractJSON implements JSON, List, Comparable {
 90  
    /**
 91  
     * Creates a JSONArray.<br>
 92  
     * Inspects the object type to call the correct JSONArray factory method.
 93  
     * Accepts JSON formatted strings, arrays and Collections.
 94  
     *
 95  
     * @param object
 96  
     * @throws JSONException if the object can not be converted to a proper
 97  
     *         JSONArray.
 98  
     */
 99  
    public static JSONArray fromObject( Object object ) {
 100  
       return fromObject( object, new JsonConfig() );
 101  
    }
 102  
 
 103  
    /**
 104  
     * Creates a JSONArray.<br>
 105  0
     * Inspects the object type to call the correct JSONArray factory method.
 106  
     * Accepts JSON formatted strings, arrays and Collections.
 107  
     *
 108  
     * @param object
 109  
     * @throws JSONException if the object can not be converted to a proper
 110  
     *         JSONArray.
 111  
     */
 112  
    public static JSONArray fromObject( Object object, JsonConfig jsonConfig ) {
 113  
       if( object instanceof JSONString ){
 114  
          return _fromJSONString( (JSONString) object, jsonConfig );
 115  
       }else if( object instanceof JSONArray ){
 116  
          return _fromJSONArray( (JSONArray) object, jsonConfig );
 117  
       }else if( object instanceof Collection ){
 118  0
          return _fromCollection( (Collection) object, jsonConfig );
 119  0
       }else if( object instanceof JSONTokener ){
 120  0
          return _fromJSONTokener( (JSONTokener) object, jsonConfig );
 121  0
       }else if( object instanceof String ){
 122  0
          return _fromString( (String) object, jsonConfig );
 123  0
       }else if( object != null && object.getClass()
 124  0
             .isArray() ){
 125  0
          Class type = object.getClass()
 126  0
                .getComponentType();  
 127  0
          if( !type.isPrimitive() ){
 128  0
             return _fromArray( (Object[]) object, jsonConfig );
 129  
          }else{
 130  0
             if( type == Boolean.TYPE ){
 131  
                return _fromArray( (boolean[]) object, jsonConfig );
 132  0
             }else if( type == Byte.TYPE ){
 133  0
                return _fromArray( (byte[]) object, jsonConfig );
 134  
             }else if( type == Short.TYPE ){
 135  0
                return _fromArray( (short[]) object, jsonConfig );
 136  0
             }else if( type == Integer.TYPE ){
 137  0
                return _fromArray( (int[]) object, jsonConfig );
 138  0
             }else if( type == Long.TYPE ){
 139  0
                return _fromArray( (long[]) object, jsonConfig );
 140  0
             }else if( type == Float.TYPE ){
 141  0
                return _fromArray( (float[]) object, jsonConfig );
 142  0
             }else if( type == Double.TYPE ){
 143  0
                return _fromArray( (double[]) object, jsonConfig );
 144  0
             }else if( type == Character.TYPE ){
 145  0
                return _fromArray( (char[]) object, jsonConfig );
 146  0
             }else{
 147  0
                throw new JSONException( "Unsupported type" );
 148  0
             }
 149  0
          }
 150  0
       }else if( JSONUtils.isBoolean( object ) || JSONUtils.isFunction( object )
 151  
             || JSONUtils.isNumber( object ) || JSONUtils.isNull( object )
 152  0
             || JSONUtils.isString( object ) || object instanceof JSON ){
 153  
          fireArrayStartEvent( jsonConfig );
 154  
          JSONArray jsonArray = new JSONArray().element( object, jsonConfig );
 155  0
          fireElementAddedEvent( 0, jsonArray.get( 0 ), jsonConfig );
 156  
          fireArrayStartEvent( jsonConfig );
 157  
          return jsonArray;
 158  0
       }else if( JSONUtils.isObject( object ) ){
 159  0
          fireArrayStartEvent( jsonConfig );
 160  0
          JSONArray jsonArray = new JSONArray().element( JSONObject.fromObject( object, jsonConfig ) );
 161  0
          fireElementAddedEvent( 0, jsonArray.get( 0 ), jsonConfig );
 162  0
          fireArrayStartEvent( jsonConfig );
 163  0
          return jsonArray;
 164  0
       }else{
 165  0
          throw new JSONException( "Unsupported type" );
 166  
       }
 167  0
    }
 168  0
 
 169  0
    /**
 170  0
     * Returns the number of dimensions suited for a java array.
 171  0
     */
 172  0
    public static int[] getDimensions( JSONArray jsonArray ) {
 173  0
       // short circuit for empty arrays
 174  
       if( jsonArray == null || jsonArray.isEmpty() ){
 175  0
          return new int[] { 0 };
 176  
       }
 177  
 
 178  
       List dims = new ArrayList();
 179  
       processArrayDimensions( jsonArray, dims, 0 );
 180  
       int[] dimensions = new int[dims.size()];
 181  
       int j = 0;
 182  
       for( Iterator i = dims.iterator(); i.hasNext(); ){
 183  
          dimensions[j++] = ((Integer) i.next()).intValue();
 184  
       }
 185  
       return dimensions;
 186  
    }
 187  
 
 188  0
    /**
 189  0
     * Creates a java array from a JSONArray.
 190  0
     */
 191  0
    public static Object toArray( JSONArray jsonArray ) {
 192  0
       return toArray( jsonArray, new JsonConfig() );
 193  0
    }
 194  
 
 195  0
    /**
 196  0
     * Creates a java array from a JSONArray.
 197  
     */
 198  0
    public static Object toArray( JSONArray jsonArray, Class objectClass ) {
 199  
       JsonConfig jsonConfig = new JsonConfig();
 200  
       jsonConfig.setRootClass( objectClass );
 201  0
       return toArray( jsonArray, jsonConfig );
 202  0
    }
 203  
 
 204  
    /**
 205  
     * Creates a java array from a JSONArray.<br>
 206  
     * Any attribute is a JSONObject and matches a key in the classMap, it will
 207  0
     * be converted to that target class.<br>
 208  0
     * The classMap has the following conventions:
 209  
     * <ul>
 210  0
     * <li>Every key must be an String.</li>
 211  0
     * <li>Every value must be a Class.</li>
 212  0
     * <li>A key may be a regular expression.</li>
 213  
     * </ul>
 214  
     */
 215  0
    public static Object toArray( JSONArray jsonArray, Class objectClass, Map classMap ) {
 216  
       JsonConfig jsonConfig = new JsonConfig();
 217  
       jsonConfig.setRootClass( objectClass );
 218  
       jsonConfig.setClassMap( classMap );
 219  
       return toArray( jsonArray, jsonConfig );
 220  
    }
 221  
 
 222  
    /**
 223  0
     * Creates a java array from a JSONArray.<br>
 224  0
     */
 225  
    public static Object toArray( JSONArray jsonArray, JsonConfig jsonConfig ) {
 226  
       Class objectClass = jsonConfig.getRootClass();
 227  0
       Map classMap = jsonConfig.getClassMap();
 228  0
 
 229  0
       if( jsonArray.size() == 0 ){
 230  0
          return Array.newInstance( objectClass == null ? Object.class : objectClass, 0 );
 231  0
       }
 232  0
 
 233  
       int[] dimensions = JSONArray.getDimensions( jsonArray );
 234  0
       Object array = Array.newInstance( objectClass == null ? Object.class : objectClass,
 235  
             dimensions );
 236  
       int size = jsonArray.size();
 237  
       for( int i = 0; i < size; i++ ){
 238  
          Object value = jsonArray.get( i );
 239  
          if( JSONUtils.isNull( value ) ){
 240  
             Array.set( array, i, null );
 241  0
          }else{
 242  
             Class type = value.getClass();
 243  
             if( JSONArray.class.isAssignableFrom( type ) ){
 244  
                Array.set( array, i, toArray( (JSONArray) value, objectClass, classMap ) );
 245  
             }else if( String.class.isAssignableFrom( type )
 246  
                   || Boolean.class.isAssignableFrom( type )
 247  
                   || Character.class.isAssignableFrom( type )
 248  0
                   || JSONFunction.class.isAssignableFrom( type ) ){
 249  0
                if( objectClass != null && !objectClass.isAssignableFrom( type ) ){
 250  0
                   value = JSONUtils.getMorpherRegistry()
 251  
                         .morph( objectClass, value );
 252  
                }
 253  
                Array.set( array, i, value );
 254  
             }else if( JSONUtils.isNumber( type ) ){
 255  
                if( objectClass != null
 256  
                      && (Byte.class.isAssignableFrom( objectClass ) || Byte.TYPE.isAssignableFrom( objectClass )) ){
 257  
                   Array.set( array, i, Byte.valueOf( String.valueOf( value ) ) );
 258  
                }else if( objectClass != null
 259  
                      && (Short.class.isAssignableFrom( objectClass ) || Short.TYPE.isAssignableFrom( objectClass )) ){
 260  
                   Array.set( array, i, Short.valueOf( String.valueOf( value ) ) );
 261  
                }else{
 262  
                   Array.set( array, i, value );
 263  
                }
 264  
             }else{
 265  0
                if( objectClass != null ){
 266  0
                   JsonConfig jsc = jsonConfig.copy();
 267  0
                   jsc.setRootClass( objectClass );
 268  0
                   jsc.setClassMap( classMap );
 269  
                   Array.set( array, i, JSONObject.toBean( (JSONObject) value, jsc ) );
 270  
                }else{
 271  
                   Array.set( array, i, JSONObject.toBean( (JSONObject) value ) );
 272  
                }
 273  
             }
 274  
          }
 275  0
       }
 276  0
       return array;
 277  
    }
 278  0
 
 279  0
    /**
 280  
     * Creates a java array from a JSONArray.<br>
 281  
     */
 282  0
    public static Object toArray( JSONArray jsonArray, Object root, JsonConfig jsonConfig ) {
 283  0
       Class objectClass = root.getClass();
 284  
       if( jsonArray.size() == 0 ){
 285  0
          return Array.newInstance( objectClass, 0 );
 286  0
       }
 287  0
 
 288  0
       int[] dimensions = JSONArray.getDimensions( jsonArray );
 289  0
       Object array = Array.newInstance( objectClass == null ? Object.class : objectClass,
 290  
             dimensions );
 291  0
       int size = jsonArray.size();
 292  0
       for( int i = 0; i < size; i++ ){
 293  0
          Object value = jsonArray.get( i );
 294  0
          if( JSONUtils.isNull( value ) ){
 295  
             Array.set( array, i, null );
 296  
          }else{
 297  
             Class type = value.getClass();
 298  0
             if( JSONArray.class.isAssignableFrom( type ) ){
 299  0
                Array.set( array, i, toArray( (JSONArray) value, root, jsonConfig ) );
 300  
             }else if( String.class.isAssignableFrom( type )
 301  
                   || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type )
 302  0
                   || Character.class.isAssignableFrom( type )
 303  0
                   || JSONFunction.class.isAssignableFrom( type ) ){
 304  0
                if( objectClass != null && !objectClass.isAssignableFrom( type ) ){
 305  
                   value = JSONUtils.getMorpherRegistry()
 306  0
                         .morph( objectClass, value );
 307  0
                }
 308  
                Array.set( array, i, value );
 309  0
             }else{
 310  
                try{
 311  0
                   Object newRoot = jsonConfig.getNewBeanInstanceStrategy()
 312  
                         .newInstance( root.getClass(), null );
 313  
                   Array.set( array, i, JSONObject.toBean( (JSONObject) value, newRoot, jsonConfig ) );
 314  0
                }catch( JSONException jsone ){
 315  0
                   throw jsone;
 316  0
                }catch( Exception e ){
 317  0
                   throw new JSONException( e );
 318  0
                }
 319  0
             }
 320  0
          }
 321  
       }
 322  
       return array;
 323  
    }
 324  
 
 325  0
    /**
 326  
     * Creates a Collection from a JSONArray.
 327  
     */
 328  
    public static Collection toCollection( JSONArray jsonArray ) {
 329  
       return toCollection( jsonArray, new JsonConfig() );
 330  
    }
 331  
 
 332  0
    /**
 333  0
     * Creates a Collection from a JSONArray.
 334  0
     */
 335  
    public static Collection toCollection( JSONArray jsonArray, Class objectClass ) {
 336  
       JsonConfig jsonConfig = new JsonConfig();
 337  0
       jsonConfig.setRootClass( objectClass );
 338  0
       return toCollection( jsonArray, jsonConfig );
 339  
    }
 340  0
 
 341  0
    /**
 342  0
     * Returns a List or a Set taking generics into account.<br/> Contributed by
 343  0
     * [Matt Small @ WaveMaker].
 344  0
     */
 345  
    public static Collection toCollection( JSONArray jsonArray, JsonConfig jsonConfig ) {
 346  0
       Collection collection = null;
 347  0
       Class collectionType = jsonConfig.getCollectionType();
 348  0
 
 349  0
       if( collectionType.isInterface() ){
 350  
          if( collectionType.equals( List.class ) ){
 351  
             collection = new ArrayList();
 352  
          }else if( collectionType.equals( Set.class ) ){
 353  0
             collection = new HashSet();
 354  0
          }else{
 355  
             throw new JSONException( "unknown interface: " + collectionType );
 356  
          }
 357  0
       }else{
 358  
          try{
 359  
             collection = (Collection) collectionType.newInstance();
 360  0
          }catch( InstantiationException e ){
 361  
             throw new JSONException( e );
 362  0
          }catch( IllegalAccessException e ){
 363  0
             throw new JSONException( e );
 364  0
          }
 365  0
       }
 366  0
 
 367  0
       Class objectClass = jsonConfig.getRootClass();
 368  
       Map classMap = jsonConfig.getClassMap();
 369  
 
 370  
       int size = jsonArray.size();
 371  0
       for( int i = 0; i < size; i++ ){
 372  
          Object value = jsonArray.get( i );
 373  
 
 374  
          if( JSONUtils.isNull( value ) ){
 375  
             collection.add( null );
 376  
          }else{
 377  
             Class type = value.getClass();
 378  0
             if( JSONArray.class.isAssignableFrom( value.getClass() ) ){
 379  
                collection.add( toCollection( (JSONArray) value, jsonConfig ) );
 380  
             }else if( String.class.isAssignableFrom( type )
 381  
                   || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type )
 382  
                   || Character.class.isAssignableFrom( type )
 383  
                   || JSONFunction.class.isAssignableFrom( type ) ){
 384  
 
 385  0
                if( !value.getClass()
 386  0
                      .isAssignableFrom( type ) ){
 387  0
                   throw new JSONException( "can't assign value " + value + " of type "
 388  
                         + value.getClass() + " to Collection of type " + type );
 389  
                }
 390  
                collection.add( value );
 391  
             }else{
 392  
                if( objectClass != null ){
 393  
                   JsonConfig jsc = jsonConfig.copy();
 394  
                   jsc.setRootClass( objectClass );
 395  0
                   jsc.setClassMap( classMap );
 396  0
                   collection.add( JSONObject.toBean( (JSONObject) value, jsc ) );
 397  
                }else{
 398  0
                   collection.add( JSONObject.toBean( (JSONObject) value ) );
 399  0
                }
 400  0
             }
 401  0
          }
 402  0
       }
 403  
 
 404  0
       return collection;
 405  
    }
 406  
 
 407  
    /**
 408  0
     * Creates a List from a JSONArray.<br>
 409  0
     *
 410  0
     * @deprecated replaced by toCollection
 411  0
     * @see #toCollection(JSONArray)
 412  0
     */
 413  0
    public static List toList( JSONArray jsonArray ) {
 414  
       return toList( jsonArray, new JsonConfig() );
 415  
    }
 416  0
 
 417  0
    /**
 418  
     * Creates a List from a JSONArray.
 419  0
     *
 420  0
     * @deprecated replaced by toCollection
 421  0
     * @see #toCollection(JSONArray,Class)
 422  
     */
 423  0
    public static List toList( JSONArray jsonArray, Class objectClass ) {
 424  0
       JsonConfig jsonConfig = new JsonConfig();
 425  
       jsonConfig.setRootClass( objectClass );
 426  0
       return toList( jsonArray, jsonConfig );
 427  0
    }
 428  0
 
 429  0
    /**
 430  
     * Creates a List from a JSONArray.<br>
 431  
     * Any attribute is a JSONObject and matches a key in the classMap, it will
 432  
     * be converted to that target class.<br>
 433  
     * The classMap has the following conventions:
 434  0
     * <ul>
 435  
     * <li>Every key must be an String.</li>
 436  0
     * <li>Every value must be a Class.</li>
 437  
     * <li>A key may be a regular expression.</li>
 438  
     * </ul>
 439  0
     *
 440  
     * @deprecated replaced by toCollection
 441  0
     * @see #toCollection(JSONArray,Class,Map)
 442  0
     */
 443  0
    public static List toList( JSONArray jsonArray, Class objectClass, Map classMap ) {
 444  0
       JsonConfig jsonConfig = new JsonConfig();
 445  0
       jsonConfig.setRootClass( objectClass );
 446  0
       jsonConfig.setClassMap( classMap );
 447  0
       return toList( jsonArray, jsonConfig );
 448  
    }
 449  
 
 450  
    /**
 451  
     * Creates a List from a JSONArray.<br>
 452  
     *
 453  0
     * @deprecated replaced by toCollection
 454  
     * @see #toCollection(JSONArray,JsonConfig)
 455  
     */
 456  
    public static List toList( JSONArray jsonArray, JsonConfig jsonConfig ) {
 457  
       if( jsonArray.size() == 0 ){
 458  
          return new ArrayList();
 459  
       }
 460  
 
 461  
       Class objectClass = jsonConfig.getRootClass();
 462  
       Map classMap = jsonConfig.getClassMap();
 463  
 
 464  
       List list = new ArrayList();
 465  
       int size = jsonArray.size();
 466  
       for( int i = 0; i < size; i++ ){
 467  
          Object value = jsonArray.get( i );
 468  
          if( JSONUtils.isNull( value ) ){
 469  
             list.add( null );
 470  
          }else{
 471  
             Class type = value.getClass();
 472  
             if( JSONArray.class.isAssignableFrom( type ) ){
 473  
                list.add( toList( (JSONArray) value, objectClass, classMap ) );
 474  
             }else if( String.class.isAssignableFrom( type )
 475  
                   || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type )
 476  
                   || Character.class.isAssignableFrom( type )
 477  
                   || JSONFunction.class.isAssignableFrom( type ) ){
 478  
                if( objectClass != null && !objectClass.isAssignableFrom( type ) ){
 479  
                   value = JSONUtils.getMorpherRegistry()
 480  
                         .morph( objectClass, value );
 481  
                }
 482  
                list.add( value );
 483  
             }else{
 484  
                if( objectClass != null ){
 485  
                   JsonConfig jsc = jsonConfig.copy();
 486  
                   jsc.setRootClass( objectClass );
 487  
                   jsc.setClassMap( classMap );
 488  
                   list.add( JSONObject.toBean( (JSONObject) value, jsc ) );
 489  
                }else{
 490  
                   list.add( JSONObject.toBean( (JSONObject) value ) );
 491  
                }
 492  
             }
 493  
          }
 494  
       }
 495  
       return list;
 496  
    }
 497  
 
 498  
    /**
 499  
     * Creates a List from a JSONArray.<br>
 500  
     */
 501  
    public static List toList( JSONArray jsonArray, Object root, JsonConfig jsonConfig ) {
 502  
       if( jsonArray.size() == 0 || root == null ){
 503  
          return new ArrayList();
 504  
       }
 505  
 
 506  
       List list = new ArrayList();
 507  
       int size = jsonArray.size();
 508  
       for( int i = 0; i < size; i++ ){
 509  
          Object value = jsonArray.get( i );
 510  
          if( JSONUtils.isNull( value ) ){
 511  
             list.add( null );
 512  
          }else{
 513  
             Class type = value.getClass();
 514  
             if( JSONArray.class.isAssignableFrom( type ) ){
 515  
                list.add( toList( (JSONArray) value, root, jsonConfig ) );
 516  
             }else if( String.class.isAssignableFrom( type )
 517  
                   || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type )
 518  
                   || Character.class.isAssignableFrom( type )
 519  
                   || JSONFunction.class.isAssignableFrom( type ) ){
 520  
                list.add( value );
 521  
             }else{
 522  
                try{
 523  
                   Object newRoot = jsonConfig.getNewBeanInstanceStrategy()
 524  
                         .newInstance( root.getClass(), null );
 525  
                   list.add( JSONObject.toBean( (JSONObject) value, newRoot, jsonConfig ) );
 526  
                }catch( JSONException jsone ){
 527  
                   throw jsone;
 528  
                }catch( Exception e ){
 529  
                   throw new JSONException( e );
 530  
                }
 531  
             }
 532  
          }
 533  
       }
 534  
       return list;
 535  
    }
 536  
 
 537  
    /**
 538  
     * Construct a JSONArray from an boolean[].<br>
 539  
     *
 540  
     * @param array An boolean[] array.
 541  
     */
 542  
    private static JSONArray _fromArray( boolean[] array, JsonConfig jsonConfig ) {
 543  
       if( !addInstance( array ) ){
 544  
          try{
 545  0
             return jsonConfig.getCycleDetectionStrategy()
 546  
                   .handleRepeatedReferenceAsArray( array );
 547  
          }catch( JSONException jsone ){
 548  
             removeInstance( array );
 549  
             fireErrorEvent( jsone, jsonConfig );
 550  
             throw jsone;
 551  
          }catch( RuntimeException e ){
 552  
             removeInstance( array );
 553  
             JSONException jsone = new JSONException( e );
 554  
             fireErrorEvent( jsone, jsonConfig );
 555  0
             throw jsone;
 556  0
          }
 557  0
       }
 558  
       fireArrayStartEvent( jsonConfig );
 559  
       
 560  
       JSONArray jsonArray = new JSONArray();
 561  
       for( int i = 0; i < array.length; i++ ){
 562  
          Boolean b = array[i] ? Boolean.TRUE : Boolean.FALSE;
 563  
          jsonArray.addValue( b, jsonConfig );
 564  
          fireElementAddedEvent( i, b, jsonConfig );
 565  
       }
 566  
 
 567  
       removeInstance( array );
 568  
       fireArrayEndEvent( jsonConfig );
 569  
       return jsonArray;
 570  
    }
 571  
 
 572  
    /**
 573  
     * Construct a JSONArray from an byte[].<br>
 574  
     *
 575  0
     * @param array An byte[] array.
 576  0
     */
 577  0
    private static JSONArray _fromArray( byte[] array, JsonConfig jsonConfig ) {
 578  0
       if( !addInstance( array ) ){
 579  
          try{
 580  
             return jsonConfig.getCycleDetectionStrategy()
 581  
                   .handleRepeatedReferenceAsArray( array );
 582  
          }catch( JSONException jsone ){
 583  
             removeInstance( array );
 584  
             fireErrorEvent( jsone, jsonConfig );
 585  
             throw jsone;
 586  
          }catch( RuntimeException e ){
 587  
             removeInstance( array );
 588  0
             JSONException jsone = new JSONException( e );
 589  0
             fireErrorEvent( jsone, jsonConfig );
 590  
             throw jsone;
 591  
          }
 592  0
       }
 593  0
       fireArrayStartEvent( jsonConfig );
 594  
       
 595  0
       JSONArray jsonArray = new JSONArray();
 596  0
       for( int i = 0; i < array.length; i++ ){
 597  0
          Number n = JSONUtils.transformNumber( new Byte( array[i] ) );
 598  0
          jsonArray.addValue( n, jsonConfig );
 599  0
          fireElementAddedEvent( i, n, jsonConfig );
 600  0
       }
 601  
 
 602  0
       removeInstance( array );
 603  0
       fireArrayEndEvent( jsonConfig );
 604  0
       return jsonArray;
 605  0
    }
 606  
 
 607  
    /**
 608  
     * Construct a JSONArray from an char[].<br>
 609  0
     *
 610  0
     * @param array An char[] array.
 611  
     */
 612  
    private static JSONArray _fromArray( char[] array, JsonConfig jsonConfig ) {
 613  0
       if( !addInstance( array ) ){
 614  
          try{
 615  0
             return jsonConfig.getCycleDetectionStrategy()
 616  0
                   .handleRepeatedReferenceAsArray( array );
 617  0
          }catch( JSONException jsone ){
 618  0
             removeInstance( array );
 619  0
             fireErrorEvent( jsone, jsonConfig );
 620  0
             throw jsone;
 621  0
          }catch( RuntimeException e ){
 622  
             removeInstance( array );
 623  
             JSONException jsone = new JSONException( e );
 624  
             fireErrorEvent( jsone, jsonConfig );
 625  
             throw jsone;
 626  0
          }
 627  
       }
 628  
       fireArrayStartEvent( jsonConfig );
 629  
       
 630  
       JSONArray jsonArray = new JSONArray();
 631  
       for( int i = 0; i < array.length; i++ ){
 632  
          Character c = new Character( array[i] );
 633  0
          jsonArray.addValue( c, jsonConfig );
 634  0
          fireElementAddedEvent( i, c, jsonConfig );
 635  
       }
 636  
 
 637  0
       removeInstance( array );
 638  0
       fireArrayEndEvent( jsonConfig );
 639  0
       return jsonArray;
 640  0
    }
 641  0
 
 642  0
    /**
 643  
     * Construct a JSONArray from an double[].<br>
 644  0
     *
 645  0
     * @param array An double[] array.
 646  0
     */
 647  0
    private static JSONArray _fromArray( double[] array, JsonConfig jsonConfig ) {
 648  
       if( !addInstance( array ) ){
 649  
          try{
 650  
             return jsonConfig.getCycleDetectionStrategy()
 651  0
                   .handleRepeatedReferenceAsArray( array );
 652  
          }catch( JSONException jsone ){
 653  
             removeInstance( array );
 654  0
             fireErrorEvent( jsone, jsonConfig );
 655  
             throw jsone;
 656  0
          }catch( RuntimeException e ){
 657  0
             removeInstance( array );
 658  0
             JSONException jsone = new JSONException( e );
 659  0
             fireErrorEvent( jsone, jsonConfig );
 660  0
             throw jsone;
 661  0
          }
 662  
       }
 663  
       fireArrayStartEvent( jsonConfig );
 664  
       
 665  0
       JSONArray jsonArray = new JSONArray();
 666  
       try{
 667  
          for( int i = 0; i < array.length; i++ ){
 668  
             Double d = new Double( array[i] );
 669  
             JSONUtils.testValidity( d );
 670  
             jsonArray.addValue( d, jsonConfig );
 671  
             fireElementAddedEvent( i, d, jsonConfig );
 672  
          }
 673  
       }catch( JSONException jsone ){
 674  0
          removeInstance( array );
 675  
          fireErrorEvent( jsone, jsonConfig );
 676  0
          throw jsone;
 677  
       }
 678  0
 
 679  0
       removeInstance( array );
 680  0
       fireArrayEndEvent( jsonConfig );
 681  0
       return jsonArray;
 682  0
    }
 683  0
 
 684  0
    /**
 685  0
     * Construct a JSONArray from an float[].<br>
 686  0
     *
 687  
     * @param array An float[] array.
 688  
     */
 689  0
    private static JSONArray _fromArray( float[] array, JsonConfig jsonConfig ) {
 690  0
       if( !addInstance( array ) ){
 691  0
          try{
 692  0
             return jsonConfig.getCycleDetectionStrategy()
 693  0
                   .handleRepeatedReferenceAsArray( array );
 694  0
          }catch( JSONException jsone ){
 695  
             removeInstance( array );
 696  
             fireErrorEvent( jsone, jsonConfig );
 697  0
             throw jsone;
 698  0
          }catch( RuntimeException e ){
 699  0
             removeInstance( array );
 700  
             JSONException jsone = new JSONException( e );
 701  
             fireErrorEvent( jsone, jsonConfig );
 702  
             throw jsone;
 703  
          }
 704  
       }
 705  
       fireArrayStartEvent( jsonConfig );
 706  
       
 707  
       JSONArray jsonArray = new JSONArray();
 708  0
       try{
 709  
          for( int i = 0; i < array.length; i++ ){
 710  0
             Float f = new Float( array[i] );
 711  
             JSONUtils.testValidity( f );
 712  0
             jsonArray.addValue( f, jsonConfig );
 713  0
             fireElementAddedEvent( i, f, jsonConfig );
 714  0
          }
 715  0
       }catch( JSONException jsone ){
 716  0
          removeInstance( array );
 717  0
          fireErrorEvent( jsone, jsonConfig );
 718  0
          throw jsone;
 719  0
       }
 720  0
 
 721  
       removeInstance( array );
 722  
       fireArrayEndEvent( jsonConfig );
 723  0
       return jsonArray;
 724  0
    }
 725  0
 
 726  0
    /**
 727  0
     * Construct a JSONArray from an int[].<br>
 728  0
     *
 729  
     * @param array An int[] array.
 730  
     */
 731  0
    private static JSONArray _fromArray( int[] array, JsonConfig jsonConfig ) {
 732  0
       if( !addInstance( array ) ){
 733  0
          try{
 734  
             return jsonConfig.getCycleDetectionStrategy()
 735  
                   .handleRepeatedReferenceAsArray( array );
 736  
          }catch( JSONException jsone ){
 737  
             removeInstance( array );
 738  
             fireErrorEvent( jsone, jsonConfig );
 739  
             throw jsone;
 740  
          }catch( RuntimeException e ){
 741  
             removeInstance( array );
 742  0
             JSONException jsone = new JSONException( e );
 743  
             fireErrorEvent( jsone, jsonConfig );
 744  0
             throw jsone;
 745  
          }
 746  0
       }
 747  0
       fireArrayStartEvent( jsonConfig );
 748  0
       
 749  0
       JSONArray jsonArray = new JSONArray();
 750  0
       for( int i = 0; i < array.length; i++ ){
 751  0
          Number n = new Integer( array[i] );
 752  0
          jsonArray.addValue( n, jsonConfig );
 753  0
          fireElementAddedEvent( i, n, jsonConfig );
 754  0
       }
 755  
 
 756  
       removeInstance( array );
 757  0
       fireArrayEndEvent( jsonConfig );
 758  0
       return jsonArray;
 759  0
    }
 760  0
 
 761  0
    /**
 762  0
     * Construct a JSONArray from an long[].<br>
 763  
     *
 764  
     * @param array An long[] array.
 765  0
     */
 766  0
    private static JSONArray _fromArray( long[] array, JsonConfig jsonConfig ) {
 767  0
       if( !addInstance( array ) ){
 768  
          try{
 769  
             return jsonConfig.getCycleDetectionStrategy()
 770  
                   .handleRepeatedReferenceAsArray( array );
 771  
          }catch( JSONException jsone ){
 772  
             removeInstance( array );
 773  
             fireErrorEvent( jsone, jsonConfig );
 774  
             throw jsone;
 775  
          }catch( RuntimeException e ){
 776  0
             removeInstance( array );
 777  
             JSONException jsone = new JSONException( e );
 778  0
             fireErrorEvent( jsone, jsonConfig );
 779  
             throw jsone;
 780  0
          }
 781  0
       }
 782  0
       fireArrayStartEvent( jsonConfig );
 783  0
       
 784  0
       JSONArray jsonArray = new JSONArray();
 785  0
       for( int i = 0; i < array.length; i++ ){
 786  0
          Number n = JSONUtils.transformNumber( new Long( array[i] ) );
 787  0
          jsonArray.addValue( n, jsonConfig );
 788  0
          fireElementAddedEvent( i, n, jsonConfig );
 789  
       }
 790  
 
 791  0
       removeInstance( array );
 792  0
       fireArrayEndEvent( jsonConfig );
 793  
       return jsonArray;
 794  0
    }
 795  0
 
 796  0
    // ------------------------------------------------------
 797  0
 
 798  0
    private static JSONArray _fromArray( Object[] array, JsonConfig jsonConfig ) {
 799  
       if( !addInstance( array ) ){
 800  0
          try{
 801  0
             return jsonConfig.getCycleDetectionStrategy()
 802  0
                   .handleRepeatedReferenceAsArray( array );
 803  0
          }catch( JSONException jsone ){
 804  0
             removeInstance( array );
 805  
             fireErrorEvent( jsone, jsonConfig );
 806  0
             throw jsone;
 807  0
          }catch( RuntimeException e ){
 808  0
             removeInstance( array );
 809  
             JSONException jsone = new JSONException( e );
 810  
             fireErrorEvent( jsone, jsonConfig );
 811  
             throw jsone;
 812  
          }
 813  
       }
 814  
       fireArrayStartEvent( jsonConfig );
 815  
       
 816  
       JSONArray jsonArray = new JSONArray();
 817  
       try{
 818  0
          for( int i = 0; i < array.length; i++ ){
 819  
             Object element = array[i];
 820  0
             jsonArray.addValue( element, jsonConfig );
 821  
             fireElementAddedEvent( i, jsonArray.get( i ), jsonConfig );
 822  0
          }
 823  0
       }catch( JSONException jsone ){
 824  0
          removeInstance( array );
 825  0
          fireErrorEvent( jsone, jsonConfig );
 826  0
          throw jsone;
 827  0
       }catch( RuntimeException e ){
 828  0
          removeInstance( array );
 829  0
          JSONException jsone = new JSONException( e );
 830  0
          fireErrorEvent( jsone, jsonConfig );
 831  
          throw jsone;
 832  
       }
 833  0
 
 834  0
       removeInstance( array );
 835  0
       fireArrayEndEvent( jsonConfig );
 836  0
       return jsonArray;
 837  0
    }
 838  
 
 839  0
    /**
 840  0
     * Construct a JSONArray from an short[].<br>
 841  0
     *
 842  0
     * @param array An short[] array.
 843  
     */
 844  
    private static JSONArray _fromArray( short[] array, JsonConfig jsonConfig ) {
 845  0
       if( !addInstance( array ) ){
 846  0
          try{
 847  0
             return jsonConfig.getCycleDetectionStrategy()
 848  
                   .handleRepeatedReferenceAsArray( array );
 849  
          }catch( JSONException jsone ){
 850  
             removeInstance( array );
 851  
             fireErrorEvent( jsone, jsonConfig );
 852  
             throw jsone;
 853  
          }catch( RuntimeException e ){
 854  
             removeInstance( array );
 855  
             JSONException jsone = new JSONException( e );
 856  0
             fireErrorEvent( jsone, jsonConfig );
 857  
             throw jsone;
 858  0
          }
 859  
       }
 860  0
       fireArrayStartEvent( jsonConfig );
 861  0
       
 862  0
       JSONArray jsonArray = new JSONArray();
 863  0
       for( int i = 0; i < array.length; i++ ){
 864  0
          Number n = JSONUtils.transformNumber( new Short( array[i] ) );
 865  0
          jsonArray.addValue( n, jsonConfig );
 866  0
          fireElementAddedEvent( i, n, jsonConfig );
 867  0
       }
 868  0
 
 869  
       removeInstance( array );
 870  
       fireArrayEndEvent( jsonConfig );
 871  0
       return jsonArray;
 872  0
    }
 873  
 
 874  0
    private static JSONArray _fromCollection( Collection collection, JsonConfig jsonConfig ) {
 875  0
       if( !addInstance( collection ) ){
 876  0
          try{
 877  0
             return jsonConfig.getCycleDetectionStrategy()
 878  0
                   .handleRepeatedReferenceAsArray( collection );
 879  
          }catch( JSONException jsone ){
 880  0
             removeInstance( collection );
 881  0
             fireErrorEvent( jsone, jsonConfig );
 882  0
             throw jsone;
 883  0
          }catch( RuntimeException e ){
 884  0
             removeInstance( collection );
 885  
             JSONException jsone = new JSONException( e );
 886  0
             fireErrorEvent( jsone, jsonConfig );
 887  0
             throw jsone;
 888  0
          }
 889  
       }
 890  
       fireArrayStartEvent( jsonConfig );
 891  
       
 892  
       JSONArray jsonArray = new JSONArray();
 893  
       try{
 894  
          int i = 0;
 895  
          for( Iterator elements = collection.iterator(); elements.hasNext(); ){
 896  
             Object element = elements.next();
 897  0
             jsonArray.addValue( element, jsonConfig );
 898  
             fireElementAddedEvent( i, jsonArray.get( i++ ), jsonConfig );
 899  0
          }
 900  
       }catch( JSONException jsone ){
 901  0
          removeInstance( collection );
 902  0
          fireErrorEvent( jsone, jsonConfig );
 903  0
          throw jsone;
 904  0
       }catch( RuntimeException e ){
 905  0
          removeInstance( collection );
 906  0
          JSONException jsone = new JSONException( e );
 907  0
          fireErrorEvent( jsone, jsonConfig );
 908  0
          throw jsone;
 909  0
       }
 910  
 
 911  
       removeInstance( collection );
 912  0
       fireArrayEndEvent( jsonConfig );
 913  0
       return jsonArray;
 914  0
    }
 915  0
 
 916  0
    private static JSONArray _fromJSONArray( JSONArray array, JsonConfig jsonConfig ) {
 917  0
       if( !addInstance( array ) ){
 918  
          try{
 919  
             return jsonConfig.getCycleDetectionStrategy()
 920  0
                   .handleRepeatedReferenceAsArray( array );
 921  0
          }catch( JSONException jsone ){
 922  0
             removeInstance( array );
 923  
             fireErrorEvent( jsone, jsonConfig );
 924  
             throw jsone;
 925  
          }catch( RuntimeException e ){
 926  
             removeInstance( array );
 927  
             JSONException jsone = new JSONException( e );
 928  
             fireErrorEvent( jsone, jsonConfig );
 929  
             throw jsone;
 930  
          }
 931  0
       }
 932  
       fireArrayStartEvent( jsonConfig );
 933  0
       
 934  
       JSONArray jsonArray = new JSONArray();
 935  0
       int index = 0;
 936  0
       for( Iterator elements = array.iterator(); elements.hasNext(); ){
 937  0
          Object element = elements.next();
 938  0
          jsonArray.addValue( element, jsonConfig );
 939  0
          fireElementAddedEvent( index++, element, jsonConfig );
 940  0
       }
 941  0
 
 942  0
       removeInstance( array );
 943  0
       fireArrayEndEvent( jsonConfig );
 944  
       return jsonArray;
 945  
    }
 946  0
 
 947  0
    private static JSONArray _fromJSONString( JSONString string, JsonConfig jsonConfig ) {
 948  0
       return _fromJSONTokener( new JSONTokener( string.toJSONString() ), jsonConfig );
 949  0
    }
 950  0
 
 951  0
    private static JSONArray _fromJSONTokener( JSONTokener tokener, JsonConfig jsonConfig ) {
 952  
       JSONArray jsonArray = new JSONArray();
 953  
       int index = 0;
 954  0
 
 955  0
       try{
 956  0
          if( tokener.nextClean() != '[' ){
 957  
             throw tokener.syntaxError( "A JSONArray text must start with '['" );
 958  
          }
 959  
 
 960  
          fireArrayStartEvent( jsonConfig );
 961  
          if( tokener.nextClean() == ']' ){
 962  0
             fireArrayEndEvent( jsonConfig );
 963  
             return jsonArray;
 964  0
          }
 965  
          tokener.back();
 966  0
          for( ;; ){
 967  0
             if( tokener.nextClean() == ',' ){
 968  0
                tokener.back();
 969  0
                jsonArray.elements.add( JSONNull.getInstance() );
 970  0
                fireElementAddedEvent( index, jsonArray.get( index++ ), jsonConfig );
 971  0
             }else{
 972  0
                tokener.back();
 973  0
                Object v = tokener.nextValue( jsonConfig );
 974  0
                if( !JSONUtils.isFunctionHeader( v ) ){
 975  
                   if( v instanceof String && JSONUtils.mayBeJSON( (String) v ) ){
 976  
                      jsonArray.addValue( JSONUtils.DOUBLE_QUOTE + v + JSONUtils.DOUBLE_QUOTE,
 977  0
                            jsonConfig );
 978  0
                   }else{
 979  
                      jsonArray.addValue( v, jsonConfig );
 980  0
                   }
 981  0
                   fireElementAddedEvent( index, jsonArray.get( index++ ), jsonConfig );
 982  0
                }else{
 983  0
                   // read params if any
 984  
                   String params = JSONUtils.getFunctionParams( (String) v );
 985  0
                   // read function text
 986  0
                   int i = 0;
 987  0
                   StringBuffer sb = new StringBuffer();
 988  0
                   for( ;; ){
 989  0
                      char ch = tokener.next();
 990  0
                      if( ch == 0 ){
 991  0
                         break;
 992  0
                      }
 993  0
                      if( ch == '{' ){
 994  0
                         i++;
 995  
                      }
 996  0
                      if( ch == '}' ){
 997  0
                         i--;
 998  0
                      }
 999  
                      sb.append( ch );
 1000  
                      if( i == 0 ){
 1001  
                         break;
 1002  
                      }
 1003  
                   }
 1004  
                   if( i != 0 ){
 1005  
                      throw tokener.syntaxError( "Unbalanced '{' or '}' on prop: " + v );
 1006  
                   }
 1007  0
                   // trim '{' at start and '}' at end
 1008  
                   String text = sb.toString();
 1009  0
                   text = text.substring( 1, text.length() - 1 )
 1010  
                         .trim();
 1011  0
                   jsonArray.addValue( new JSONFunction( (params != null) ? StringUtils.split(
 1012  0
                         params, "," ) : null, text ), jsonConfig );
 1013  0
                   fireElementAddedEvent( index, jsonArray.get( index++ ), jsonConfig );
 1014  0
                }
 1015  0
             }
 1016  0
             switch( tokener.nextClean() ){
 1017  0
                case ';':
 1018  0
                case ',':
 1019  0
                   if( tokener.nextClean() == ']' ){
 1020  
                      fireArrayEndEvent( jsonConfig );
 1021  
                      return jsonArray;
 1022  0
                   }
 1023  0
                   tokener.back();
 1024  0
                   break;
 1025  0
                case ']':
 1026  0
                   fireArrayEndEvent( jsonConfig );
 1027  0
                   return jsonArray;
 1028  
                default:
 1029  
                   throw tokener.syntaxError( "Expected a ',' or ']'" );
 1030  0
             }
 1031  0
          }
 1032  0
       }catch( JSONException jsone ){
 1033  
          fireErrorEvent( jsone, jsonConfig );
 1034  
          throw jsone;
 1035  
       }
 1036  0
    }
 1037  
 
 1038  0
    private static JSONArray _fromString( String string, JsonConfig jsonConfig ) {
 1039  
       return _fromJSONTokener( new JSONTokener( string ), jsonConfig );
 1040  0
    }
 1041  0
 
 1042  0
    private static void processArrayDimensions( JSONArray jsonArray, List dims, int index ) {
 1043  0
       if( dims.size() <= index ){
 1044  0
          dims.add( new Integer( jsonArray.size() ) );
 1045  0
       }else{
 1046  0
          int i = ((Integer) dims.get( index )).intValue();
 1047  0
          if( jsonArray.size() > i ){
 1048  0
             dims.set( index, new Integer( jsonArray.size() ) );
 1049  
          }
 1050  
       }
 1051  0
       for( Iterator i = jsonArray.iterator(); i.hasNext(); ){
 1052  0
          Object item = i.next();
 1053  
          if( item instanceof JSONArray ){
 1054  0
             processArrayDimensions( (JSONArray) item, dims, index + 1 );
 1055  0
          }
 1056  0
       }
 1057  0
    }
 1058  0
 
 1059  0
    // ------------------------------------------------------
 1060  0
 
 1061  0
    /**
 1062  0
     * The List where the JSONArray's properties are kept.
 1063  0
     */
 1064  0
    private List elements;
 1065  0
 
 1066  0
    /**
 1067  0
     * A flag for XML processing.
 1068  0
     */
 1069  0
    private boolean expandElements;
 1070  
 
 1071  0
    /**
 1072  0
     * Construct an empty JSONArray.
 1073  0
     */
 1074  
    public JSONArray() {
 1075  
       this.elements = new ArrayList();
 1076  
    }
 1077  0
 
 1078  
    public void add( int index, Object value ) {
 1079  0
       add( index, value, new JsonConfig() );
 1080  
    }
 1081  0
 
 1082  0
    public void add( int index, Object value, JsonConfig jsonConfig ) {
 1083  0
       this.elements.add( index, processValue( value, jsonConfig ) );
 1084  0
    }
 1085  0
 
 1086  0
    public boolean add( Object value ) {
 1087  0
       return add( value, new JsonConfig() );
 1088  0
    }
 1089  0
 
 1090  
    public boolean add( Object value, JsonConfig jsonConfig ) {
 1091  
       element( value, jsonConfig );
 1092  0
       return true;
 1093  0
    }
 1094  0
 
 1095  0
    public boolean addAll( Collection collection ) {
 1096  0
       return addAll( collection, new JsonConfig() );
 1097  0
    }
 1098  0
 
 1099  0
    public boolean addAll( Collection collection, JsonConfig jsonConfig ) {
 1100  
       if( collection == null || collection.size() == 0 ){
 1101  0
          return false;
 1102  0
       }
 1103  0
       for( Iterator i = collection.iterator(); i.hasNext(); ){
 1104  
          element( i.next(), jsonConfig );
 1105  
       }
 1106  
       return true;
 1107  0
    }
 1108  
 
 1109  
    public boolean addAll( int index, Collection collection ) {
 1110  
       return addAll( index, collection, new JsonConfig() );
 1111  
    }
 1112  0
 
 1113  0
    public boolean addAll( int index, Collection collection, JsonConfig jsonConfig ) {
 1114  
       if( collection == null || collection.size() == 0 ){
 1115  
          return false;
 1116  0
       }
 1117  0
       int offset = 0;
 1118  
       for( Iterator i = collection.iterator(); i.hasNext(); ){
 1119  0
          this.elements.add( index + (offset++), processValue( i.next(), jsonConfig ) );
 1120  0
       }
 1121  0
       return true;
 1122  0
    }
 1123  
 
 1124  0
    public void clear() {
 1125  
       elements.clear();
 1126  0
    }
 1127  0
 
 1128  0
    public int compareTo( Object obj ) {
 1129  0
       if( obj != null && (obj instanceof JSONArray) ){
 1130  
          JSONArray other = (JSONArray) obj;
 1131  0
          int size1 = size();
 1132  0
          int size2 = other.size();
 1133  0
          if( size1 < size2 ){
 1134  0
             return -1;
 1135  0
          }else if( size1 > size2 ){
 1136  
             return 1;
 1137  
          }else if( this.equals( other ) ){
 1138  0
             return 0;
 1139  
          }
 1140  0
       }
 1141  
       return -1;
 1142  
    }
 1143  0
 
 1144  
    public boolean contains( Object o ) {
 1145  0
       return contains( o, new JsonConfig() );
 1146  0
    }
 1147  
 
 1148  0
    public boolean contains( Object o, JsonConfig jsonConfig ) {
 1149  0
       return elements.contains( processValue( o, jsonConfig ) );
 1150  0
    }
 1151  
 
 1152  0
    public boolean containsAll( Collection collection ) {
 1153  0
       return containsAll( collection, new JsonConfig() );
 1154  
    }
 1155  0
 
 1156  0
    public boolean containsAll( Collection collection, JsonConfig jsonConfig ) {
 1157  
       return elements.containsAll( fromObject( collection, jsonConfig ) );
 1158  0
    }
 1159  0
 
 1160  0
    /**
 1161  
     * Remove an element, if present.
 1162  0
     *
 1163  0
     * @param index the index of the element.
 1164  0
     * @return this.
 1165  
     */
 1166  
    public JSONArray discard( int index ) {
 1167  0
       elements.remove( index );
 1168  0
       return this;
 1169  
    }
 1170  0
 
 1171  
    /**
 1172  0
     * Remove an element, if present.
 1173  
     *
 1174  
     * @param index the element.
 1175  0
     * @return this.
 1176  
     */
 1177  
    public JSONArray discard( Object o ) {
 1178  0
       elements.remove( o );
 1179  0
       return this;
 1180  0
    }
 1181  
 
 1182  0
    /**
 1183  0
     * Append a boolean value. This increases the array's length by one.
 1184  
     *
 1185  0
     * @param value A boolean value.
 1186  0
     * @return this.
 1187  
     */
 1188  0
    public JSONArray element( boolean value ) {
 1189  
       return element( value ? Boolean.TRUE : Boolean.FALSE );
 1190  
    }
 1191  0
 
 1192  0
    /**
 1193  0
     * Append a value in the JSONArray, where the value will be a JSONArray which
 1194  
     * is produced from a Collection.
 1195  
     *
 1196  
     * @param value A Collection value.
 1197  
     * @return this.
 1198  0
     */
 1199  
    public JSONArray element( Collection value ) {
 1200  
       return element( value, new JsonConfig() );
 1201  
    }
 1202  0
 
 1203  0
    /**
 1204  
     * Append a value in the JSONArray, where the value will be a JSONArray which
 1205  0
     * is produced from a Collection.
 1206  0
     *
 1207  0
     * @param value A Collection value.
 1208  
     * @return this.
 1209  
     */
 1210  0
    public JSONArray element( Collection value, JsonConfig jsonConfig ) {
 1211  0
       if( value instanceof JSONArray ){
 1212  0
          elements.add( value );
 1213  0
          return this;
 1214  
       }else{
 1215  0
          return element( _fromCollection( value, jsonConfig ) );
 1216  0
       }
 1217  
    }
 1218  
 
 1219  
    /**
 1220  
     * Append a double value. This increases the array's length by one.
 1221  
     *
 1222  
     * @param value A double value.
 1223  
     * @throws JSONException if the value is not finite.
 1224  
     * @return this.
 1225  
     */
 1226  
    public JSONArray element( double value ) {
 1227  
       Double d = new Double( value );
 1228  
       JSONUtils.testValidity( d );
 1229  
       return element( d );
 1230  
    }
 1231  
 
 1232  
    /**
 1233  0
     * Append an int value. This increases the array's length by one.
 1234  0
     *
 1235  0
     * @param value An int value.
 1236  
     * @return this.
 1237  
     */
 1238  0
    public JSONArray element( int value ) {
 1239  0
       return element( new Integer( value ) );
 1240  
    }
 1241  
 
 1242  0
    /**
 1243  0
     * Put or replace a boolean value in the JSONArray. If the index is greater
 1244  
     * than the length of the JSONArray, then null elements will be added as
 1245  
     * necessary to pad it out.
 1246  0
     *
 1247  
     * @param index The subscript.
 1248  
     * @param value A boolean value.
 1249  
     * @return this.
 1250  0
     * @throws JSONException If the index is negative.
 1251  0
     */
 1252  
    public JSONArray element( int index, boolean value ) {
 1253  
       return element( index, value ? Boolean.TRUE : Boolean.FALSE );
 1254  
    }
 1255  0
 
 1256  
    /**
 1257  
     * Put a value in the JSONArray, where the value will be a JSONArray which is
 1258  
     * produced from a Collection.
 1259  0
     *
 1260  0
     * @param index The subscript.
 1261  
     * @param value A Collection value.
 1262  0
     * @return this.
 1263  0
     * @throws JSONException If the index is negative or if the value is not
 1264  
     *         finite.
 1265  0
     */
 1266  
    public JSONArray element( int index, Collection value ) {
 1267  
       return element( index, value, new JsonConfig() );
 1268  
    }
 1269  0
 
 1270  
    /**
 1271  
     * Put a value in the JSONArray, where the value will be a JSONArray which is
 1272  
     * produced from a Collection.
 1273  0
     *
 1274  0
     * @param index The subscript.
 1275  
     * @param value A Collection value.
 1276  0
     * @return this.
 1277  0
     * @throws JSONException If the index is negative or if the value is not
 1278  0
     *         finite.
 1279  
     */
 1280  0
    public JSONArray element( int index, Collection value, JsonConfig jsonConfig ) {
 1281  
       if( value instanceof JSONArray ){
 1282  
          if( index < 0 ){
 1283  
             throw new JSONException( "JSONArray[" + index + "] not found." );
 1284  0
          }
 1285  0
          if( index < size() ){
 1286  
             elements.set( index, value );
 1287  
          }else{
 1288  0
             while( index != size() ){
 1289  0
                element( JSONNull.getInstance() );
 1290  0
             }
 1291  0
             element( value, jsonConfig );
 1292  0
          }
 1293  0
          return this;
 1294  0
       }else{
 1295  0
          return element( index, _fromCollection( value, jsonConfig ) );
 1296  0
       }
 1297  0
    }
 1298  
 
 1299  
    /**
 1300  0
     * Put or replace a double value. If the index is greater than the length of
 1301  
     * the JSONArray, then null elements will be added as necessary to pad it
 1302  
     * out.
 1303  
     *
 1304  0
     * @param index The subscript.
 1305  
     * @param value A double value.
 1306  
     * @return this.
 1307  
     * @throws JSONException If the index is negative or if the value is not
 1308  0
     *         finite.
 1309  
     */
 1310  
    public JSONArray element( int index, double value ) {
 1311  
       return element( index, new Double( value ) );
 1312  0
    }
 1313  
 
 1314  
    /**
 1315  
     * Put or replace an int value. If the index is greater than the length of
 1316  0
     * the JSONArray, then null elements will be added as necessary to pad it
 1317  
     * out.
 1318  
     *
 1319  
     * @param index The subscript.
 1320  
     * @param value An int value.
 1321  
     * @return this.
 1322  
     * @throws JSONException If the index is negative.
 1323  
     */
 1324  
    public JSONArray element( int index, int value ) {
 1325  
       return element( index, new Integer( value ) );
 1326  0
    }
 1327  0
 
 1328  
    /**
 1329  
     * Put or replace a long value. If the index is greater than the length of
 1330  
     * the JSONArray, then null elements will be added as necessary to pad it
 1331  
     * out.
 1332  
     *
 1333  
     * @param index The subscript.
 1334  
     * @param value A long value.
 1335  
     * @return this.
 1336  
     * @throws JSONException If the index is negative.
 1337  0
     */
 1338  0
    public JSONArray element( int index, long value ) {
 1339  
       return element( index, new Long( value ) );
 1340  
    }
 1341  
 
 1342  
    /**
 1343  
     * Put a value in the JSONArray, where the value will be a JSONObject which
 1344  
     * is produced from a Map.
 1345  
     *
 1346  
     * @param index The subscript.
 1347  
     * @param value The Map value.
 1348  0
     * @return this.
 1349  
     * @throws JSONException If the index is negative or if the the value is an
 1350  
     *         invalid number.
 1351  
     */
 1352  
    public JSONArray element( int index, Map value ) {
 1353  
       return element( index, value, new JsonConfig() );
 1354  
    }
 1355  
 
 1356  
    /**
 1357  
     * Put a value in the JSONArray, where the value will be a JSONObject which
 1358  
     * is produced from a Map.
 1359  0
     *
 1360  
     * @param index The subscript.
 1361  
     * @param value The Map value.
 1362  
     * @return this.
 1363  
     * @throws JSONException If the index is negative or if the the value is an
 1364  
     *         invalid number.
 1365  
     */
 1366  
    public JSONArray element( int index, Map value, JsonConfig jsonConfig ) {
 1367  
       if( value instanceof JSONObject ){
 1368  
          if( index < 0 ){
 1369  
             throw new JSONException( "JSONArray[" + index + "] not found." );
 1370  0
          }
 1371  0
          if( index < size() ){
 1372  0
             elements.set( index, value );
 1373  
          }else{
 1374  0
             while( index != size() ){
 1375  
                element( JSONNull.getInstance() );
 1376  
             }
 1377  
             element( value, jsonConfig );
 1378  
          }
 1379  
          return this;
 1380  
       }else{
 1381  
          return element( index, JSONObject.fromObject( value, jsonConfig ) );
 1382  
       }
 1383  
    }
 1384  
 
 1385  
    /**
 1386  0
     * Put or replace an object value in the JSONArray. If the index is greater
 1387  0
     * than the length of the JSONArray, then null elements will be added as
 1388  0
     * necessary to pad it out.
 1389  
     *
 1390  
     * @param index The subscript.
 1391  
     * @param value An object value. The value should be a Boolean, Double,
 1392  
     *        Integer, JSONArray, JSONObject, JSONFunction, Long, String,
 1393  
     *        JSONString or the JSONNull object.
 1394  
     * @return this.
 1395  
     * @throws JSONException If the index is negative or if the the value is an
 1396  
     *         invalid number.
 1397  
     */
 1398  0
    public JSONArray element( int index, Object value ) {
 1399  
       return element( index, value, new JsonConfig() );
 1400  
    }
 1401  
 
 1402  
    /**
 1403  
     * Put or replace an object value in the JSONArray. If the index is greater
 1404  
     * than the length of the JSONArray, then null elements will be added as
 1405  
     * necessary to pad it out.
 1406  
     *
 1407  
     * @param index The subscript.
 1408  
     * @param value An object value. The value should be a Boolean, Double,
 1409  
     *        Integer, JSONArray, JSONObject, JSONFunction, Long, String,
 1410  
     *        JSONString or the JSONNull object.
 1411  
     * @return this.
 1412  0
     * @throws JSONException If the index is negative or if the the value is an
 1413  
     *         invalid number.
 1414  
     */
 1415  
    public JSONArray element( int index, Object value, JsonConfig jsonConfig ) {
 1416  
       JSONUtils.testValidity( value );
 1417  
       if( index < 0 ){
 1418  
          throw new JSONException( "JSONArray[" + index + "] not found." );
 1419  
       }
 1420  
       if( index < size() ){
 1421  
          this.elements.set( index, processValue( value, jsonConfig ) );
 1422  
       }else{
 1423  
          while( index != size() ){
 1424  
             element( JSONNull.getInstance() );
 1425  
          }
 1426  0
          element( value, jsonConfig );
 1427  
       }
 1428  
       return this;
 1429  
    }
 1430  
 
 1431  
    /**
 1432  
     * Put or replace a String value in the JSONArray. If the index is greater
 1433  
     * than the length of the JSONArray, then null elements will be added as
 1434  
     * necessary to pad it out.<br>
 1435  
     * The string may be a valid JSON formatted string, in tha case, it will be
 1436  
     * transformed to a JSONArray, JSONObject or JSONNull.
 1437  
     *
 1438  
     * @param index The subscript.
 1439  
     * @param value A String value.
 1440  0
     * @return this.
 1441  0
     * @throws JSONException If the index is negative or if the the value is an
 1442  0
     *         invalid number.
 1443  
     */
 1444  0
    public JSONArray element( int index, String value ) {
 1445  0
       return element( index, value, new JsonConfig() );
 1446  
    }
 1447  0
 
 1448  0
    /**
 1449  
     * Put or replace a String value in the JSONArray. If the index is greater
 1450  0
     * than the length of the JSONArray, then null elements will be added as
 1451  
     * necessary to pad it out.<br>
 1452  0
     * The string may be a valid JSON formatted string, in tha case, it will be
 1453  
     * transformed to a JSONArray, JSONObject or JSONNull.
 1454  0
     *
 1455  
     * @param index The subscript.
 1456  
     * @param value A String value.
 1457  
     * @return this.
 1458  
     * @throws JSONException If the index is negative or if the the value is an
 1459  
     *         invalid number.
 1460  
     */
 1461  
    public JSONArray element( int index, String value, JsonConfig jsonConfig ) {
 1462  
       if( index < 0 ){
 1463  
          throw new JSONException( "JSONArray[" + index + "] not found." );
 1464  
       }
 1465  
       if( index < size() ){
 1466  
          if( value == null ){
 1467  
             this.elements.set( index, "" );
 1468  
          }else if( JSONUtils.mayBeJSON( value ) ){
 1469  
             try{
 1470  0
                this.elements.set( index, JSONSerializer.toJSON( value, jsonConfig ) );
 1471  
             }catch( JSONException jsone ){
 1472  
                this.elements.set( index, JSONUtils.stripQuotes( value ) );
 1473  
             }
 1474  
          }else{
 1475  
             this.elements.set( index, JSONUtils.stripQuotes( value ) );
 1476  
          }
 1477  
       }else{
 1478  
          while( index != size() ){
 1479  
             element( JSONNull.getInstance() );
 1480  
          }
 1481  
          element( value, jsonConfig );
 1482  
       }
 1483  
       return this;
 1484  0
    }
 1485  
 
 1486  
    /**
 1487  
     * Append an JSON value. This increases the array's length by one.
 1488  
     *
 1489  
     * @param value An JSON value.
 1490  
     * @return this.
 1491  
     */
 1492  
    public JSONArray element( JSONNull value ) {
 1493  
       this.elements.add( value );
 1494  
       return this;
 1495  
    }
 1496  
 
 1497  
    /**
 1498  0
     * Append an JSON value. This increases the array's length by one.
 1499  
     *
 1500  
     * @param value An JSON value.
 1501  
     * @return this.
 1502  
     */
 1503  
    public JSONArray element( JSONObject value ) {
 1504  
       this.elements.add( value );
 1505  
       return this;
 1506  
    }
 1507  
 
 1508  
    /**
 1509  
     * Append an long value. This increases the array's length by one.
 1510  
     *
 1511  
     * @param value A long value.
 1512  0
     * @return this.
 1513  
     */
 1514  
    public JSONArray element( long value ) {
 1515  
       return element( JSONUtils.transformNumber( new Long( value ) ) );
 1516  
    }
 1517  
 
 1518  
    /**
 1519  
     * Put a value in the JSONArray, where the value will be a JSONObject which
 1520  
     * is produced from a Map.
 1521  
     *
 1522  
     * @param value A Map value.
 1523  
     * @return this.
 1524  
     */
 1525  
    public JSONArray element( Map value ) {
 1526  0
       return element( value, new JsonConfig() );
 1527  0
    }
 1528  0
 
 1529  
    /**
 1530  0
     * Put a value in the JSONArray, where the value will be a JSONObject which
 1531  0
     * is produced from a Map.
 1532  
     *
 1533  0
     * @param value A Map value.
 1534  0
     * @return this.
 1535  
     */
 1536  0
    public JSONArray element( Map value, JsonConfig jsonConfig ) {
 1537  
       if( value instanceof JSONObject ){
 1538  0
          elements.add( value );
 1539  
          return this;
 1540  0
       }else{
 1541  
          return element( JSONObject.fromObject( value, jsonConfig ) );
 1542  
       }
 1543  
    }
 1544  
 
 1545  
    /**
 1546  
     * Append an object value. This increases the array's length by one.
 1547  
     *
 1548  
     * @param value An object value. The value should be a Boolean, Double,
 1549  
     *        Integer, JSONArray, JSONObject, JSONFunction, Long, String,
 1550  
     *        JSONString or the JSONNull object.
 1551  
     * @return this.
 1552  
     */
 1553  
    public JSONArray element( Object value ) {
 1554  
       return element( value, new JsonConfig() );
 1555  
    }
 1556  
 
 1557  
    /**
 1558  0
     * Append an object value. This increases the array's length by one.
 1559  
     *
 1560  
     * @param value An object value. The value should be a Boolean, Double,
 1561  
     *        Integer, JSONArray, JSONObject, JSONFunction, Long, String,
 1562  
     *        JSONString or the JSONNull object.
 1563  
     * @return this.
 1564  
     */
 1565  
    public JSONArray element( Object value, JsonConfig jsonConfig ) {
 1566  
       return addValue( value, jsonConfig );
 1567  
    }
 1568  
 
 1569  
    /**
 1570  
     * Append a String value. This increases the array's length by one.<br>
 1571  
     * The string may be a valid JSON formatted string, in tha case, it will be
 1572  
     * transformed to a JSONArray, JSONObject or JSONNull.
 1573  
     *
 1574  
     * @param value A String value.
 1575  0
     * @return this.
 1576  0
     */
 1577  0
    public JSONArray element( String value ) {
 1578  
       return element( value, new JsonConfig() );
 1579  0
    }
 1580  0
 
 1581  
    /**
 1582  0
     * Append a String value. This increases the array's length by one.<br>
 1583  0
     * The string may be a valid JSON formatted string, in tha case, it will be
 1584  
     * transformed to a JSONArray, JSONObject or JSONNull.
 1585  0
     *
 1586  
     * @param value A String value.
 1587  0
     * @return this.
 1588  
     */
 1589  
    public JSONArray element( String value, JsonConfig jsonConfig ) {
 1590  
       if( value == null ) {
 1591  
          this.elements.add("");
 1592  
       } else if( JSONUtils.hasQuotes( value )) {
 1593  
          this.elements.add(value);
 1594  
       } else if( JSONNull.getInstance().equals( value )) {
 1595  
          this.elements.add( JSONNull.getInstance() );
 1596  
       } else if( JSONUtils.isJsonKeyword(value,jsonConfig)) {
 1597  
          if( jsonConfig.isJavascriptCompliant() && "undefined".equals( value )){
 1598  
             this.elements.add( JSONNull.getInstance() );
 1599  
          }else{
 1600  
             this.elements.add(value);
 1601  
          }
 1602  
       } else if( JSONUtils.mayBeJSON( value ) ){
 1603  
          try{
 1604  0
             this.elements.add( JSONSerializer.toJSON( value, jsonConfig ) );
 1605  
          }catch( JSONException jsone ){
 1606  
             this.elements.add( value );
 1607  
          }
 1608  
       } else {
 1609  
          this.elements.add(value);
 1610  
       }
 1611  
       return this;
 1612  
    }
 1613  
 
 1614  
    public boolean equals( Object obj ) {
 1615  
       if( obj == this ){
 1616  
          return true;
 1617  
       }
 1618  
       if( obj == null ){
 1619  
          return false;
 1620  
       }
 1621  0
 
 1622  0
       if( !(obj instanceof JSONArray) ){
 1623  
          return false;
 1624  0
       }
 1625  0
 
 1626  0
       JSONArray other = (JSONArray) obj;
 1627  0
 
 1628  
       if( other.size() != size() ){
 1629  0
          return false;
 1630  0
       }
 1631  0
 
 1632  0
       int max = size();
 1633  
       for( int i = 0; i < max; i++ ){
 1634  0
          Object o1 = get( i );
 1635  
          Object o2 = other.get( i );
 1636  
 
 1637  0
          // handle nulls
 1638  0
          if( JSONNull.getInstance()
 1639  
                .equals( o1 ) ){
 1640  0
             if( JSONNull.getInstance()
 1641  
                   .equals( o2 ) ){
 1642  0
                continue;
 1643  
             }else{
 1644  
                return false;
 1645  
             }
 1646  
          }else{
 1647  
             if( JSONNull.getInstance()
 1648  
                   .equals( o2 ) ){
 1649  
                return false;
 1650  
             }
 1651  
          }
 1652  0
 
 1653  0
          if( o1 instanceof JSONArray && o2 instanceof JSONArray ){
 1654  
             JSONArray e = (JSONArray) o1;
 1655  
             JSONArray a = (JSONArray) o2;
 1656  
             if( !a.equals( e ) ){
 1657  
                return false;
 1658  
             }
 1659  
          }else{
 1660  
             if( o1 instanceof String && o2 instanceof JSONFunction ){
 1661  
                if( !o1.equals( String.valueOf( o2 ) ) ){
 1662  
                   return false;
 1663  0
                }
 1664  0
             }else if( o1 instanceof JSONFunction && o2 instanceof String ){
 1665  
                if( !o2.equals( String.valueOf( o1 ) ) ){
 1666  
                   return false;
 1667  
                }
 1668  
             }else if( o1 instanceof JSONObject && o2 instanceof JSONObject ){
 1669  
                if( !o1.equals( o2 ) ){
 1670  
                   return false;
 1671  
                }
 1672  
             }else if( o1 instanceof JSONArray && o2 instanceof JSONArray ){
 1673  
                if( !o1.equals( o2 ) ){
 1674  0
                   return false;
 1675  
                }
 1676  
             }else if( o1 instanceof JSONFunction && o2 instanceof JSONFunction ){
 1677  
                if( !o1.equals( o2 ) ){
 1678  
                   return false;
 1679  
                }
 1680  
             }else{
 1681  
                if( o1 instanceof String ){
 1682  
                   if( !o1.equals( String.valueOf( o2 ) ) ){
 1683  
                      return false;
 1684  
                   }
 1685  0
                }else if( o2 instanceof String ){
 1686  
                   if( !o2.equals( String.valueOf( o1 ) ) ){
 1687  
                      return false;
 1688  
                   }
 1689  
                }else{
 1690  
                   Morpher m1 = JSONUtils.getMorpherRegistry()
 1691  
                         .getMorpherFor( o1.getClass() );
 1692  
                   Morpher m2 = JSONUtils.getMorpherRegistry()
 1693  
                         .getMorpherFor( o2.getClass() );
 1694  
                   if( m1 != null && m1 != IdentityObjectMorpher.getInstance() ){
 1695  
                      if( !o1.equals( JSONUtils.getMorpherRegistry()
 1696  0
                            .morph( o1.getClass(), o2 ) ) ){
 1697  0
                         return false;
 1698  0
                      }
 1699  
                   }else if( m2 != null && m2 != IdentityObjectMorpher.getInstance() ){
 1700  0
                      if( !JSONUtils.getMorpherRegistry()
 1701  
                            .morph( o1.getClass(), o1 )
 1702  
                            .equals( o2 ) ){
 1703  
                         return false;
 1704  
                      }
 1705  
                   }else{
 1706  
                      if( !o1.equals( o2 ) ){
 1707  
                         return false;
 1708  
                      }
 1709  
                   }
 1710  
                }
 1711  
             }
 1712  
          }
 1713  0
       }
 1714  
       return true;
 1715  
    }
 1716  
 
 1717  
    /**
 1718  
     * Get the object value associated with an index.
 1719  
     *
 1720  
     * @param index The index must be between 0 and size() - 1.
 1721  
     * @return An object value.
 1722  
     */
 1723  
    public Object get( int index ) {
 1724  
       /*
 1725  0
        * Object o = opt( index ); if( o == null ){ throw new JSONException(
 1726  
        * "JSONArray[" + index + "] not found." ); } return o;
 1727  
        */
 1728  
       return this.elements.get( index );
 1729  
    }
 1730  
 
 1731  
    /**
 1732  
     * Get the boolean value associated with an index. The string values "true"
 1733  
     * and "false" are converted to boolean.
 1734  
     *
 1735  
     * @param index The index must be between 0 and size() - 1.
 1736  
     * @return The truth.
 1737  0
     * @throws JSONException If there is no value for the index or if the value
 1738  
     *         is not convertable to boolean.
 1739  
     */
 1740  
    public boolean getBoolean( int index ) {
 1741  
       Object o = get( index );
 1742  
       if( o != null ){
 1743  
          if( o.equals( Boolean.FALSE )
 1744  
                || (o instanceof String && ((String) o).equalsIgnoreCase( "false" )) ){
 1745  
             return false;
 1746  
          }else if( o.equals( Boolean.TRUE )
 1747  
                || (o instanceof String && ((String) o).equalsIgnoreCase( "true" )) ){
 1748  
             return true;
 1749  0
          }
 1750  0
       }
 1751  0
       throw new JSONException( "JSONArray[" + index + "] is not a Boolean." );
 1752  0
    }
 1753  0
 
 1754  0
    /**
 1755  0
     * Get the double value associated with an index.
 1756  0
     *
 1757  0
     * @param index The index must be between 0 and size() - 1.
 1758  
     * @return The value.
 1759  0
     * @throws JSONException If the key is not found or if the value cannot be
 1760  
     *         converted to a number.
 1761  0
     */
 1762  
    public double getDouble( int index ) {
 1763  0
       Object o = get( index );
 1764  0
       if( o != null ){
 1765  0
          try{
 1766  0
             return o instanceof Number ? ((Number) o).doubleValue()
 1767  
                   : Double.parseDouble( (String) o );
 1768  0
          }catch( Exception e ){
 1769  
             throw new JSONException( "JSONArray[" + index + "] is not a number." );
 1770  0
          }
 1771  
       }
 1772  
       throw new JSONException( "JSONArray[" + index + "] is not a number." );
 1773  
    }
 1774  0
 
 1775  0
    /**
 1776  
     * Get the int value associated with an index.
 1777  0
     *
 1778  0
     * @param index The index must be between 0 and size() - 1.
 1779  
     * @return The value.
 1780  
     * @throws JSONException If the key is not found or if the value cannot be
 1781  0
     *         converted to a number. if the value cannot be converted to a
 1782  0
     *         number.
 1783  
     */
 1784  
    public int getInt( int index ) {
 1785  0
       Object o = get( index );
 1786  
       if( o != null ){
 1787  0
          return o instanceof Number ? ((Number) o).intValue() : (int) getDouble( index );
 1788  0
       }
 1789  
       throw new JSONException( "JSONArray[" + index + "] is not a number." );
 1790  
    }
 1791  0
 
 1792  0
    /**
 1793  0
     * Get the JSONArray associated with an index.
 1794  0
     *
 1795  
     * @param index The index must be between 0 and size() - 1.
 1796  
     * @return A JSONArray value.
 1797  0
     * @throws JSONException If there is no value for the index. or if the value
 1798  
     *         is not a JSONArray
 1799  0
     */
 1800  
    public JSONArray getJSONArray( int index ) {
 1801  0
       Object o = get( index );
 1802  
       if( o != null && o instanceof JSONArray ){
 1803  0
          return (JSONArray) o;
 1804  
       }
 1805  
       throw new JSONException( "JSONArray[" + index + "] is not a JSONArray." );
 1806  0
    }
 1807  
 
 1808  0
    /**
 1809  
     * Get the JSONObject associated with an index.
 1810  
     *
 1811  
     * @param index subscript
 1812  0
     * @return A JSONObject value.
 1813  0
     * @throws JSONException If there is no value for the index or if the value
 1814  0
     *         is not a JSONObject
 1815  0
     */
 1816  0
    public JSONObject getJSONObject( int index ) {
 1817  
       Object o = get( index );
 1818  0
       if( JSONNull.getInstance()
 1819  0
             .equals( o ) ){
 1820  0
          return new JSONObject( true );
 1821  0
       }else if( o instanceof JSONObject ){
 1822  
          return (JSONObject) o;
 1823  0
       }
 1824  0
       throw new JSONException( "JSONArray[" + index + "] is not a JSONObject." );
 1825  0
    }
 1826  
 
 1827  0
    /**
 1828  0
     * Get the long value associated with an index.
 1829  0
     *
 1830  
     * @param index The index must be between 0 and size() - 1.
 1831  0
     * @return The value.
 1832  0
     * @throws JSONException If the key is not found or if the value cannot be
 1833  0
     *         converted to a number.
 1834  
     */
 1835  0
    public long getLong( int index ) {
 1836  0
       Object o = get( index );
 1837  0
       if( o != null ){
 1838  
          return o instanceof Number ? ((Number) o).longValue() : (long) getDouble( index );
 1839  
       }
 1840  0
       throw new JSONException( "JSONArray[" + index + "] is not a number." );
 1841  0
    }
 1842  0
 
 1843  
    /**
 1844  0
     * Get the string associated with an index.
 1845  0
     *
 1846  0
     * @param index The index must be between 0 and size() - 1.
 1847  
     * @return A string value.
 1848  
     * @throws JSONException If there is no value for the index.
 1849  0
     */
 1850  
    public String getString( int index ) {
 1851  0
       Object o = get( index );
 1852  
       if( o != null ){
 1853  0
          return o.toString();
 1854  0
       }
 1855  
       throw new JSONException( "JSONArray[" + index + "] not found." );
 1856  0
    }
 1857  
 
 1858  0
    public int hashCode() {
 1859  0
       int hashcode = 29;
 1860  
 
 1861  
       for( Iterator e = elements.iterator(); e.hasNext(); ){
 1862  0
          Object element = e.next();
 1863  
          hashcode += JSONUtils.hashCode( element );
 1864  
       }
 1865  0
       return hashcode;
 1866  0
    }
 1867  
 
 1868  
    public int indexOf( Object o ) {
 1869  
       return elements.indexOf( o );
 1870  
    }
 1871  
 
 1872  
    public boolean isArray() {
 1873  0
       return true;
 1874  
    }
 1875  
 
 1876  
    public boolean isEmpty() {
 1877  
       return this.elements.isEmpty();
 1878  
    }
 1879  
 
 1880  
    public boolean isExpandElements() {
 1881  
       return expandElements;
 1882  
    }
 1883  
 
 1884  
    /**
 1885  
     * Returns an Iterator for this JSONArray
 1886  
     */
 1887  0
    public Iterator iterator() {
 1888  
       return new JSONArrayListIterator();
 1889  
    }
 1890  
 
 1891  
    /**
 1892  
     * Make a string from the contents of this JSONArray. The
 1893  
     * <code>separator</code> string is inserted between each element. Warning:
 1894  
     * This method assumes that the data structure is acyclical.
 1895  
     *
 1896  
     * @param separator A string that will be inserted between the elements.
 1897  
     * @return a string.
 1898  
     * @throws JSONException If the array contains an invalid number.
 1899  
     */
 1900  0
    public String join( String separator ) {
 1901  0
       return join( separator, false );
 1902  0
    }
 1903  
 
 1904  0
    /**
 1905  0
     * Make a string from the contents of this JSONArray. The
 1906  
     * <code>separator</code> string is inserted between each element. Warning:
 1907  0
     * This method assumes that the data structure is acyclical.
 1908  
     *
 1909  
     * @param separator A string that will be inserted between the elements.
 1910  0
     * @return a string.
 1911  
     * @throws JSONException If the array contains an invalid number.
 1912  
     */
 1913  
    public String join( String separator, boolean stripQuotes ) {
 1914  
       int len = size();
 1915  
       StringBuffer sb = new StringBuffer();
 1916  
 
 1917  
       for( int i = 0; i < len; i += 1 ){
 1918  
          if( i > 0 ){
 1919  
             sb.append( separator );
 1920  
          }
 1921  
          String value = JSONUtils.valueToString( this.elements.get( i ) );
 1922  0
          sb.append( stripQuotes ? JSONUtils.stripQuotes( value ) : value );
 1923  0
       }
 1924  
       return sb.toString();
 1925  0
    }
 1926  
 
 1927  0
    public int lastIndexOf( Object o ) {
 1928  0
       return elements.lastIndexOf( o );
 1929  
    }
 1930  
 
 1931  0
    public ListIterator listIterator() {
 1932  
       return listIterator( 0 );
 1933  
    }
 1934  
 
 1935  
    public ListIterator listIterator( int index ) {
 1936  
       if( index < 0 || index > size() )
 1937  
          throw new IndexOutOfBoundsException( "Index: " + index );
 1938  
 
 1939  
       return new JSONArrayListIterator( index );
 1940  
    }
 1941  
 
 1942  
    /**
 1943  
     * Get the optional object value associated with an index.
 1944  0
     *
 1945  0
     * @param index The index must be between 0 and size() - 1.
 1946  0
     * @return An object value, or null if there is no object at that index.
 1947  
     */
 1948  0
    public Object opt( int index ) {
 1949  
       return (index < 0 || index >= size()) ? null : this.elements.get( index );
 1950  
    }
 1951  
 
 1952  
    /**
 1953  
     * Get the optional boolean value associated with an index. It returns false
 1954  
     * if there is no value at that index, or if the value is not Boolean.TRUE or
 1955  
     * the String "true".
 1956  
     *
 1957  
     * @param index The index must be between 0 and size() - 1.
 1958  
     * @return The truth.
 1959  
     */
 1960  0
    public boolean optBoolean( int index ) {
 1961  0
       return optBoolean( index, false );
 1962  0
    }
 1963  
 
 1964  0
    /**
 1965  
     * Get the optional boolean value associated with an index. It returns the
 1966  
     * defaultValue if there is no value at that index or if it is not a Boolean
 1967  
     * or the String "true" or "false" (case insensitive).
 1968  
     *
 1969  
     * @param index The index must be between 0 and size() - 1.
 1970  
     * @param defaultValue A boolean default.
 1971  
     * @return The truth.
 1972  
     */
 1973  
    public boolean optBoolean( int index, boolean defaultValue ) {
 1974  
       try{
 1975  
          return getBoolean( index );
 1976  0
       }catch( Exception e ){
 1977  0
          return defaultValue;
 1978  
       }
 1979  0
    }
 1980  0
 
 1981  0
    /**
 1982  
     * Get the optional double value associated with an index. NaN is returned if
 1983  0
     * there is no value for the index, or if the value is not a number and
 1984  
     * cannot be converted to a number.
 1985  
     *
 1986  
     * @param index The index must be between 0 and size() - 1.
 1987  
     * @return The value.
 1988  
     */
 1989  
    public double optDouble( int index ) {
 1990  
       return optDouble( index, Double.NaN );
 1991  
    }
 1992  
 
 1993  
    /**
 1994  
     * Get the optional double value associated with an index. The defaultValue
 1995  0
     * is returned if there is no value for the index, or if the value is not a
 1996  0
     * number and cannot be converted to a number.
 1997  0
     *
 1998  
     * @param index subscript
 1999  0
     * @param defaultValue The default value.
 2000  
     * @return The value.
 2001  
     */
 2002  
    public double optDouble( int index, double defaultValue ) {
 2003  
       try{
 2004  
          return getDouble( index );
 2005  
       }catch( Exception e ){
 2006  
          return defaultValue;
 2007  
       }
 2008  
    }
 2009  
 
 2010  0
    /**
 2011  0
     * Get the optional int value associated with an index. Zero is returned if
 2012  0
     * there is no value for the index, or if the value is not a number and
 2013  
     * cannot be converted to a number.
 2014  0
     *
 2015  
     * @param index The index must be between 0 and size() - 1.
 2016  
     * @return The value.
 2017  
     */
 2018  0
    public int optInt( int index ) {
 2019  
       return optInt( index, 0 );
 2020  0
    }
 2021  0
 
 2022  0
    /**
 2023  0
     * Get the optional int value associated with an index. The defaultValue is
 2024  0
     * returned if there is no value for the index, or if the value is not a
 2025  
     * number and cannot be converted to a number.
 2026  
     *
 2027  
     * @param index The index must be between 0 and size() - 1.
 2028  0
     * @param defaultValue The default value.
 2029  
     * @return The value.
 2030  
     */
 2031  
    public int optInt( int index, int defaultValue ) {
 2032  0
       try{
 2033  
          return getInt( index );
 2034  
       }catch( Exception e ){
 2035  
          return defaultValue;
 2036  0
       }
 2037  
    }
 2038  
 
 2039  
    /**
 2040  0
     * Get the optional JSONArray associated with an index.
 2041  
     *
 2042  
     * @param index subscript
 2043  
     * @return A JSONArray value, or null if the index has no value, or if the
 2044  
     *         value is not a JSONArray.
 2045  
     */
 2046  
    public JSONArray optJSONArray( int index ) {
 2047  0
       Object o = opt( index );
 2048  
       return o instanceof JSONArray ? (JSONArray) o : null;
 2049  
    }
 2050  
 
 2051  
    /**
 2052  
     * Get the optional JSONObject associated with an index. Null is returned if
 2053  
     * the key is not found, or null if the index has no value, or if the value
 2054  
     * is not a JSONObject.
 2055  
     *
 2056  
     * @param index The index must be between 0 and size() - 1.
 2057  
     * @return A JSONObject value.
 2058  
     */
 2059  
    public JSONObject optJSONObject( int index ) {
 2060  0
       Object o = opt( index );
 2061  
       return o instanceof JSONObject ? (JSONObject) o : null;
 2062  
    }
 2063  
 
 2064  
    /**
 2065  
     * Get the optional long value associated with an index. Zero is returned if
 2066  
     * there is no value for the index, or if the value is not a number and
 2067  
     * cannot be converted to a number.
 2068  
     *
 2069  
     * @param index The index must be between 0 and size() - 1.
 2070  
     * @return The value.
 2071  
     */
 2072  
    public long optLong( int index ) {
 2073  0
       return optLong( index, 0 );
 2074  0
    }
 2075  
 
 2076  0
    /**
 2077  0
     * Get the optional long value associated with an index. The defaultValue is
 2078  0
     * returned if there is no value for the index, or if the value is not a
 2079  
     * number and cannot be converted to a number.
 2080  0
     *
 2081  0
     * @param index The index must be between 0 and size() - 1.
 2082  
     * @param defaultValue The default value.
 2083  0
     * @return The value.
 2084  
     */
 2085  
    public long optLong( int index, long defaultValue ) {
 2086  
       try{
 2087  0
          return getLong( index );
 2088  
       }catch( Exception e ){
 2089  
          return defaultValue;
 2090  
       }
 2091  0
    }
 2092  
 
 2093  
    /**
 2094  
     * Get the optional string value associated with an index. It returns an
 2095  0
     * empty string if there is no value at that index. If the value is not a
 2096  0
     * string and is not null, then it is coverted to a string.
 2097  
     *
 2098  0
     * @param index The index must be between 0 and size() - 1.
 2099  
     * @return A String value.
 2100  
     */
 2101  
    public String optString( int index ) {
 2102  
       return optString( index, "" );
 2103  
    }
 2104  
 
 2105  
    /**
 2106  
     * Get the optional string associated with an index. The defaultValue is
 2107  
     * returned if the key is not found.
 2108  0
     *
 2109  
     * @param index The index must be between 0 and size() - 1.
 2110  
     * @param defaultValue The default value.
 2111  
     * @return A String value.
 2112  
     */
 2113  
    public String optString( int index, String defaultValue ) {
 2114  
       Object o = opt( index );
 2115  
       return o != null ? o.toString() : defaultValue;
 2116  
    }
 2117  
 
 2118  
    public Object remove( int index ) {
 2119  
       return elements.remove( index );
 2120  0
    }
 2121  
 
 2122  
    public boolean remove( Object o ) {
 2123  
       return elements.remove( o );
 2124  
    }
 2125  
 
 2126  
    public boolean removeAll( Collection collection ) {
 2127  
       return removeAll( collection, new JsonConfig() );
 2128  
    }
 2129  
 
 2130  
    public boolean removeAll( Collection collection, JsonConfig jsonConfig ) {
 2131  
       return elements.removeAll( fromObject( collection, jsonConfig ) );
 2132  
    }
 2133  
 
 2134  0
    public boolean retainAll( Collection collection ) {
 2135  0
       return retainAll( collection, new JsonConfig() );
 2136  0
    }
 2137  
 
 2138  
    public boolean retainAll( Collection collection, JsonConfig jsonConfig ) {
 2139  
       return elements.retainAll( fromObject( collection, jsonConfig ) );
 2140  
    }
 2141  
 
 2142  
    public Object set( int index, Object value ) {
 2143  
       return set( index, value, new JsonConfig() );
 2144  
    }
 2145  
 
 2146  
    public Object set( int index, Object value, JsonConfig jsonConfig ) {
 2147  
       Object previous = get( index );
 2148  
       element( index, value, jsonConfig );
 2149  0
       return previous;
 2150  
    }
 2151  
 
 2152  
    public void setExpandElements( boolean expandElements ) {
 2153  
       this.expandElements = expandElements;
 2154  
    }
 2155  
 
 2156  
    /**
 2157  
     * Get the number of elements in the JSONArray, included nulls.
 2158  
     *
 2159  
     * @return The length (or size).
 2160  
     */
 2161  
    public int size() {
 2162  
       return this.elements.size();
 2163  0
    }
 2164  0
 
 2165  0
    public List subList( int fromIndex, int toIndex ) {
 2166  
       return elements.subList( fromIndex, toIndex );
 2167  
    }
 2168  
 
 2169  
    /**
 2170  
     * Produce an Object[] with the contents of this JSONArray.
 2171  
     */
 2172  
    public Object[] toArray() {
 2173  
       return this.elements.toArray();
 2174  
    }
 2175  
 
 2176  
    public Object[] toArray( Object[] array ) {
 2177  
       return elements.toArray( array );
 2178  0
    }
 2179  
 
 2180  
    /**
 2181  
     * Produce a JSONObject by combining a JSONArray of names with the values of
 2182  
     * this JSONArray.
 2183  
     *
 2184  
     * @param names A JSONArray containing a list of key strings. These will be
 2185  
     *        paired with the values.
 2186  
     * @return A JSONObject, or null if there are no names or if this JSONArray
 2187  
     *         has no values.
 2188  
     * @throws JSONException If any of the names are null.
 2189  
     */
 2190  
    public JSONObject toJSONObject( JSONArray names ) {
 2191  
       if( names == null || names.size() == 0 || size() == 0 ){
 2192  0
          return null;
 2193  0
       }
 2194  0
       JSONObject jo = new JSONObject();
 2195  
       for( int i = 0; i < names.size(); i++ ){
 2196  
          jo.element( names.getString( i ), this.opt( i ) );
 2197  
       }
 2198  
       return jo;
 2199  
    }
 2200  
 
 2201  
    /**
 2202  
     * Make a JSON text of this JSONArray. For compactness, no unnecessary
 2203  
     * whitespace is added. If it is not possible to produce a syntactically
 2204  
     * correct JSON text then null will be returned instead. This could occur if
 2205  
     * the array contains an invalid number.
 2206  0
     * <p>
 2207  0
     * Warning: This method assumes that the data structure is acyclical.
 2208  
     *
 2209  
     * @return a printable, displayable, transmittable representation of the
 2210  
     *         array.
 2211  
     */
 2212  
    public String toString() {
 2213  
       try{
 2214  
          return '[' + join( "," ) + ']';
 2215  
       }catch( Exception e ){
 2216  
          return null;
 2217  
       }
 2218  
    }
 2219  0
 
 2220  0
    /**
 2221  
     * Make a prettyprinted JSON text of this JSONArray. Warning: This method
 2222  
     * assumes that the data structure is acyclical.
 2223  
     *
 2224  
     * @param indentFactor The number of spaces to add to each level of
 2225  
     *        indentation.
 2226  
     * @return a printable, displayable, transmittable representation of the
 2227  
     *         object, beginning with <code>[</code>&nbsp;<small>(left
 2228  
     *         bracket)</small> and ending with <code>]</code>&nbsp;<small>(right
 2229  
     *         bracket)</small>.
 2230  
     * @throws JSONException
 2231  
     */
 2232  0
    public String toString( int indentFactor ) {
 2233  
       if( indentFactor == 0 ){
 2234  
          return this.toString();
 2235  
       }
 2236  
       return toString( indentFactor, 0 );
 2237  
    }
 2238  
 
 2239  
    /**
 2240  
     * Make a prettyprinted JSON text of this JSONArray. Warning: This method
 2241  
     * assumes that the data structure is acyclical.
 2242  
     *
 2243  
     * @param indentFactor The number of spaces to add to each level of
 2244  
     *        indentation.
 2245  
     * @param indent The indention of the top level.
 2246  0
     * @return a printable, displayable, transmittable representation of the
 2247  0
     *         array.
 2248  0
     * @throws JSONException
 2249  
     */
 2250  
    public String toString( int indentFactor, int indent ) {
 2251  
       int len = size();
 2252  
       if( len == 0 ){
 2253  
          return "[]";
 2254  
       }
 2255  
       if( indentFactor == 0 ){
 2256  
          return this.toString();
 2257  
       }
 2258  
       int i;
 2259  
       StringBuffer sb = new StringBuffer( "[" );
 2260  
       if( len == 1 ){
 2261  0
          sb.append( JSONUtils.valueToString( this.elements.get( 0 ), indentFactor, indent ) );
 2262  
       }else{
 2263  
          int newindent = indent + indentFactor;
 2264  
          sb.append( '\n' );
 2265  
          for( i = 0; i < len; i += 1 ){
 2266  
             if( i > 0 ){
 2267  
                sb.append( ",\n" );
 2268  
             }
 2269  
             for( int j = 0; j < newindent; j += 1 ){
 2270  
                sb.append( ' ' );
 2271  
             }
 2272  
             sb.append( JSONUtils.valueToString( this.elements.get( i ), indentFactor, newindent ) );
 2273  0
          }
 2274  0
          sb.append( '\n' );
 2275  
          for( i = 0; i < indent; i += 1 ){
 2276  
             sb.append( ' ' );
 2277  
          }
 2278  0
          for( i = 0; i < indent; i += 1 ){
 2279  
             sb.insert( 0, ' ' );
 2280  
          }
 2281  
       }
 2282  0
       sb.append( ']' );
 2283  
       return sb.toString();
 2284  
    }
 2285  
 
 2286  0
    /**
 2287  
     * Write the contents of the JSONArray as JSON text to a writer. For
 2288  
     * compactness, no whitespace is added.
 2289  
     * <p>
 2290  0
     * Warning: This method assumes that the data structure is acyclical.
 2291  
     *
 2292  
     * @return The writer.
 2293  
     * @throws JSONException
 2294  0
     */
 2295  
    public Writer write( Writer writer ) {
 2296  
       try{
 2297  
          boolean b = false;
 2298  0
          int len = size();
 2299  
 
 2300  
          writer.write( '[' );
 2301  
 
 2302  0
          for( int i = 0; i < len; i += 1 ){
 2303  
             if( b ){
 2304  
                writer.write( ',' );
 2305  
             }
 2306  0
             Object v = this.elements.get( i );
 2307  0
             if( v instanceof JSONObject ){
 2308  0
                ((JSONObject) v).write( writer );
 2309  
             }else if( v instanceof JSONArray ){
 2310  
                ((JSONArray) v).write( writer );
 2311  
             }else{
 2312  0
                writer.write( JSONUtils.valueToString( v ) );
 2313  0
             }
 2314  
             b = true;
 2315  
          }
 2316  
          writer.write( ']' );
 2317  
          return writer;
 2318  
       }catch( IOException e ){
 2319  
          throw new JSONException( e );
 2320  
       }
 2321  0
    }
 2322  
 
 2323  
    /**
 2324  
     * Adds a String without performing any conversion on it.
 2325  0
     */
 2326  
    protected JSONArray addString( String str ) {
 2327  
       if( str != null ){
 2328  
          elements.add( str );
 2329  
       }
 2330  
       return this;
 2331  
    }
 2332  0
 
 2333  
    /**
 2334  
     * Append an object value. This increases the array's length by one.
 2335  
     *
 2336  0
     * @param value An object value. The value should be a Boolean, Double,
 2337  
     *        Integer, JSONArray, JSONObject, JSONFunction, Long, String,
 2338  
     *        JSONString or the JSONNull object.
 2339  
     * @return this.
 2340  
     */
 2341  
    private JSONArray _addValue( Object value, JsonConfig jsonConfig ) {
 2342  
       this.elements.add(value);
 2343  
       return this;
 2344  
    }
 2345  
 
 2346  
    protected Object _processValue( Object value, JsonConfig jsonConfig ) {
 2347  
       if( value instanceof JSONTokener ) {
 2348  
          return _fromJSONTokener( (JSONTokener) value, jsonConfig );
 2349  
       }
 2350  0
       return super._processValue( value, jsonConfig );
 2351  0
    }
 2352  
 
 2353  0
    /**
 2354  0
     * Append an object value. This increases the array's length by one.
 2355  0
     *
 2356  
     * @param value An object value. The value should be a Boolean, Double,
 2357  0
     *        Integer, JSONArray, JSONObject, JSONFunction, Long, String,
 2358  
     *        JSONString or the JSONNull object.
 2359  
     * @return this.
 2360  
     */
 2361  
    private JSONArray addValue( Object value, JsonConfig jsonConfig ) {
 2362  
       return _addValue( processValue( value, jsonConfig ), jsonConfig );
 2363  
    }
 2364  
 
 2365  
    private Object processValue( Object value, JsonConfig jsonConfig ) {
 2366  
       if( value != null ){
 2367  
          JsonValueProcessor jsonValueProcessor = jsonConfig.findJsonValueProcessor( value.getClass() );
 2368  
          if( jsonValueProcessor != null ){
 2369  
             value = jsonValueProcessor.processArrayValue( value, jsonConfig );
 2370  
             if( !JsonVerifier.isValidJsonValue( value ) ){
 2371  
                throw new JSONException( "Value is not a valid JSON value. " + value );
 2372  
             }
 2373  0
          }
 2374  0
       }
 2375  0
       return _processValue( value, jsonConfig );
 2376  
    }
 2377  
    
 2378  
    private class JSONArrayListIterator implements ListIterator {
 2379  
       int currentIndex = 0;
 2380  
       int lastIndex = -1;
 2381  
       
 2382  
       JSONArrayListIterator() {
 2383  
          
 2384  
       }
 2385  
       
 2386  
       JSONArrayListIterator( int index ) {
 2387  
          currentIndex = index;
 2388  
       }
 2389  
 
 2390  
       public boolean hasNext() {
 2391  
          return currentIndex != size();
 2392  0
       }
 2393  0
 
 2394  
       public Object next() {
 2395  0
          try {
 2396  
             Object next = get( currentIndex );
 2397  
             lastIndex = currentIndex++;
 2398  
             return next;
 2399  
          } catch( IndexOutOfBoundsException e ) {
 2400  
             throw new NoSuchElementException();
 2401  
          }
 2402  
       }
 2403  
 
 2404  
       public void remove() {
 2405  
          if( lastIndex == -1 )
 2406  
             throw new IllegalStateException();
 2407  
          try {
 2408  
             JSONArray.this.remove( lastIndex );
 2409  
             if( lastIndex < currentIndex ){
 2410  0
                currentIndex--;
 2411  0
             }
 2412  0
             lastIndex = -1;
 2413  
          } catch( IndexOutOfBoundsException e ) {
 2414  0
             throw new ConcurrentModificationException();
 2415  0
          }
 2416  
       }
 2417  
 
 2418  0
       public boolean hasPrevious() {
 2419  0
          return currentIndex != 0;
 2420  0
       }
 2421  
 
 2422  0
       public Object previous() {
 2423  0
          try {
 2424  0
             int index = currentIndex - 1;
 2425  0
             Object previous = get( index );
 2426  0
             lastIndex = currentIndex = index;
 2427  
             return previous;
 2428  0
          } catch( IndexOutOfBoundsException e ) {
 2429  0
             throw new NoSuchElementException();
 2430  
          }
 2431  0
       }
 2432  
 
 2433  0
       public int nextIndex() {
 2434  0
          return currentIndex;
 2435  0
       }
 2436  
 
 2437  0
       public int previousIndex() {
 2438  0
          return currentIndex - 1;
 2439  
       }
 2440  
 
 2441  0
       public void set( Object obj ) {
 2442  0
          if( lastIndex == -1 ){
 2443  
             throw new IllegalStateException();
 2444  
          }
 2445  
 
 2446  
          try {
 2447  
             JSONArray.this.set( lastIndex, obj );
 2448  
          } catch( IndexOutOfBoundsException ex ) {
 2449  
             throw new ConcurrentModificationException();
 2450  
          }
 2451  
       }
 2452  
 
 2453  
       public void add( Object obj ) {
 2454  
          try {
 2455  
             JSONArray.this.add( currentIndex++, obj );
 2456  0
             lastIndex = -1;
 2457  0
          } catch( IndexOutOfBoundsException ex ) {
 2458  
             throw new ConcurrentModificationException();
 2459  0
          }
 2460  
       }
 2461  0
    }
 2462  0
 }