Implement opext:keys-or-members method
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml b/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml
index f323e47..bb710a9 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml
+++ b/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml
@@ -655,11 +655,11 @@
         <runtime type="scalar" class="org.apache.vxquery.runtime.functions.json.ValueScalarEvaluatorFactory"/>
     </operator>
 
-    <!-- jdm:keys($o as object()) as xs:string* -->
-    <operator name="jdm:keys">
+    <!-- opext:keys-or-members($o as json-item()) as xs:string* -->
+    <operator name="opext:keys-or-members">
         <param name="expr" type="json-item()"/>
         <return type="xs:string*"/>
-        <runtime type="scalar" class="org.apache.vxquery.runtime.functions.json.KeysScalarEvaluatorFactory"/>
+        <runtime type="scalar" class="org.apache.vxquery.runtime.functions.json.KeysOrMembersScalarEvaluatorFactory"/>
     </operator>
 
     <!-- opext:subtract($arg1 as xs:anyAtomicType?, $arg2 as xs:anyAtomicType?) as xs:anyAtomicType? -->
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysOrMembersScalarEvaluator.java
similarity index 77%
rename from vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysScalarEvaluator.java
rename to vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysOrMembersScalarEvaluator.java
index ad58cb3..1b90282 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysScalarEvaluator.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysOrMembersScalarEvaluator.java
@@ -28,11 +28,11 @@
 
 import java.io.IOException;
 
-public class KeysScalarEvaluator extends AbstractTaggedValueArgumentScalarEvaluator {
+public class KeysOrMembersScalarEvaluator extends AbstractTaggedValueArgumentScalarEvaluator {
     protected final IHyracksTaskContext ctx;
     private final ObjectPointable op;
 
-    public KeysScalarEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) {
+    public KeysOrMembersScalarEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) {
         super(args);
         this.ctx = ctx;
         op = (ObjectPointable) ObjectPointable.FACTORY.createPointable();
@@ -41,15 +41,17 @@
     @Override
     protected void evaluate(TaggedValuePointable[] args, IPointable result) throws SystemException {
         TaggedValuePointable tvp1 = args[0];
-        if (!(tvp1.getTag() == ValueTag.OBJECT_TAG)) {
+        if (!((tvp1.getTag() == ValueTag.OBJECT_TAG) || (tvp1.getTag() == ValueTag.ARRAY_TAG))) {
             throw new SystemException(ErrorCode.FORG0006);
         }
-        try {
-            tvp1.getValue(op);
-            op.getKeys(result);
-        } catch (IOException e) {
-            throw new SystemException(ErrorCode.SYSE0001, e);
+        if (tvp1.getTag() == ValueTag.OBJECT_TAG) {
+            try {
+                tvp1.getValue(op);
+                op.getKeys(result);
+            } catch (IOException e) {
+                throw new SystemException(ErrorCode.SYSE0001, e);
 
+            }
         }
     }
 
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysScalarEvaluatorFactory.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysOrMembersScalarEvaluatorFactory.java
similarity index 85%
rename from vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysScalarEvaluatorFactory.java
rename to vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysOrMembersScalarEvaluatorFactory.java
index 30bf850..d664318 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysScalarEvaluatorFactory.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/KeysOrMembersScalarEvaluatorFactory.java
@@ -22,18 +22,18 @@
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.vxquery.runtime.functions.base.AbstractTaggedValueArgumentScalarEvaluatorFactory;
 
-public class KeysScalarEvaluatorFactory extends AbstractTaggedValueArgumentScalarEvaluatorFactory {
+public class KeysOrMembersScalarEvaluatorFactory extends AbstractTaggedValueArgumentScalarEvaluatorFactory {
 
     private static final long serialVersionUID = 1L;
 
-    public KeysScalarEvaluatorFactory(IScalarEvaluatorFactory[] args) {
+    public KeysOrMembersScalarEvaluatorFactory(IScalarEvaluatorFactory[] args) {
         super(args);
     }
 
     @Override
     protected IScalarEvaluator createEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args)
             throws AlgebricksException {
-        return new KeysScalarEvaluator(ctx, args);
+        return new KeysOrMembersScalarEvaluator(ctx, args);
     }
 
 }
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java
index 8e18651..a635951 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java
+++ b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java
@@ -1561,7 +1561,7 @@
                                     }
                                 }
                                 if (arguments.size() == 0) {
-                                    ctxExpr = sfce(BuiltinOperators.KEYS, expr);
+                                    ctxExpr = sfce(BuiltinOperators.KEYS_OR_MEMBERS, expr);
                                 }
                             } else {
                                 predicates = postfixNode.getArgs();