/**
   * Used by the parser to create a new array with elements of the given class and store it in the
   * master objects table under the given ID.
   *
   * @param objID A unique ID used to index objects in the master object table.
   * @param cls The class to instantiate.
   * @param size The number of elements in the array.
   * @param depth The number of levels of indirection.
   * @return The newly instantiated array.
   */
  public Object newArrayInstance(Long objID, Class cls, int size, int depth) throws ParseException {
    if (pMasterTable.containsKey(objID))
      throw new ParseException("Duplicate object ID (" + objID + " encountered!");

    Object obj = null;
    try {
      if (depth == 1) {
        obj = Array.newInstance(cls, size);
      } else if (depth > 1) {
        StringBuilder buf = new StringBuilder();

        int wk;
        for (wk = 1; wk < depth; wk++) buf.append("[");

        if (cls.isPrimitive()) {
          if (cls == Boolean.TYPE) buf.append("Z");
          else if (cls == Byte.TYPE) buf.append("B");
          else if (cls == Short.TYPE) buf.append("S");
          else if (cls == Integer.TYPE) buf.append("I");
          else if (cls == Long.TYPE) buf.append("J");
          else if (cls == Float.TYPE) buf.append("F");
          else if (cls == Double.TYPE) buf.append("D");
          else if (cls == Character.TYPE) buf.append("C");
          else throw new IllegalStateException("Unknown array type (" + cls + ")!");
        } else {
          buf.append("L" + cls.getName() + ";");
        }

        Class acls = Class.forName(buf.toString());
        obj = Array.newInstance(acls, size);
      } else {
        throw new NegativeArraySizeException("Array depth (" + depth + ") must be positive!");
      }
    } catch (Exception ex) {
      throw new ParseException(ex.toString());
    }

    pMasterTable.put(objID, obj);

    return obj;
  }