/**
   * We convert script values to the nearest Java value. We unwrap wrapped Java objects so that
   * access from Bindings.get() would return "workable" value for Java. But, at the same time, we
   * need to make few special cases and hence the following function is used.
   */
  private Object jsToJava(Object jsObj) {
    if (jsObj instanceof Wrapper) {
      Wrapper njb = (Wrapper) jsObj;
      /* importClass feature of ImporterTopLevel puts
       * NativeJavaClass in global scope. If we unwrap
       * it, importClass won't work.
       */
      if (njb instanceof NativeJavaClass) {
        return njb;
      }

      /* script may use Java primitive wrapper type objects
       * (such as java.lang.Integer, java.lang.Boolean etc)
       * explicitly. If we unwrap, then these script objects
       * will become script primitive types. For example,
       *
       *    var x = new java.lang.Double(3.0); print(typeof x);
       *
       * will print 'number'. We don't want that to happen.
       */
      Object obj = njb.unwrap();
      if (obj instanceof Number
          || obj instanceof String
          || obj instanceof Boolean
          || obj instanceof Character) {
        // special type wrapped -- we just leave it as is.
        return njb;
      } else {
        // return unwrapped object for any other object.
        return obj;
      }
    } else { // not-a-Java-wrapper
      return jsObj;
    }
  }
  @SuppressWarnings("nls")
  private static Date parseDate(String dateString) {
    if (dateString == null) return null;
    if (!dateString.toLowerCase().startsWith("new date(")) return null;

    String value = dateString.substring(9, dateString.lastIndexOf(')'));

    if (value.trim().length() == 0) return new Date();

    Object[] args = null;
    if (value.startsWith("\"") || value.startsWith("'")) {
      args = new Object[] {value.substring(1, value.length() - 1)};
    } else {
      ArrayList<String> al = new ArrayList<String>();
      StringTokenizer st = new StringTokenizer(value, ",");
      while (st.hasMoreTokens()) {
        al.add(st.nextToken());
      }
      args = al.toArray();
    }
    Wrapper wrapper = (Wrapper) NativeDate.jsConstructor(args);
    return (Date) wrapper.unwrap();
  }