public static Boolean enumNext(Object enumObj)
    {
        IdEnumeration x = (IdEnumeration)enumObj;
        if (x.iterator != null) {
            Object v = ScriptableObject.getProperty(x.iterator, "next");
            if (!(v instanceof Callable))
                return Boolean.FALSE;
            Callable f = (Callable) v;
            Context cx = Context.enter();
            try {
                x.currentId = f.call(cx, x.iterator.getParentScope(), 
                                     x.iterator, emptyArgs);
                return Boolean.TRUE;
            } catch (JavaScriptException e) {
                if (e.getValue() instanceof NativeIterator.StopIteration) {
                  return Boolean.FALSE;
                }
                throw e;
            } finally {
                Context.exit();
            }
        }
        for (;;) {
            if (x.obj == null) {
                return Boolean.FALSE;
            }
            if (x.index == x.ids.length) {
                x.obj = x.obj.getPrototype();
                enumChangeObject(x);
                continue;
            }
            Object id = x.ids[x.index++];
            if (x.used != null && x.used.has(id)) {
                continue;
            }
            if (id instanceof String) {
                String strId = (String)id;
                if (!x.obj.has(strId, x.obj))
                    continue;   // must have been deleted
                x.currentId = strId;
            } else {
                int intId = ((Number)id).intValue();
                if (!x.obj.has(intId, x.obj))
                    continue;   // must have been deleted
                x.currentId = x.enumNumbers ? (Object) (new Integer(intId))
                                            : String.valueOf(intId);
            }
            return Boolean.TRUE;
        }
    }