This check-in is a clean up of the asterix code.
It gets rid of redundant classes (FunIdentifier, FunctionUtil etc) and also corrects comparisons made using == instead of a .equals. 


git-svn-id: https://asterixdb.googlecode.com/svn/trunk/asterix@39 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixInlineVariablesRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixInlineVariablesRule.java
index 5bac6ce..08e31ba 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixInlineVariablesRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/AsterixInlineVariablesRule.java
@@ -185,8 +185,8 @@
                     ILogicalExpression expr = exprRef.getValue();
                     if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
                         ScalarFunctionCallExpression funExpr = (ScalarFunctionCallExpression) expr;
-                        if (funExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR
-                                || funExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR) {
+                        if (funExpr.getFunctionIdentifier().equals(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR)
+                                || funExpr.getFunctionIdentifier().equals(AsterixBuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR)) {
                             assignRecord = true;
                             break;
                         }
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ByNameToByHandleFieldAccessRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ByNameToByHandleFieldAccessRule.java
index 8d8ce31..7331aaa 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ByNameToByHandleFieldAccessRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ByNameToByHandleFieldAccessRule.java
@@ -7,7 +7,7 @@
 import org.apache.commons.lang3.mutable.MutableObject;
 
 import edu.uci.ics.asterix.algebra.base.AsterixOperatorAnnotations;
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
index 43c94b0..6833caf 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ByNameToByIndexFieldAccessRule.java
@@ -6,7 +6,7 @@
 import org.apache.commons.lang3.mutable.MutableObject;
 
 import edu.uci.ics.asterix.algebra.base.AsterixOperatorAnnotations;
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.om.base.AInt32;
 import edu.uci.ics.asterix.om.base.AString;
 import edu.uci.ics.asterix.om.base.IAObject;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java
index b72a3a1..cf4747b 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java
@@ -146,7 +146,7 @@
             if (!checkArgs(expr)) {
                 return new Pair<Boolean, ILogicalExpression>(changed, expr);
             }
-            if (expr.getFunctionIdentifier() == AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME) {
+            if (expr.getFunctionIdentifier().equals(AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME)) {
                 ARecordType rt = (ARecordType) _emptyTypeEnv.getType(expr.getArguments().get(0).getValue());
                 String str = ((AString) ((AsterixConstantValue) ((ConstantExpression) expr.getArguments().get(1)
                         .getValue()).getValue()).getObject()).getStringValue();
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FeedScanCollectionToUnnest.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FeedScanCollectionToUnnest.java
index 58d4b7b..b4d9d54 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FeedScanCollectionToUnnest.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FeedScanCollectionToUnnest.java
@@ -4,15 +4,15 @@
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
 import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FuzzyEqRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FuzzyEqRule.java
index 22bd58e..60ea0ea 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FuzzyEqRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FuzzyEqRule.java
@@ -6,8 +6,8 @@
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledMetadataDeclarations;
 import edu.uci.ics.asterix.metadata.declared.AqlMetadataProvider;
 import edu.uci.ics.asterix.om.base.AFloat;
@@ -79,7 +79,7 @@
         AbstractFunctionCallExpression funcExp = (AbstractFunctionCallExpression) exp;
         FunctionIdentifier fi = funcExp.getFunctionIdentifier();
 
-        if (fi == AsterixBuiltinFunctions.FUZZY_EQ) {
+        if (fi.equals(AsterixBuiltinFunctions.FUZZY_EQ)) {
             List<Mutable<ILogicalExpression>> inputExps = funcExp.getArguments();
 
             ArrayList<Mutable<ILogicalExpression>> similarityArgs = new ArrayList<Mutable<ILogicalExpression>>();
@@ -164,7 +164,7 @@
 
             return true;
 
-        } else if (fi == AlgebricksBuiltinFunctions.AND || fi == AlgebricksBuiltinFunctions.OR) {
+        } else if (fi.equals(AlgebricksBuiltinFunctions.AND) || fi.equals(AlgebricksBuiltinFunctions.OR)) {
             for (int i = 0; i < 2; i++) {
                 if (expandFuzzyEq(funcExp.getArguments().get(i), context, env, aqlMetadata)) {
                     expanded = true;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FuzzyJoinRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FuzzyJoinRule.java
index 5f8f7ff..8a746eb 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FuzzyJoinRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/FuzzyJoinRule.java
@@ -350,10 +350,10 @@
         ILogicalExpression exp = expRef.getValue();
         if (exp.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
             AbstractFunctionCallExpression funcExp = (AbstractFunctionCallExpression) exp;
-            if (funcExp.getFunctionIdentifier() == AsterixBuiltinFunctions.FUZZY_EQ) {
+            if (funcExp.getFunctionIdentifier().equals(AsterixBuiltinFunctions.FUZZY_EQ)) {
                 return expRef;
-            } else if (funcExp.getFunctionIdentifier() == AlgebricksBuiltinFunctions.AND
-                    || funcExp.getFunctionIdentifier() == AlgebricksBuiltinFunctions.OR) {
+            } else if (funcExp.getFunctionIdentifier().equals(AlgebricksBuiltinFunctions.AND)
+                    || funcExp.getFunctionIdentifier().equals(AlgebricksBuiltinFunctions.OR)) {
                 for (int i = 0; i < 2; i++) {
                     Mutable<ILogicalExpression> expRefRet = getSimilarityExpression(funcExp.getArguments().get(i));
                     if (expRefRet != null) {
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IfElseToSwitchCaseFunctionRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IfElseToSwitchCaseFunctionRule.java
index 1420acd..677cb6c 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IfElseToSwitchCaseFunctionRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IfElseToSwitchCaseFunctionRule.java
@@ -6,7 +6,7 @@
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceBTreeIndexSearchRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceBTreeIndexSearchRule.java
index 790bac7..48abbec 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceBTreeIndexSearchRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceBTreeIndexSearchRule.java
@@ -7,9 +7,9 @@
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
 import edu.uci.ics.asterix.common.functions.FunctionArgumentsConstants;
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledDatasetDecl;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledIndexDecl;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledMetadataDeclarations;
@@ -37,17 +37,17 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions.ComparisonKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions.ComparisonKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
 import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -178,14 +178,14 @@
                 FunctionIdentifier fi = fce.getFunctionIdentifier();
 
                 int fieldIndex = -1;
-                if (fi == AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME) {
+                if (fi.equals(AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME)) {
                     ILogicalExpression nameArg = fce.getArguments().get(1).getValue();
                     if (nameArg.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
                         return false;
                     }
                     ConstantExpression cNameExpr = (ConstantExpression) nameArg;
                     fieldName = ((AString) ((AsterixConstantValue) cNameExpr.getValue()).getObject()).getStringValue();
-                } else if (fi == AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX) {
+                } else if (fi.equals(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX)) {
                     ILogicalExpression idxArg = fce.getArguments().get(1).getValue();
                     if (idxArg.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
                         return false;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceRTreeIndexSearchRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceRTreeIndexSearchRule.java
index cb9f494..7618649 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceRTreeIndexSearchRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceRTreeIndexSearchRule.java
@@ -7,9 +7,9 @@
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
 import edu.uci.ics.asterix.common.functions.FunctionArgumentsConstants;
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledDatasetDecl;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledIndexDecl;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledMetadataDeclarations;
@@ -41,13 +41,13 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
 import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -82,7 +82,7 @@
         if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
             AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr;
             FunctionIdentifier fi = fce.getFunctionIdentifier();
-            if (!AsterixBuiltinFunctions.isSpatialFilterFunction(fi) && fi != AlgebricksBuiltinFunctions.AND) {
+            if (!AsterixBuiltinFunctions.isSpatialFilterFunction(fi) && !fi.equals(AlgebricksBuiltinFunctions.AND)) {
                 return false;
             }
         } else {
@@ -154,14 +154,14 @@
 
             int fieldIndex = -1;
 
-            if (fi == AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME) {
+            if (fi.equals(AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME)) {
                 ILogicalExpression nameArg = fce.getArguments().get(1).getValue();
                 if (nameArg.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
                     return false;
                 }
                 ConstantExpression cNameExpr = (ConstantExpression) nameArg;
                 fieldName = ((AString) ((AsterixConstantValue) cNameExpr.getValue()).getObject()).getStringValue();
-            } else if (fi == AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX) {
+            } else if (fi.equals(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX)) {
                 ILogicalExpression idxArg = fce.getArguments().get(1).getValue();
                 if (idxArg.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
                     return false;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
index ceaebcf..4873ed9 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
@@ -6,15 +6,15 @@
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledDatasetDecl;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledIndexDecl;
-import edu.uci.ics.asterix.metadata.declared.AqlCompiledIndexDecl.IndexKind;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledMetadataDeclarations;
 import edu.uci.ics.asterix.metadata.declared.AqlDataSource;
 import edu.uci.ics.asterix.metadata.declared.AqlIndex;
 import edu.uci.ics.asterix.metadata.declared.AqlMetadataProvider;
+import edu.uci.ics.asterix.metadata.declared.AqlCompiledIndexDecl.IndexKind;
 import edu.uci.ics.asterix.metadata.utils.DatasetUtils;
 import edu.uci.ics.asterix.om.base.AInt32;
 import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/LoadRecordFieldsRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/LoadRecordFieldsRule.java
index bb99d93..58f6cba 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/LoadRecordFieldsRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/LoadRecordFieldsRule.java
@@ -111,7 +111,7 @@
                     boolean b2 = pushFieldLoads(f.getArguments().get(1), topOp, context);
                     return b1 || b2;
                 }
-                if (fi == AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME) {
+                if (fi.equals(AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME)) {
                     if (AnalysisUtil.numberOfVarsInExpr(f) == 0) {
                         return false;
                     }
@@ -247,7 +247,7 @@
             return false;
         }
         ConstantExpression ce = (ConstantExpression) arg1;
-        if (f.getFunctionIdentifier() == AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME) {
+        if (f.getFunctionIdentifier().equals(AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME)) {
             String fldName = ((AString) ((AsterixConstantValue) ce.getValue()).getObject()).getStringValue();
             ILogicalExpression fldExpr = findFieldExpression(assign, recordVar, fldName);
             if (fldExpr != null) {
@@ -256,7 +256,7 @@
             } else {
                 return false;
             }
-        } else if (f.getFunctionIdentifier() == AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX) {
+        } else if (f.getFunctionIdentifier().equals(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX)) {
             // int fldIdx = ((IntegerLiteral) ce.getValue()).getValue();
             // TODO
             return false;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/PullPositionalVariableFromUnnestRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/PullPositionalVariableFromUnnestRule.java
index 787c063..563088e 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/PullPositionalVariableFromUnnestRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/PullPositionalVariableFromUnnestRule.java
@@ -5,7 +5,7 @@
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/RemoveRedundantListifyRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/RemoveRedundantListifyRule.java
index a2a21f3..716d5d0 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/RemoveRedundantListifyRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/RemoveRedundantListifyRule.java
@@ -7,7 +7,7 @@
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetAsterixPhysicalOperatorsRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetAsterixPhysicalOperatorsRule.java
index d187857..8a7132d 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetAsterixPhysicalOperatorsRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetAsterixPhysicalOperatorsRule.java
@@ -144,7 +144,7 @@
                     if (unnestExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
                         AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) unnestExpr;
                         FunctionIdentifier fid = f.getFunctionIdentifier();
-                        if (fid == AsterixBuiltinFunctions.INDEX_SEARCH) {
+                        if (fid.equals(AsterixBuiltinFunctions.INDEX_SEARCH)) {
                             notSet = false;
                             AqlMetadataProvider mp = (AqlMetadataProvider) context.getMetadataProvider();
                             ConstantExpression ce0 = (ConstantExpression) f.getArguments().get(0).getValue();
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetClosedRecordConstructorsRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetClosedRecordConstructorsRule.java
index 40d0506..33377e1 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetClosedRecordConstructorsRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/SetClosedRecordConstructorsRule.java
@@ -2,8 +2,8 @@
 
 import org.apache.commons.lang3.mutable.Mutable;
 
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.common.config.GlobalConfig;
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.asterix.om.types.AOrderedListType;
 import edu.uci.ics.asterix.om.types.ARecordType;
@@ -89,7 +89,7 @@
                 throws AlgebricksException {
             boolean allClosed = true;
             boolean changed = false;
-            if (expr.getFunctionIdentifier() == AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR) {
+            if (expr.getFunctionIdentifier().equals(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR)) {
                 int n = expr.getArguments().size();
                 if (n % 2 > 0) {
                     throw new AlgebricksException("Record constructor expected to have an even number of arguments: "
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/UnnestToDataScanRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/UnnestToDataScanRule.java
index 8b12d14..ec8fb88 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/UnnestToDataScanRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/UnnestToDataScanRule.java
@@ -57,7 +57,7 @@
             AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) unnestExpr;
             FunctionIdentifier fid = f.getFunctionIdentifier();
 
-            if (fid == AsterixBuiltinFunctions.DATASET) {
+            if (fid.equals(AsterixBuiltinFunctions.DATASET)) {
                 if (unnest.getPositionalVariable() != null) {
                     throw new AlgebricksException("No positional variables are allowed over datasets.");
                 }
@@ -106,7 +106,7 @@
                 return true;
             }
             
-            if (fid == AsterixBuiltinFunctions.FEED_INGEST) {
+            if (fid.equals(AsterixBuiltinFunctions.FEED_INGEST)) {
                 if (unnest.getPositionalVariable() != null) {
                     throw new AlgebricksException("No positional variables are allowed over datasets.");
                 }
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
index c3a8494..d601fc4 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
@@ -11,8 +11,8 @@
 
 import edu.uci.ics.asterix.aql.base.Clause;
 import edu.uci.ics.asterix.aql.base.Expression;
-import edu.uci.ics.asterix.aql.base.Expression.Kind;
 import edu.uci.ics.asterix.aql.base.Statement;
+import edu.uci.ics.asterix.aql.base.Expression.Kind;
 import edu.uci.ics.asterix.aql.expression.BeginFeedStatement;
 import edu.uci.ics.asterix.aql.expression.CallExpr;
 import edu.uci.ics.asterix.aql.expression.ControlFeedStatement;
@@ -30,7 +30,6 @@
 import edu.uci.ics.asterix.aql.expression.FieldAccessor;
 import edu.uci.ics.asterix.aql.expression.FieldBinding;
 import edu.uci.ics.asterix.aql.expression.ForClause;
-import edu.uci.ics.asterix.aql.expression.FunIdentifier;
 import edu.uci.ics.asterix.aql.expression.FunctionDecl;
 import edu.uci.ics.asterix.aql.expression.FunctionDropStatement;
 import edu.uci.ics.asterix.aql.expression.GbyVariableExpressionPair;
@@ -42,7 +41,6 @@
 import edu.uci.ics.asterix.aql.expression.LetClause;
 import edu.uci.ics.asterix.aql.expression.LimitClause;
 import edu.uci.ics.asterix.aql.expression.ListConstructor;
-import edu.uci.ics.asterix.aql.expression.ListConstructor.Type;
 import edu.uci.ics.asterix.aql.expression.LiteralExpr;
 import edu.uci.ics.asterix.aql.expression.LoadFromFileStatement;
 import edu.uci.ics.asterix.aql.expression.NodeGroupDropStatement;
@@ -50,10 +48,8 @@
 import edu.uci.ics.asterix.aql.expression.OperatorExpr;
 import edu.uci.ics.asterix.aql.expression.OperatorType;
 import edu.uci.ics.asterix.aql.expression.OrderbyClause;
-import edu.uci.ics.asterix.aql.expression.OrderbyClause.OrderModifier;
 import edu.uci.ics.asterix.aql.expression.OrderedListTypeDefinition;
 import edu.uci.ics.asterix.aql.expression.QuantifiedExpression;
-import edu.uci.ics.asterix.aql.expression.QuantifiedExpression.Quantifier;
 import edu.uci.ics.asterix.aql.expression.QuantifiedPair;
 import edu.uci.ics.asterix.aql.expression.Query;
 import edu.uci.ics.asterix.aql.expression.RecordConstructor;
@@ -63,7 +59,6 @@
 import edu.uci.ics.asterix.aql.expression.TypeDropStatement;
 import edu.uci.ics.asterix.aql.expression.TypeReferenceExpression;
 import edu.uci.ics.asterix.aql.expression.UnaryExpr;
-import edu.uci.ics.asterix.aql.expression.UnaryExpr.Sign;
 import edu.uci.ics.asterix.aql.expression.UnionExpr;
 import edu.uci.ics.asterix.aql.expression.UnorderedListTypeDefinition;
 import edu.uci.ics.asterix.aql.expression.UpdateClause;
@@ -72,11 +67,15 @@
 import edu.uci.ics.asterix.aql.expression.WhereClause;
 import edu.uci.ics.asterix.aql.expression.WriteFromQueryResultStatement;
 import edu.uci.ics.asterix.aql.expression.WriteStatement;
+import edu.uci.ics.asterix.aql.expression.ListConstructor.Type;
+import edu.uci.ics.asterix.aql.expression.OrderbyClause.OrderModifier;
+import edu.uci.ics.asterix.aql.expression.QuantifiedExpression.Quantifier;
+import edu.uci.ics.asterix.aql.expression.UnaryExpr.Sign;
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
 import edu.uci.ics.asterix.formats.base.IDataFormat;
 import edu.uci.ics.asterix.metadata.MetadataException;
 import edu.uci.ics.asterix.metadata.MetadataTransactionContext;
@@ -94,6 +93,7 @@
 import edu.uci.ics.asterix.om.base.AString;
 import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.IAType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.Counter;
@@ -105,14 +105,14 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.OperatorAnnotations;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation.BroadcastSide;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation.BroadcastSide;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
@@ -127,7 +127,6 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SinkOperator;
@@ -136,6 +135,7 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteResultOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
 import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -146,17 +146,13 @@
 import edu.uci.ics.hyracks.dataflow.std.file.FileSplit;
 
 /**
- * 
  * Each visit returns a pair of an operator and a variable. The variable
  * corresponds to the new column, if any, added to the tuple flow. E.g., for
  * Unnest, the column is the variable bound to the elements in the list, for
  * Subplan it is null.
- * 
  * The first argument of a visit method is the expression which is translated.
- * 
  * The second argument of a visit method is the tuple source for the current
  * subtree.
- * 
  */
 
 public class AqlExpressionToPlanTranslator extends AbstractAqlTranslator implements
@@ -404,8 +400,8 @@
             Mutable<ILogicalOperator> tupSource) throws AsterixException {
         Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = aqlExprToAlgExpression(fa.getExpr(), tupSource);
         LogicalVariable v = context.newVar();
-        AbstractFunctionCallExpression fldAccess = new ScalarFunctionCallExpression(
-                FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME));
+        AbstractFunctionCallExpression fldAccess = new ScalarFunctionCallExpression(FunctionUtils
+                .getFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME));
         fldAccess.getArguments().add(new MutableObject<ILogicalExpression>(p.first));
         ILogicalExpression faExpr = new ConstantExpression(new AsterixConstantValue(new AString(fa.getIdent()
                 .getValue())));
@@ -424,8 +420,8 @@
         AbstractFunctionCallExpression f;
         int i = ia.getIndex();
         if (i == IndexAccessor.ANY) {
-            f = new ScalarFunctionCallExpression(
-                    FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.ANY_COLLECTION_MEMBER));
+            f = new ScalarFunctionCallExpression(FunctionUtils
+                    .getFunctionInfo(AsterixBuiltinFunctions.ANY_COLLECTION_MEMBER));
             f.getArguments().add(new MutableObject<ILogicalExpression>(p.first));
         } else {
             f = new ScalarFunctionCallExpression(FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.GET_ITEM));
@@ -443,7 +439,7 @@
     public Pair<ILogicalOperator, LogicalVariable> visitCallExpr(CallExpr fcall, Mutable<ILogicalOperator> tupSource)
             throws AsterixException {
         LogicalVariable v = context.newVar();
-        FunIdentifier fid = fcall.getIdent();
+        AsterixFunction fid = fcall.getIdent();
         List<Mutable<ILogicalExpression>> args = new ArrayList<Mutable<ILogicalExpression>>();
         Mutable<ILogicalOperator> topOp = tupSource;
 
@@ -472,13 +468,13 @@
             }
         }
 
-        FunctionIdentifier fi = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS, fid.getValue(), false);
+        FunctionIdentifier fi = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS, fid.getFunctionName(), false);
         FunctionIdentifier builtinAquafi = AlgebricksBuiltinFunctions.getBuiltinFunctionIdentifier(fi);
 
         if (builtinAquafi != null) {
             fi = builtinAquafi;
         } else {
-            fi = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, fid.getValue(), false);
+            fi = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, fid.getFunctionName(), false);
             FunctionIdentifier builtinAsterixFi = AsterixBuiltinFunctions.getBuiltinFunctionIdentifier(fi);
             if (builtinAsterixFi != null) {
                 fi = builtinAsterixFi;
@@ -488,8 +484,8 @@
         if (AsterixBuiltinFunctions.isBuiltinAggregateFunction(fi)) {
             f = AsterixBuiltinFunctions.makeAggregateFunctionExpression(fi, args);
         } else if (AsterixBuiltinFunctions.isBuiltinUnnestingFunction(fi)) {
-            UnnestingFunctionCallExpression ufce = new UnnestingFunctionCallExpression(
-                    FunctionUtils.getFunctionInfo(fi), args);
+            UnnestingFunctionCallExpression ufce = new UnnestingFunctionCallExpression(FunctionUtils
+                    .getFunctionInfo(fi), args);
             ufce.setReturnsUniqueValues(AsterixBuiltinFunctions.returnsUniqueValues(fi));
             f = ufce;
         } else {
@@ -592,9 +588,9 @@
         sel1.getInputs().add(new MutableObject<ILogicalOperator>(pThen.first));
 
         Pair<ILogicalOperator, LogicalVariable> pElse = ifexpr.getElseExpr().accept(this, nestedSource);
-        AbstractFunctionCallExpression notVarCond = new ScalarFunctionCallExpression(
-                FunctionUtils.getFunctionInfo(AlgebricksBuiltinFunctions.NOT), new MutableObject<ILogicalExpression>(
-                        new VariableReferenceExpression(varCond)));
+        AbstractFunctionCallExpression notVarCond = new ScalarFunctionCallExpression(FunctionUtils
+                .getFunctionInfo(AlgebricksBuiltinFunctions.NOT), new MutableObject<ILogicalExpression>(
+                new VariableReferenceExpression(varCond)));
         SelectOperator sel2 = new SelectOperator(new MutableObject<ILogicalExpression>(notVarCond));
         sel2.getInputs().add(new MutableObject<ILogicalOperator>(pElse.first));
 
@@ -607,10 +603,10 @@
         sp.getInputs().add(opCondRef);
 
         LogicalVariable resV = context.newVar();
-        AbstractFunctionCallExpression concatNonNull = new ScalarFunctionCallExpression(
-                FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.CONCAT_NON_NULL),
-                new MutableObject<ILogicalExpression>(new VariableReferenceExpression(pThen.second)),
-                new MutableObject<ILogicalExpression>(new VariableReferenceExpression(pElse.second)));
+        AbstractFunctionCallExpression concatNonNull = new ScalarFunctionCallExpression(FunctionUtils
+                .getFunctionInfo(AsterixBuiltinFunctions.CONCAT_NON_NULL), new MutableObject<ILogicalExpression>(
+                new VariableReferenceExpression(pThen.second)), new MutableObject<ILogicalExpression>(
+                new VariableReferenceExpression(pElse.second)));
         AssignOperator a = new AssignOperator(resV, new MutableObject<ILogicalExpression>(concatNonNull));
         a.getInputs().add(new MutableObject<ILogicalOperator>(sp));
 
@@ -718,8 +714,9 @@
             OrderModifier m = modifIter.next();
             OrderOperator.IOrder comp = (m == OrderModifier.ASC) ? OrderOperator.ASC_ORDER : OrderOperator.DESC_ORDER;
             ord.getOrderExpressions()
-                    .add(new Pair<IOrder, Mutable<ILogicalExpression>>(comp, new MutableObject<ILogicalExpression>(
-                            p.first)));
+                    .add(
+                            new Pair<IOrder, Mutable<ILogicalExpression>>(comp, new MutableObject<ILogicalExpression>(
+                                    p.first)));
             topOp = p.second;
         }
         ord.getInputs().add(topOp);
@@ -773,8 +770,8 @@
         } else { // EVERY
             List<Mutable<ILogicalExpression>> satExprList = new ArrayList<Mutable<ILogicalExpression>>(1);
             satExprList.add(new MutableObject<ILogicalExpression>(eo2.first));
-            s = new SelectOperator(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(
-                    FunctionUtils.getFunctionInfo(AlgebricksBuiltinFunctions.NOT), satExprList)));
+            s = new SelectOperator(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(FunctionUtils
+                    .getFunctionInfo(AlgebricksBuiltinFunctions.NOT), satExprList)));
             s.getInputs().add(eo2.second);
             fAgg = AsterixBuiltinFunctions.makeAggregateFunctionExpression(AsterixBuiltinFunctions.EMPTY_STREAM,
                     new ArrayList<Mutable<ILogicalExpression>>());
@@ -795,8 +792,8 @@
     @Override
     public Pair<ILogicalOperator, LogicalVariable> visitRecordConstructor(RecordConstructor rc,
             Mutable<ILogicalOperator> tupSource) throws AsterixException {
-        AbstractFunctionCallExpression f = new ScalarFunctionCallExpression(
-                FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR));
+        AbstractFunctionCallExpression f = new ScalarFunctionCallExpression(FunctionUtils
+                .getFunctionInfo(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR));
         LogicalVariable v1 = context.newVar();
         AssignOperator a = new AssignOperator(v1, new MutableObject<ILogicalExpression>(f));
         Mutable<ILogicalOperator> topOp = tupSource;
@@ -840,8 +837,8 @@
         if (u.getSign() == Sign.POSITIVE) {
             a = new AssignOperator(v1, new MutableObject<ILogicalExpression>(eo.first));
         } else {
-            AbstractFunctionCallExpression m = new ScalarFunctionCallExpression(
-                    FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.NUMERIC_UNARY_MINUS));
+            AbstractFunctionCallExpression m = new ScalarFunctionCallExpression(FunctionUtils
+                    .getFunctionInfo(AsterixBuiltinFunctions.NUMERIC_UNARY_MINUS));
             m.getArguments().add(new MutableObject<ILogicalExpression>(eo.first));
             a = new AssignOperator(v1, new MutableObject<ILogicalExpression>(m));
         }
@@ -1264,8 +1261,8 @@
     private ILogicalExpression makeUnnestExpression(ILogicalExpression expr) {
         switch (expr.getExpressionTag()) {
             case VARIABLE: {
-                return new UnnestingFunctionCallExpression(
-                        FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.SCAN_COLLECTION),
+                return new UnnestingFunctionCallExpression(FunctionUtils
+                        .getFunctionInfo(AsterixBuiltinFunctions.SCAN_COLLECTION),
                         new MutableObject<ILogicalExpression>(expr));
             }
             case FUNCTION_CALL: {
@@ -1273,8 +1270,8 @@
                 if (fce.getKind() == FunctionKind.UNNEST) {
                     return expr;
                 } else {
-                    return new UnnestingFunctionCallExpression(
-                            FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.SCAN_COLLECTION),
+                    return new UnnestingFunctionCallExpression(FunctionUtils
+                            .getFunctionInfo(AsterixBuiltinFunctions.SCAN_COLLECTION),
                             new MutableObject<ILogicalExpression>(expr));
                 }
             }
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlPlusExpressionToPlanTranslator.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlPlusExpressionToPlanTranslator.java
index 4268d7b..b1b8cb2 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlPlusExpressionToPlanTranslator.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlPlusExpressionToPlanTranslator.java
@@ -29,7 +29,6 @@
 import edu.uci.ics.asterix.aql.expression.FieldAccessor;
 import edu.uci.ics.asterix.aql.expression.FieldBinding;
 import edu.uci.ics.asterix.aql.expression.ForClause;
-import edu.uci.ics.asterix.aql.expression.FunIdentifier;
 import edu.uci.ics.asterix.aql.expression.FunctionDecl;
 import edu.uci.ics.asterix.aql.expression.FunctionDropStatement;
 import edu.uci.ics.asterix.aql.expression.GbyVariableExpressionPair;
@@ -43,7 +42,6 @@
 import edu.uci.ics.asterix.aql.expression.LetClause;
 import edu.uci.ics.asterix.aql.expression.LimitClause;
 import edu.uci.ics.asterix.aql.expression.ListConstructor;
-import edu.uci.ics.asterix.aql.expression.ListConstructor.Type;
 import edu.uci.ics.asterix.aql.expression.LiteralExpr;
 import edu.uci.ics.asterix.aql.expression.LoadFromFileStatement;
 import edu.uci.ics.asterix.aql.expression.MetaVariableClause;
@@ -53,10 +51,8 @@
 import edu.uci.ics.asterix.aql.expression.OperatorExpr;
 import edu.uci.ics.asterix.aql.expression.OperatorType;
 import edu.uci.ics.asterix.aql.expression.OrderbyClause;
-import edu.uci.ics.asterix.aql.expression.OrderbyClause.OrderModifier;
 import edu.uci.ics.asterix.aql.expression.OrderedListTypeDefinition;
 import edu.uci.ics.asterix.aql.expression.QuantifiedExpression;
-import edu.uci.ics.asterix.aql.expression.QuantifiedExpression.Quantifier;
 import edu.uci.ics.asterix.aql.expression.QuantifiedPair;
 import edu.uci.ics.asterix.aql.expression.Query;
 import edu.uci.ics.asterix.aql.expression.RecordConstructor;
@@ -66,7 +62,6 @@
 import edu.uci.ics.asterix.aql.expression.TypeDropStatement;
 import edu.uci.ics.asterix.aql.expression.TypeReferenceExpression;
 import edu.uci.ics.asterix.aql.expression.UnaryExpr;
-import edu.uci.ics.asterix.aql.expression.UnaryExpr.Sign;
 import edu.uci.ics.asterix.aql.expression.UnionExpr;
 import edu.uci.ics.asterix.aql.expression.UnorderedListTypeDefinition;
 import edu.uci.ics.asterix.aql.expression.UpdateClause;
@@ -75,11 +70,15 @@
 import edu.uci.ics.asterix.aql.expression.WhereClause;
 import edu.uci.ics.asterix.aql.expression.WriteFromQueryResultStatement;
 import edu.uci.ics.asterix.aql.expression.WriteStatement;
+import edu.uci.ics.asterix.aql.expression.ListConstructor.Type;
+import edu.uci.ics.asterix.aql.expression.OrderbyClause.OrderModifier;
+import edu.uci.ics.asterix.aql.expression.QuantifiedExpression.Quantifier;
+import edu.uci.ics.asterix.aql.expression.UnaryExpr.Sign;
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlPlusExpressionVisitor;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
 import edu.uci.ics.asterix.formats.base.IDataFormat;
 import edu.uci.ics.asterix.metadata.MetadataTransactionContext;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledDatasetDecl;
@@ -93,6 +92,7 @@
 import edu.uci.ics.asterix.om.base.AString;
 import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.IAType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.Counter;
@@ -104,14 +104,14 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.OperatorAnnotations;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation.BroadcastSide;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation.BroadcastSide;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
@@ -128,13 +128,13 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
 import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.base.IEvaluatorFactory;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -439,7 +439,7 @@
     public Pair<ILogicalOperator, LogicalVariable> visitCallExpr(CallExpr fcall,  Mutable<ILogicalOperator> tupSource)
             throws AsterixException {
         LogicalVariable v = context.newVar();
-        FunIdentifier fid = fcall.getIdent();
+        AsterixFunction fid = fcall.getIdent();
         List<Mutable<ILogicalExpression>> args = new ArrayList<Mutable<ILogicalExpression>>();
         Mutable<ILogicalOperator> topOp = tupSource;
 
@@ -468,13 +468,13 @@
             }
         }
 
-        FunctionIdentifier fi = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS, fid.getValue(), false);
+        FunctionIdentifier fi = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS, fid.getFunctionName(), false);
         FunctionIdentifier builtinAquafi = AlgebricksBuiltinFunctions.getBuiltinFunctionIdentifier(fi);
 
         if (builtinAquafi != null) {
             fi = builtinAquafi;
         } else {
-            fi = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, fid.getValue(), false);
+            fi = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, fid.getFunctionName(), false);
             FunctionIdentifier builtinAsterixFi = AsterixBuiltinFunctions.getBuiltinFunctionIdentifier(fi);
             if (builtinAsterixFi != null) {
                 fi = builtinAsterixFi;
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/DmlTranslator.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/DmlTranslator.java
index 11222c6..9e2150c 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/DmlTranslator.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/DmlTranslator.java
@@ -1,7 +1,5 @@
 package edu.uci.ics.asterix.translator;
 
-import java.io.FileReader;
-import java.io.Reader;
 import java.rmi.RemoteException;
 import java.util.ArrayList;
 import java.util.List;
@@ -14,14 +12,12 @@
 import edu.uci.ics.asterix.aql.expression.BeginFeedStatement;
 import edu.uci.ics.asterix.aql.expression.CallExpr;
 import edu.uci.ics.asterix.aql.expression.ControlFeedStatement;
-import edu.uci.ics.asterix.aql.expression.ControlFeedStatement.OperationType;
 import edu.uci.ics.asterix.aql.expression.CreateIndexStatement;
 import edu.uci.ics.asterix.aql.expression.DeleteStatement;
 import edu.uci.ics.asterix.aql.expression.FLWOGRExpression;
 import edu.uci.ics.asterix.aql.expression.FieldAccessor;
 import edu.uci.ics.asterix.aql.expression.FieldBinding;
 import edu.uci.ics.asterix.aql.expression.ForClause;
-import edu.uci.ics.asterix.aql.expression.FunIdentifier;
 import edu.uci.ics.asterix.aql.expression.Identifier;
 import edu.uci.ics.asterix.aql.expression.InsertStatement;
 import edu.uci.ics.asterix.aql.expression.LiteralExpr;
@@ -31,8 +27,8 @@
 import edu.uci.ics.asterix.aql.expression.VariableExpr;
 import edu.uci.ics.asterix.aql.expression.WhereClause;
 import edu.uci.ics.asterix.aql.expression.WriteFromQueryResultStatement;
+import edu.uci.ics.asterix.aql.expression.ControlFeedStatement.OperationType;
 import edu.uci.ics.asterix.aql.literal.StringLiteral;
-import edu.uci.ics.asterix.aql.parser.AQLParser;
 import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
 import edu.uci.ics.asterix.common.config.DatasetConfig.IndexType;
 import edu.uci.ics.asterix.metadata.IDatasetDetails;
@@ -43,10 +39,10 @@
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledMetadataDeclarations;
 import edu.uci.ics.asterix.metadata.entities.Dataset;
 import edu.uci.ics.asterix.metadata.entities.FeedDatasetDetails;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 import edu.uci.ics.asterix.om.types.ARecordType;
 import edu.uci.ics.asterix.om.types.IAType;
 import edu.uci.ics.asterix.transaction.management.exception.ACIDException;
-import edu.uci.ics.asterix.transaction.management.service.transaction.TransactionManagementConstants.LockManagerConstants.LockMode;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 
 public class DmlTranslator extends AbstractAqlTranslator {
@@ -104,15 +100,15 @@
                 }
                 case INSERT: {
                     InsertStatement is = (InsertStatement) stmt;
-                    CompiledInsertStatement clfrqs = new CompiledInsertStatement(is.getDatasetName().getValue(),
-                            is.getQuery(), is.getVarCounter());
+                    CompiledInsertStatement clfrqs = new CompiledInsertStatement(is.getDatasetName().getValue(), is
+                            .getQuery(), is.getVarCounter());
                     dmlStatements.add(clfrqs);
                     break;
                 }
                 case DELETE: {
                     DeleteStatement ds = (DeleteStatement) stmt;
-                    CompiledDeleteStatement clfrqs = new CompiledDeleteStatement(ds.getVariableExpr(),
-                            ds.getDatasetName(), ds.getCondition(), ds.getDieClause(), ds.getVarCounter(),
+                    CompiledDeleteStatement clfrqs = new CompiledDeleteStatement(ds.getVariableExpr(), ds
+                            .getDatasetName(), ds.getCondition(), ds.getDieClause(), ds.getVarCounter(),
                             compiledDeclarations);
                     dmlStatements.add(clfrqs);
                     break;
@@ -120,8 +116,8 @@
 
                 case BEGIN_FEED: {
                     BeginFeedStatement bfs = (BeginFeedStatement) stmt;
-                    CompiledBeginFeedStatement cbfs = new CompiledBeginFeedStatement(bfs.getDatasetName(),
-                            bfs.getQuery(), bfs.getVarCounter());
+                    CompiledBeginFeedStatement cbfs = new CompiledBeginFeedStatement(bfs.getDatasetName(), bfs
+                            .getQuery(), bfs.getVarCounter());
                     dmlStatements.add(cbfs);
                     Dataset dataset;
                     try {
@@ -142,8 +138,8 @@
 
                 case CONTROL_FEED: {
                     ControlFeedStatement cfs = (ControlFeedStatement) stmt;
-                    CompiledControlFeedStatement clcfs = new CompiledControlFeedStatement(cfs.getOperationType(),
-                            cfs.getDatasetName(), cfs.getAlterAdapterConfParams());
+                    CompiledControlFeedStatement clcfs = new CompiledControlFeedStatement(cfs.getOperationType(), cfs
+                            .getDatasetName(), cfs.getAlterAdapterConfParams());
                     dmlStatements.add(clcfs);
                     break;
 
@@ -412,7 +408,7 @@
             LiteralExpr argumentLiteral = new LiteralExpr(new StringLiteral(datasetName));
             arguments.add(argumentLiteral);
 
-            CallExpr callExpression = new CallExpr(new FunIdentifier("dataset", 1), arguments);
+            CallExpr callExpression = new CallExpr(new AsterixFunction("dataset", 1), arguments);
             List<Clause> clauseList = new ArrayList<Clause>();
             Clause forClause = new ForClause(var, callExpression);
             clauseList.add(forClause);
@@ -454,25 +450,4 @@
 
     }
 
-    public static void main(String args[]) throws Exception {
-        Reader reader = new FileReader(args[0]);
-        AQLParser parser = new AQLParser(reader);
-        Query q = (Query) parser.Statement();
-
-        // Begin a transaction against the metadata.
-        // Lock the metadata in X mode to protect against other DDL and DML.
-        // TODO: Is there a way to know whether we can get away with locking in
-        // S mode?
-        MetadataTransactionContext ctx = MetadataManager.INSTANCE.beginTransaction();
-        MetadataManager.INSTANCE.lock(ctx, LockMode.EXCLUSIVE);
-        try {
-            DmlTranslator dmlt = new DmlTranslator(ctx, q.getPrologDeclList());
-            dmlt.translate();
-            // dmlt.execute();
-            MetadataManager.INSTANCE.commitTransaction(ctx);
-        } catch (Exception e) {
-            MetadataManager.INSTANCE.abortTransaction(ctx);
-            throw e;
-        }
-    }
 }
diff --git a/asterix-algebra/src/main/javacc/AQLPlus.jj b/asterix-algebra/src/main/javacc/AQLPlus.jj
index b61fb00..9a8f783 100644
--- a/asterix-algebra/src/main/javacc/AQLPlus.jj
+++ b/asterix-algebra/src/main/javacc/AQLPlus.jj
@@ -36,6 +36,8 @@
 import edu.uci.ics.asterix.aql.context.RootScopeFactory;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
 
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
+
 public class AQLPlusParser extends ScopeChecker {
 
 /*
@@ -391,7 +393,8 @@
 FunctionDecl FunctionDeclaration() throws ParseException:
 {
   FunctionDecl func = new FunctionDecl();
-  FunIdentifier ident = new FunIdentifier();
+  AsterixFunction ident;
+  String functionName;
   int arity = 0;
   List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
   Expression funcBody;
@@ -403,7 +406,7 @@
     <IDENTIFIER>
 	{
 	  Token t = getToken(0);
-	  ident.setValue(t.toString());
+	  functionName = t.toString();
 	}
     <LEFTPAREN> (<VARIABLE>
     {
@@ -423,7 +426,7 @@
     })*)? <RIGHTPAREN> "{" funcBody = Expression() "}"
 
     {
-      ident.setArity(arity);
+      ident = new AsterixFunction(functionName, arity);
       getCurrentScope().addFunctionDescriptor(ident, false);
       func.setIdent(ident);
       func.setFuncBody(funcBody);
@@ -1053,10 +1056,10 @@
      } ("," tmp = Expression() { argList.add(tmp); arity++; })*)? <RIGHTPAREN>
 
      {
-       FunIdentifier fd = lookupFunctionSignature(funcName.toString(), arity);
+       AsterixFunction fd = lookupFunctionSignature(funcName.toString(), arity);
 	     if(fd == null)
 	     {
-	        fd = new FunIdentifier(funcName.toString(), arity);
+	        fd = new AsterixFunction(funcName.toString(), arity);
 //	     	notFoundFunctionList.add(fd);
 	     }
 //	     	throw new ParseException("can't find function "+ funcName.toString() + "@" + arity);
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java b/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java
index d60823e..13c904e 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/api/common/APIFramework.java
@@ -468,7 +468,7 @@
                 planAndMetadata.getMetadataProvider(), t.getVarCounter());
         if (pc.isOptimize()) {
             compiler.optimize();
-            if (pc.isPrintPhysicalOpsOnly()) {
+            if (true) {
                 StringBuilder buffer = new StringBuilder();
                 PlanPrettyPrinter.printPhysicalOps(planAndMetadata.getPlan(), buffer, 0);
                 out.print(buffer);
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/DdlTranslator.java b/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/DdlTranslator.java
index dd170a1..9565dde 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/DdlTranslator.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/aql/translator/DdlTranslator.java
@@ -21,8 +21,8 @@
 import java.util.List;
 import java.util.Map;
 
-import edu.uci.ics.asterix.api.common.APIFramework.DisplayFormat;
 import edu.uci.ics.asterix.api.common.SessionConfig;
+import edu.uci.ics.asterix.api.common.APIFramework.DisplayFormat;
 import edu.uci.ics.asterix.aql.base.Statement;
 import edu.uci.ics.asterix.aql.base.Statement.Kind;
 import edu.uci.ics.asterix.aql.expression.CreateDataverseStatement;
@@ -43,15 +43,15 @@
 import edu.uci.ics.asterix.aql.expression.OrderedListTypeDefinition;
 import edu.uci.ics.asterix.aql.expression.Query;
 import edu.uci.ics.asterix.aql.expression.RecordTypeDefinition;
-import edu.uci.ics.asterix.aql.expression.RecordTypeDefinition.RecordKind;
 import edu.uci.ics.asterix.aql.expression.TypeDecl;
 import edu.uci.ics.asterix.aql.expression.TypeDropStatement;
 import edu.uci.ics.asterix.aql.expression.TypeExpression;
 import edu.uci.ics.asterix.aql.expression.TypeReferenceExpression;
 import edu.uci.ics.asterix.aql.expression.UnorderedListTypeDefinition;
-import edu.uci.ics.asterix.aql.util.FunctionUtil;
-import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
+import edu.uci.ics.asterix.aql.expression.RecordTypeDefinition.RecordKind;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.common.config.GlobalConfig;
+import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
 import edu.uci.ics.asterix.common.parse.IParseFileSplitsDecl;
@@ -63,7 +63,6 @@
 import edu.uci.ics.asterix.metadata.MetadataTransactionContext;
 import edu.uci.ics.asterix.metadata.declared.AqlCompiledMetadataDeclarations;
 import edu.uci.ics.asterix.metadata.entities.AsterixBuiltinArtifactMap;
-import edu.uci.ics.asterix.metadata.entities.AsterixBuiltinArtifactMap.ARTIFACT_KIND;
 import edu.uci.ics.asterix.metadata.entities.AsterixBuiltinTypeMap;
 import edu.uci.ics.asterix.metadata.entities.Dataset;
 import edu.uci.ics.asterix.metadata.entities.Datatype;
@@ -74,6 +73,7 @@
 import edu.uci.ics.asterix.metadata.entities.Index;
 import edu.uci.ics.asterix.metadata.entities.InternalDatasetDetails;
 import edu.uci.ics.asterix.metadata.entities.NodeGroup;
+import edu.uci.ics.asterix.metadata.entities.AsterixBuiltinArtifactMap.ARTIFACT_KIND;
 import edu.uci.ics.asterix.om.types.AOrderedListType;
 import edu.uci.ics.asterix.om.types.ARecordType;
 import edu.uci.ics.asterix.om.types.ATypeTag;
@@ -416,16 +416,17 @@
 
                 case CREATE_FUNCTION: {
                     CreateFunctionStatement cfs = (CreateFunctionStatement) stmt;
-                    Function function = new Function(compiledDeclarations.getDataverseName(), cfs
-                            .getFunctionIdentifier().getValue(), cfs.getFunctionIdentifier().getArity(),
-                            cfs.getParamList(), cfs.getFunctionBody());
+                    Function function = new Function(compiledDeclarations.getDataverseName(), cfs.getFunctionIdentifier().getFunctionName(),
+                            cfs.getFunctionIdentifier().getArity(), cfs.getParamList(), cfs.getFunctionBody());
+                    
+                    
                     try {
-                        FunctionUtil.getFunctionDecl(function);
+                        FunctionUtils.getFunctionDecl(function);
                     } catch (Exception e) {
                         throw new AsterixException("unable to compile function definition", e);
                     }
                     MetadataManager.INSTANCE.addFunction(mdTxnCtx, new Function(
-                            compiledDeclarations.getDataverseName(), cfs.getFunctionIdentifier().getValue(), cfs
+                            compiledDeclarations.getDataverseName(), cfs.getFunctionIdentifier().getFunctionName(), cfs
                                     .getFunctionIdentifier().getArity(), cfs.getParamList(), cfs.getFunctionBody()));
                     break;
                 }
diff --git a/asterix-app/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java b/asterix-app/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
index 7adafc8..87018c4 100644
--- a/asterix-app/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
+++ b/asterix-app/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
@@ -51,7 +51,7 @@
         Reader query = new BufferedReader(new FileReader(scriptFile));
         AsterixJavaClient asterix = new AsterixJavaClient(hcc, query, print);
         try {
-            asterix.compile(true, false, false, false, false, true, false);
+            asterix.compile(true, false, true, true, false, true, false);
         } catch (AsterixException e) {
             throw new Exception("Compile ERROR for " + scriptFile + ": " + e.getMessage(), e);
         } finally {
diff --git a/asterix-app/src/test/java/edu/uci/ics/asterix/test/runtime/RuntimeTest.java b/asterix-app/src/test/java/edu/uci/ics/asterix/test/runtime/RuntimeTest.java
index 0aa755c..79731b5 100644
--- a/asterix-app/src/test/java/edu/uci/ics/asterix/test/runtime/RuntimeTest.java
+++ b/asterix-app/src/test/java/edu/uci/ics/asterix/test/runtime/RuntimeTest.java
@@ -149,6 +149,7 @@
                 Assume.assumeTrue(TestHelper.isInPrefixList(only, queryFileShort));
             }
             Assume.assumeTrue(!TestHelper.isInPrefixList(ignore, queryFileShort));
+            System.out.println("RUNNING TEST: " + queryFile + " \n");
             LOGGER.severe("RUNNING TEST: " + queryFile + " \n");
             TestsUtils.runScriptAndCompareWithResult(AsterixHyracksIntegrationUtil.getHyracksClientConnection(),
                     queryFile, ERR, expectedFile, actualFile);
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/FunctionExpressionMap.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/FunctionExpressionMap.java
index e082fee..f30ae09 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/FunctionExpressionMap.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/FunctionExpressionMap.java
@@ -2,9 +2,9 @@
 
 import java.util.HashMap;
 
-import edu.uci.ics.asterix.aql.expression.FunIdentifier;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 
-public class FunctionExpressionMap extends HashMap<Integer, FunIdentifier> {
+public class FunctionExpressionMap extends HashMap<Integer, AsterixFunction> {
     /**
      * 
      */
@@ -24,7 +24,7 @@
         this.varargs = varargs;
     }
 
-    public FunIdentifier get(int arity) {
+    public AsterixFunction get(int arity) {
         if (varargs) {
             return super.get(-1);
         } else {
@@ -32,7 +32,7 @@
         }
     }
 
-    public FunIdentifier put(int arity, FunIdentifier fd) {
+    public AsterixFunction put(int arity, AsterixFunction fd) {
         if (varargs) {
             return super.put(-1, fd);
         } else {
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/FunctionSignatures.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/FunctionSignatures.java
index fa3e8fc..1027c42 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/FunctionSignatures.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/FunctionSignatures.java
@@ -3,7 +3,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import edu.uci.ics.asterix.aql.expression.FunIdentifier;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 
 public class FunctionSignatures {
     private final Map<String, FunctionExpressionMap> functionMap;
@@ -12,7 +12,7 @@
         functionMap = new HashMap<String, FunctionExpressionMap>();
     }
 
-    public FunIdentifier get(String name, int arity) {
+    public AsterixFunction get(String name, int arity) {
         FunctionExpressionMap possibleFD = functionMap.get(name);
         if (possibleFD == null) {
             return null;
@@ -21,8 +21,8 @@
         }
     }
 
-    public void put(FunIdentifier fd, boolean varargs) {
-        String name = fd.getValue();
+    public void put(AsterixFunction fd, boolean varargs) {
+        String name = fd.getFunctionName();
         FunctionExpressionMap func = functionMap.get(name);
         if (func == null) {
             func = new FunctionExpressionMap(varargs);
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/Scope.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/Scope.java
index 3f9c2be..ef338d4 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/Scope.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/Scope.java
@@ -2,10 +2,10 @@
 
 import java.util.HashMap;
 
-import edu.uci.ics.asterix.aql.expression.FunIdentifier;
 import edu.uci.ics.asterix.aql.expression.Identifier;
 import edu.uci.ics.asterix.aql.expression.VarIdentifier;
 import edu.uci.ics.asterix.aql.parser.ScopeChecker;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 
 public final class Scope {
     private Scope parent;
@@ -78,7 +78,7 @@
      * @param varargs
      *            whether this function has varargs
      */
-    public void addFunctionDescriptor(FunIdentifier fd, boolean varargs) {
+    public void addFunctionDescriptor(AsterixFunction fd, boolean varargs) {
         if (functionSignatures == null) {
             functionSignatures = new FunctionSignatures();
         }
@@ -94,8 +94,8 @@
      *            # of arguments
      * @return FunctionDescriptor of the function found; otherwise null
      */
-    public FunIdentifier findFunctionSignature(String name, int arity) {
-        FunIdentifier fd = null;
+    public AsterixFunction findFunctionSignature(String name, int arity) {
+        AsterixFunction fd = null;
         if (functionSignatures != null) {
             fd = functionSignatures.get(name, arity);
         }
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CallExpr.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CallExpr.java
index 39a21e3..cda7e69 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CallExpr.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CallExpr.java
@@ -6,25 +6,26 @@
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlVisitorWithVoidReturn;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 
 public class CallExpr implements Expression {
-    private FunIdentifier ident;
+    private AsterixFunction ident;
     private List<Expression> exprList;
     private boolean isBuiltin;
 
     public CallExpr() {
     }
 
-    public CallExpr(FunIdentifier ident, List<Expression> exprList) {
+    public CallExpr(AsterixFunction ident, List<Expression> exprList) {
         this.ident = ident;
         this.exprList = exprList;
     }
 
-    public FunIdentifier getIdent() {
+    public AsterixFunction getIdent() {
         return ident;
     }
 
-    public void setIdent(FunIdentifier ident) {
+    public void setIdent(AsterixFunction ident) {
         this.ident = ident;
     }
 
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CreateFunctionStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CreateFunctionStatement.java
index e18200f..6ffd39d 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CreateFunctionStatement.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CreateFunctionStatement.java
@@ -3,26 +3,25 @@
 import java.util.ArrayList;
 import java.util.List;
 
-
 import edu.uci.ics.asterix.aql.base.Statement;
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlVisitorWithVoidReturn;
-import edu.uci.ics.asterix.aql.util.FunctionUtil;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 
 public class CreateFunctionStatement implements Statement {
 
-    private FunIdentifier funIdentifier;
+    private AsterixFunction asterixFunction;
     private String functionBody;
     private boolean ifNotExists;
     private List<String> paramList;
 
-    public FunIdentifier getFunctionIdentifier() {
-        return funIdentifier;
+    public AsterixFunction getFunctionIdentifier() {
+        return asterixFunction;
     }
 
-    public void setFunctionIdentifier(FunIdentifier funIdentifier) {
-        this.funIdentifier = funIdentifier;
+    public void setFunctionIdentifier(AsterixFunction AsterixFunction) {
+        this.asterixFunction = AsterixFunction;
     }
 
     public String getFunctionBody() {
@@ -37,10 +36,10 @@
         this.ifNotExists = ifNotExists;
     }
 
-    public CreateFunctionStatement(FunIdentifier funIdentifier, List<VarIdentifier> parameterList, String functionBody,
+    public CreateFunctionStatement(AsterixFunction AsterixFunction, List<VarIdentifier> parameterList, String functionBody,
             boolean ifNotExists) {
         
-        this.funIdentifier = funIdentifier;
+        this.asterixFunction = AsterixFunction;
         this.functionBody = functionBody;
         this.ifNotExists = ifNotExists;
         this.paramList = new ArrayList<String>();
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunIdentifier.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunIdentifier.java
deleted file mode 100644
index 85651fe..0000000
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunIdentifier.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package edu.uci.ics.asterix.aql.expression;
-
-public class FunIdentifier extends Identifier {
-    private int arity;
-
-    public FunIdentifier() {
-    }
-
-    public FunIdentifier(String name, int arity) {
-        this.value = name;
-        this.arity = arity;
-    }
-
-    public int getArity() {
-        return arity;
-    }
-
-    public void setArity(int arity) {
-        this.arity = arity;
-    }
-
-    public boolean equals(Object o) {
-        if (FunIdentifier.class.isInstance(o)) {
-            FunIdentifier obj = (FunIdentifier) o;
-            if (obj.getArity() == arity && obj.getValue().equals(value)) {
-                return true;
-            } else {
-                return false;
-            }
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return value + "@" + arity;
-    }
-
-}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunctionDecl.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunctionDecl.java
index 1428a54..e69035a 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunctionDecl.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunctionDecl.java
@@ -7,26 +7,27 @@
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlVisitorWithVoidReturn;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 
 public class FunctionDecl implements Statement {
-    private FunIdentifier ident;
+    private AsterixFunction ident;
     private List<VarIdentifier> paramList;
     private Expression funcBody;
 
     public FunctionDecl() {
     }
 
-    public FunctionDecl(FunIdentifier ident, List<VarIdentifier> paramList, Expression funcBody) {
+    public FunctionDecl(AsterixFunction ident, List<VarIdentifier> paramList, Expression funcBody) {
         this.ident = ident;
         this.paramList = paramList;
         this.funcBody = funcBody;
     }
 
-    public FunIdentifier getIdent() {
+    public AsterixFunction getIdent() {
         return ident;
     }
 
-    public void setIdent(FunIdentifier ident) {
+    public void setIdent(AsterixFunction ident) {
         this.ident = ident;
     }
 
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/AQLPrintVisitor.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/AQLPrintVisitor.java
index f4b895b..f01991b 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/AQLPrintVisitor.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/AQLPrintVisitor.java
@@ -294,7 +294,7 @@
 
     @Override
     public void visit(FunctionDecl fd, Integer step) throws AsterixException {
-        out.println(skip(step) + "FunctionDecl " + fd.getIdent().getValue() + "(" + fd.getParamList().toString()
+        out.println(skip(step) + "FunctionDecl " + fd.getIdent().getFunctionName() + "(" + fd.getParamList().toString()
                 + ") {");
         fd.getFuncBody().accept(this, step + 1);
         out.println(skip(step) + "}");
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/parser/ScopeChecker.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/parser/ScopeChecker.java
index 51537e3..5171d5a 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/parser/ScopeChecker.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/parser/ScopeChecker.java
@@ -3,8 +3,8 @@
 import java.util.Stack;
 
 import edu.uci.ics.asterix.aql.context.Scope;
-import edu.uci.ics.asterix.aql.expression.FunIdentifier;
 import edu.uci.ics.asterix.aql.expression.Identifier;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.Counter;
 
 public abstract class ScopeChecker {
@@ -95,7 +95,7 @@
      * 
      * @return functionDescriptor
      */
-    public final FunIdentifier lookupFunctionSignature(String name, int arity) {
+    public final AsterixFunction lookupFunctionSignature(String name, int arity) {
         if (name != null) {
             return getCurrentScope().findFunctionSignature(name, arity);
         } else {
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/AqlRewriter.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/AqlRewriter.java
index 5f03cca..fdb56be 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/AqlRewriter.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/AqlRewriter.java
@@ -7,8 +7,8 @@
 
 import edu.uci.ics.asterix.aql.base.Clause;
 import edu.uci.ics.asterix.aql.base.Expression;
-import edu.uci.ics.asterix.aql.base.Expression.Kind;
 import edu.uci.ics.asterix.aql.base.Statement;
+import edu.uci.ics.asterix.aql.base.Expression.Kind;
 import edu.uci.ics.asterix.aql.expression.BeginFeedStatement;
 import edu.uci.ics.asterix.aql.expression.CallExpr;
 import edu.uci.ics.asterix.aql.expression.ControlFeedStatement;
@@ -26,7 +26,6 @@
 import edu.uci.ics.asterix.aql.expression.FieldAccessor;
 import edu.uci.ics.asterix.aql.expression.FieldBinding;
 import edu.uci.ics.asterix.aql.expression.ForClause;
-import edu.uci.ics.asterix.aql.expression.FunIdentifier;
 import edu.uci.ics.asterix.aql.expression.FunctionDecl;
 import edu.uci.ics.asterix.aql.expression.FunctionDropStatement;
 import edu.uci.ics.asterix.aql.expression.GbyVariableExpressionPair;
@@ -65,13 +64,14 @@
 import edu.uci.ics.asterix.aql.expression.WriteFromQueryResultStatement;
 import edu.uci.ics.asterix.aql.expression.WriteStatement;
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
-import edu.uci.ics.asterix.aql.util.FunctionUtil;
+import edu.uci.ics.asterix.aql.util.FunctionUtils;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
 import edu.uci.ics.asterix.metadata.MetadataManager;
 import edu.uci.ics.asterix.metadata.MetadataTransactionContext;
 import edu.uci.ics.asterix.metadata.entities.Function;
 import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 
@@ -130,7 +130,7 @@
             return;
         }
         List<FunctionDecl> fdecls = buildFunctionDeclList(topExpr);
-        List<FunIdentifier> funIds = new ArrayList<FunIdentifier>();
+        List<AsterixFunction> funIds = new ArrayList<AsterixFunction>();
         for (FunctionDecl fdecl : fdecls) {
             funIds.add(fdecl.getIdent());
         }
@@ -148,20 +148,20 @@
     }
 
     private void buildOtherUdfs(Expression expression, List<FunctionDecl> functionDecls,
-            List<FunIdentifier> declaredFunctions) throws AsterixException {
+            List<AsterixFunction> declaredFunctions) throws AsterixException {
         if (expression == null) {
             return;
         }
 
-        List<FunIdentifier> functionCalls = getFunctionCalls(expression);
-        for (FunIdentifier funId : functionCalls) {
+        List<AsterixFunction> functionCalls = getFunctionCalls(expression);
+        for (AsterixFunction funId : functionCalls) {
             if (AsterixBuiltinFunctions.isBuiltinCompilerFunction(new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
-                    funId.getValue(), false))) {
+                    funId.getFunctionName(), false))) {
                 continue;
             }
 
             if (AsterixBuiltinFunctions.isBuiltinCompilerFunction(new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS,
-                    funId.getValue(), false))) {
+                    funId.getFunctionName(), false))) {
                 continue;
             }
             
@@ -178,48 +178,48 @@
         }
     }
 
-    private FunctionDecl getFunctionDecl(FunIdentifier funId) throws AsterixException {
-        Function function = MetadataManager.INSTANCE.getFunction(mdTxnCtx, dataverseName, funId.getValue(), funId
+    private FunctionDecl getFunctionDecl(AsterixFunction funId) throws AsterixException {
+        Function function = MetadataManager.INSTANCE.getFunction(mdTxnCtx, dataverseName, funId.getFunctionName(), funId
                 .getArity());
         if (function == null) {
             throw new AsterixException(" unknown function " + funId);
         }
-        return FunctionUtil.getFunctionDecl(function);
+        return FunctionUtils.getFunctionDecl(function);
 
     }
 
-    private List<FunIdentifier> getFunctionCalls(Expression expression) throws AsterixException {
-        Map<FunIdentifier, DfsColor> color = new HashMap<FunIdentifier, DfsColor>();
-        Map<FunIdentifier, List<FunIdentifier>> arcs = new HashMap<FunIdentifier, List<FunIdentifier>>();
+    private List<AsterixFunction> getFunctionCalls(Expression expression) throws AsterixException {
+        Map<AsterixFunction, DfsColor> color = new HashMap<AsterixFunction, DfsColor>();
+        Map<AsterixFunction, List<AsterixFunction>> arcs = new HashMap<AsterixFunction, List<AsterixFunction>>();
         GatherFunctionCalls gfc = new GatherFunctionCalls();
         expression.accept(gfc, null);
-        List<FunIdentifier> calls = gfc.getCalls();
+        List<AsterixFunction> calls = gfc.getCalls();
         return calls;
     }
 
     private void checkRecursivity(List<FunctionDecl> fdecls) throws AsterixException {
-        Map<FunIdentifier, DfsColor> color = new HashMap<FunIdentifier, DfsColor>();
-        Map<FunIdentifier, List<FunIdentifier>> arcs = new HashMap<FunIdentifier, List<FunIdentifier>>();
+        Map<AsterixFunction, DfsColor> color = new HashMap<AsterixFunction, DfsColor>();
+        Map<AsterixFunction, List<AsterixFunction>> arcs = new HashMap<AsterixFunction, List<AsterixFunction>>();
         for (FunctionDecl fd : fdecls) {
             GatherFunctionCalls gfc = new GatherFunctionCalls();
             fd.getFuncBody().accept(gfc, null);
-            List<FunIdentifier> calls = gfc.getCalls();
+            List<AsterixFunction> calls = gfc.getCalls();
             arcs.put(fd.getIdent(), calls);
             color.put(fd.getIdent(), DfsColor.WHITE);
         }
-        for (FunIdentifier a : arcs.keySet()) {
+        for (AsterixFunction a : arcs.keySet()) {
             if (color.get(a) == DfsColor.WHITE) {
                 checkRecursivityDfs(a, arcs, color);
             }
         }
     }
 
-    private void checkRecursivityDfs(FunIdentifier a, Map<FunIdentifier, List<FunIdentifier>> arcs,
-            Map<FunIdentifier, DfsColor> color) throws AsterixException {
+    private void checkRecursivityDfs(AsterixFunction a, Map<AsterixFunction, List<AsterixFunction>> arcs,
+            Map<AsterixFunction, DfsColor> color) throws AsterixException {
         color.put(a, DfsColor.GRAY);
-        List<FunIdentifier> next = arcs.get(a);
+        List<AsterixFunction> next = arcs.get(a);
         if (next != null) {
-            for (FunIdentifier f : next) {
+            for (AsterixFunction f : next) {
                 DfsColor dc = color.get(f);
                 if (dc == DfsColor.GRAY) {
                     throw new AsterixException("Recursive function calls, created by calling " + f + " starting from "
@@ -245,7 +245,7 @@
 
     private static class GatherFunctionCalls implements IAqlExpressionVisitor<Void, Void> {
 
-        private final List<FunIdentifier> calls = new ArrayList<FunIdentifier>();
+        private final List<AsterixFunction> calls = new ArrayList<AsterixFunction>();
 
         public GatherFunctionCalls() {
         }
@@ -530,7 +530,7 @@
             return null;
         }
 
-        public List<FunIdentifier> getCalls() {
+        public List<AsterixFunction> getCalls() {
             return calls;
         }
 
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/InlineUdfsVisitor.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/InlineUdfsVisitor.java
index 5c59c7c..f0b2da6 100644
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/InlineUdfsVisitor.java
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/InlineUdfsVisitor.java
@@ -6,8 +6,8 @@
 
 import edu.uci.ics.asterix.aql.base.Clause;
 import edu.uci.ics.asterix.aql.base.Expression;
-import edu.uci.ics.asterix.aql.base.Expression.Kind;
 import edu.uci.ics.asterix.aql.base.IAqlExpression;
+import edu.uci.ics.asterix.aql.base.Expression.Kind;
 import edu.uci.ics.asterix.aql.expression.BeginFeedStatement;
 import edu.uci.ics.asterix.aql.expression.CallExpr;
 import edu.uci.ics.asterix.aql.expression.ControlFeedStatement;
@@ -25,7 +25,6 @@
 import edu.uci.ics.asterix.aql.expression.FieldAccessor;
 import edu.uci.ics.asterix.aql.expression.FieldBinding;
 import edu.uci.ics.asterix.aql.expression.ForClause;
-import edu.uci.ics.asterix.aql.expression.FunIdentifier;
 import edu.uci.ics.asterix.aql.expression.FunctionDecl;
 import edu.uci.ics.asterix.aql.expression.FunctionDropStatement;
 import edu.uci.ics.asterix.aql.expression.GbyVariableExpressionPair;
@@ -65,6 +64,7 @@
 import edu.uci.ics.asterix.aql.expression.WriteStatement;
 import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 import edu.uci.ics.hyracks.algebricks.core.utils.Pair;
 
 public class InlineUdfsVisitor implements IAqlExpressionVisitor<Boolean, List<FunctionDecl>> {
@@ -337,7 +337,7 @@
         return new Pair<Boolean, ArrayList<Expression>>(changed, newList);
     }
 
-    private static FunctionDecl findFuncDeclaration(FunIdentifier fid, List<FunctionDecl> sequence) {
+    private static FunctionDecl findFuncDeclaration(AsterixFunction fid, List<FunctionDecl> sequence) {
         for (FunctionDecl f : sequence) {
             if (f.getIdent().equals(fid)) {
                 return f;
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/util/FunctionUtil.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/util/FunctionUtil.java
deleted file mode 100644
index 0214ada..0000000
--- a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/util/FunctionUtil.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package edu.uci.ics.asterix.aql.util;
-
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.List;
-
-import edu.uci.ics.asterix.aql.expression.FunctionDecl;
-import edu.uci.ics.asterix.aql.expression.Query;
-import edu.uci.ics.asterix.aql.expression.VarIdentifier;
-import edu.uci.ics.asterix.aql.parser.AQLParser;
-import edu.uci.ics.asterix.aql.parser.ParseException;
-import edu.uci.ics.asterix.common.exceptions.AsterixException;
-import edu.uci.ics.asterix.metadata.entities.Function;
-
-public class FunctionUtil {
-
-
-    public static FunctionDecl getFunctionDecl(Function function) throws AsterixException {
-        String functionBody = function.getFunctionBody();
-        List<String> params = function.getParams();
-        List<VarIdentifier> varIdentifiers = new ArrayList<VarIdentifier>();
-
-        StringBuilder builder = new StringBuilder();
-        builder.append(" declare function " + function.getFunctionName());
-        builder.append("(");
-        for (String param : params) {
-            VarIdentifier varId = new VarIdentifier(param);
-            varIdentifiers.add(varId);
-            builder.append(param);
-            builder.append(",");
-        }
-        builder.delete(builder.length() - 1, builder.length());
-        builder.append(")");
-        builder.append("{");
-        builder.append(functionBody);
-        builder.append("}");
-        AQLParser parser = new AQLParser(new StringReader(new String(builder)));
-
-        Query query = null;
-        try {
-            query = (Query) parser.Statement();
-        } catch (ParseException pe) {
-            throw new AsterixException(pe);
-        }
-
-        FunctionDecl decl = (FunctionDecl) query.getPrologDeclList().get(0);
-        return decl;
-    }
-}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/util/FunctionUtils.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/util/FunctionUtils.java
new file mode 100644
index 0000000..d246a92
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/util/FunctionUtils.java
@@ -0,0 +1,97 @@
+package edu.uci.ics.asterix.aql.util;
+
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.expression.FunctionDecl;
+import edu.uci.ics.asterix.aql.expression.Query;
+import edu.uci.ics.asterix.aql.expression.VarIdentifier;
+import edu.uci.ics.asterix.aql.parser.AQLParser;
+import edu.uci.ics.asterix.aql.parser.ParseException;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.common.functions.FunctionConstants;
+import edu.uci.ics.asterix.metadata.MetadataException;
+import edu.uci.ics.asterix.metadata.MetadataManager;
+import edu.uci.ics.asterix.metadata.MetadataTransactionContext;
+import edu.uci.ics.asterix.metadata.entities.Function;
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
+import edu.uci.ics.asterix.om.functions.AsterixFunctionInfo;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
+
+public class FunctionUtils {
+
+    public static FunctionDecl getFunctionDecl(Function function) throws AsterixException {
+        String functionBody = function.getFunctionBody();
+        List<String> params = function.getParams();
+        List<VarIdentifier> varIdentifiers = new ArrayList<VarIdentifier>();
+
+        StringBuilder builder = new StringBuilder();
+        builder.append(" declare function " + function.getFunctionName());
+        builder.append("(");
+        for (String param : params) {
+            VarIdentifier varId = new VarIdentifier(param);
+            varIdentifiers.add(varId);
+            builder.append(param);
+            builder.append(",");
+        }
+        builder.delete(builder.length() - 1, builder.length());
+        builder.append(")");
+        builder.append("{");
+        builder.append(functionBody);
+        builder.append("}");
+        AQLParser parser = new AQLParser(new StringReader(new String(builder)));
+
+        Query query = null;
+        try {
+            query = (Query) parser.Statement();
+        } catch (ParseException pe) {
+            throw new AsterixException(pe);
+        }
+
+        FunctionDecl decl = (FunctionDecl) query.getPrologDeclList().get(0);
+        return decl;
+    }
+
+    public static IFunctionInfo getFunctionInfo(FunctionIdentifier fi) {
+        return AsterixBuiltinFunctions.getAsterixFunctionInfo(fi);
+    }
+
+    public static IFunctionInfo getFunctionInfo(MetadataTransactionContext mdTxnCtx, String dataverseName,
+            AsterixFunction asterixFunction) throws MetadataException {
+        FunctionIdentifier fid = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+                asterixFunction.getFunctionName(), asterixFunction.getArity(), true);
+        IFunctionInfo finfo = AsterixBuiltinFunctions.getAsterixFunctionInfo(fid);
+        if (fid == null) {
+            fid = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS, asterixFunction.getFunctionName(),
+                    asterixFunction.getArity(), true);
+        }
+        if (fid == null) {
+            Function function = MetadataManager.INSTANCE.getFunction(mdTxnCtx, dataverseName, asterixFunction
+                    .getFunctionName(), asterixFunction.getArity());
+            if (function != null) {
+                finfo = new AsterixFunctionInfo(dataverseName, asterixFunction, false);
+                // todo: for external functions, we shall construct another kind of function info (that extends AsterixFunctionInfo)
+                // and has additional information.
+            }
+        }
+        return finfo; // could be null
+    }
+}
diff --git a/asterix-aql/src/main/javacc/AQL.jj b/asterix-aql/src/main/javacc/AQL.jj
index 544e855..1fa40b8 100644
--- a/asterix-aql/src/main/javacc/AQL.jj
+++ b/asterix-aql/src/main/javacc/AQL.jj
@@ -37,6 +37,7 @@
 import edu.uci.ics.asterix.aql.context.RootScopeFactory;
 import edu.uci.ics.asterix.common.annotations.*;
 import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.functions.AsterixFunction;
 
 
 public class AQLParser extends ScopeChecker {
@@ -1027,7 +1028,8 @@
 FunctionDecl FunctionDeclaration() throws ParseException:
 {
   FunctionDecl func = new FunctionDecl();
-  FunIdentifier ident = new FunIdentifier();
+  AsterixFunction ident;
+  String functionName;
   int arity = 0;
   List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
   Expression funcBody;
@@ -1039,7 +1041,7 @@
     <IDENTIFIER>
 	{
 	  Token t = getToken(0);
-	  ident.setValue(t.toString());
+	  functionName = t.toString();
 	}
     <LEFTPAREN> (<VARIABLE>
     {
@@ -1059,7 +1061,7 @@
     })*)? <RIGHTPAREN> "{" funcBody = Expression() "}"
 
     {
-      ident.setArity(arity);
+      ident = new AsterixFunction(functionName,arity);
       getCurrentScope().addFunctionDescriptor(ident, false);
       func.setIdent(ident);
       func.setFuncBody(funcBody);
@@ -1071,7 +1073,8 @@
 CreateFunctionStatement FunctionCreation() throws ParseException:
 {
   CreateFunctionStatement cfs = null;
-  FunIdentifier ident = new FunIdentifier();
+  AsterixFunction ident;
+  String functionName;
   int arity = 0;
   boolean ifNotExists = false;
   List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
@@ -1084,7 +1087,7 @@
     <IDENTIFIER>
 	{
 	  Token t = getToken(0);
-	  ident.setValue(t.toString());
+	  functionName= t.toString();
 	}
 	
 	(
@@ -1115,7 +1118,7 @@
           }
           "}"
     {
-      ident.setArity(arity);
+      ident = new AsterixFunction(functionName, arity);
       getCurrentScope().addFunctionDescriptor(ident, false);
       cfs = new CreateFunctionStatement(ident, paramList, funcBody, ifNotExists);
       return cfs;
@@ -1728,10 +1731,10 @@
      } ("," tmp = Expression() { argList.add(tmp); arity++; })*)? <RIGHTPAREN>
 
      {
-       FunIdentifier fd = lookupFunctionSignature(funcName.toString(), arity);
+       AsterixFunction fd = lookupFunctionSignature(funcName.toString(), arity);
 	     if(fd == null)
 	     {
-	        fd = new FunIdentifier(funcName.toString(), arity);
+	        fd = new AsterixFunction(funcName.toString(), arity);
 //	     	notFoundFunctionList.add(fd);
 	     }
 //	     	throw new ParseException("can't find function "+ funcName.toString() + "@" + arity);
diff --git a/asterix-common/src/main/java/edu/uci/ics/asterix/common/functions/FunctionUtils.java b/asterix-common/src/main/java/edu/uci/ics/asterix/common/functions/FunctionUtils.java
deleted file mode 100644
index ae72a65..0000000
--- a/asterix-common/src/main/java/edu/uci/ics/asterix/common/functions/FunctionUtils.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package edu.uci.ics.asterix.common.functions;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; 
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionInfoImpl;
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
-
-public class FunctionUtils {
-
-    private static Map<FunctionIdentifier, IFunctionInfo> _finfos = new HashMap<FunctionIdentifier, IFunctionInfo>();
-
-    public static IFunctionInfo getFunctionInfo(FunctionIdentifier fi) {
-        IFunctionInfo finfo = _finfos.get(fi);
-        if (finfo != null) {
-            return finfo;
-        }
-        IFunctionInfo newF = new FunctionInfoImpl(fi);
-        _finfos.put(fi, newF);
-        return newF;
-    }
-
-}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
index e9260c1..c898f86 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -9,7 +9,6 @@
 import org.apache.commons.lang3.mutable.Mutable;
 
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
 import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.ABooleanTypeComputer;
 import edu.uci.ics.asterix.om.typecomputer.impl.ACircleTypeComputer;
@@ -78,714 +77,690 @@
 
 public class AsterixBuiltinFunctions {
 
-	public enum SpatialFilterKind {
-		SI
-	}
+    public enum SpatialFilterKind {
+        SI
+    }
 
-	// it is supposed to be an identity mapping
-	private final static Map<FunctionIdentifier, FunctionIdentifier> builtinFunctionsSet = new HashMap<FunctionIdentifier, FunctionIdentifier>();
+    private final static Map<AsterixFunction, IFunctionInfo> asterixFunctionToInfo = new HashMap<AsterixFunction, IFunctionInfo>();
+    private final static Map<FunctionIdentifier, IFunctionInfo> asterixFunctionIdToInfo = new HashMap<FunctionIdentifier, IFunctionInfo>();
 
-	private final static Map<FunctionIdentifier, IResultTypeComputer> funTypeComputer = new HashMap<FunctionIdentifier, IResultTypeComputer>();
+    // it is supposed to be an identity mapping
+    private final static Map<IFunctionInfo, IFunctionInfo> builtinFunctionsSet = new HashMap<IFunctionInfo, IFunctionInfo>();
+    private final static Map<IFunctionInfo, IResultTypeComputer> funTypeComputer = new HashMap<IFunctionInfo, IResultTypeComputer>();
 
-	private final static Set<FunctionIdentifier> builtinAggregateFunctions = new HashSet<FunctionIdentifier>();
-	private static final Set<FunctionIdentifier> datasetFunctions = new HashSet<FunctionIdentifier>();
-	private static final Map<FunctionIdentifier, FunctionIdentifier> aggregateToLocalAggregate = new HashMap<FunctionIdentifier, FunctionIdentifier>();
-	private static final Map<FunctionIdentifier, FunctionIdentifier> aggregateToGlobalAggregate = new HashMap<FunctionIdentifier, FunctionIdentifier>();
-	private static final Map<FunctionIdentifier, FunctionIdentifier> aggregateToSerializableAggregate = new HashMap<FunctionIdentifier, FunctionIdentifier>();
-	private final static Map<FunctionIdentifier, Boolean> builtinUnnestingFunctions = new HashMap<FunctionIdentifier, Boolean>();
-	private final static Map<FunctionIdentifier, FunctionIdentifier> scalarToAggregateFunctionMap = new HashMap<FunctionIdentifier, FunctionIdentifier>();
-	private static final Map<FunctionIdentifier, SpatialFilterKind> spatialFilterFunctions = new HashMap<FunctionIdentifier, SpatialFilterKind>();
+    private final static Set<IFunctionInfo> builtinAggregateFunctions = new HashSet<IFunctionInfo>();
+    private static final Set<IFunctionInfo> datasetFunctions = new HashSet<IFunctionInfo>();
+    private static final Map<IFunctionInfo, IFunctionInfo> aggregateToLocalAggregate = new HashMap<IFunctionInfo, IFunctionInfo>();
+    private static final Map<IFunctionInfo, IFunctionInfo> aggregateToGlobalAggregate = new HashMap<IFunctionInfo, IFunctionInfo>();
+    private static final Map<IFunctionInfo, IFunctionInfo> aggregateToSerializableAggregate = new HashMap<IFunctionInfo, IFunctionInfo>();
+    private final static Map<IFunctionInfo, Boolean> builtinUnnestingFunctions = new HashMap<IFunctionInfo, Boolean>();
+    private final static Map<IFunctionInfo, IFunctionInfo> scalarToAggregateFunctionMap = new HashMap<IFunctionInfo, IFunctionInfo>();
+    private static final Map<IFunctionInfo, SpatialFilterKind> spatialFilterFunctions = new HashMap<IFunctionInfo, SpatialFilterKind>();
 
-	public final static FunctionIdentifier TYPE_OF = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "type-of", 1, true);
-	public final static FunctionIdentifier GET_HANDLE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "get-handle", 2, true);
-	public final static FunctionIdentifier GET_DATA = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "get-data", 2, true);
-	public final static FunctionIdentifier EMBED_TYPE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "embed-type", 1, true);
-
-	public final static FunctionIdentifier GET_ITEM = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "get-item", 2, true);
-	public final static FunctionIdentifier ANY_COLLECTION_MEMBER = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "any-collection-member", 1, true);
-	public final static FunctionIdentifier LISTIFY = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "listify", 1, true);
-	// public final static FunctionIdentifier BAGIFY = new
-	// FunctionIdentifier(ASTERIX_NS, "bagify", 1, true);
-	public final static FunctionIdentifier LEN = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "len", 1, true);
-
-	public final static FunctionIdentifier CONCAT_NON_NULL = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "concat-non-null",
-			FunctionIdentifier.VARARGS, true);
-	public final static FunctionIdentifier EMPTY_STREAM = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "empty-stream", 0, true);
-	public final static FunctionIdentifier NON_EMPTY_STREAM = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "non-empty-stream", 0, true);
-	public final static FunctionIdentifier ORDERED_LIST_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "ordered-list-constructor",
-			FunctionIdentifier.VARARGS, true);
-	public final static FunctionIdentifier UNORDERED_LIST_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "unordered-list-constructor",
-			FunctionIdentifier.VARARGS, true);
-
-	// records
-	public final static FunctionIdentifier CLOSED_RECORD_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "closed-record-constructor",
-			FunctionIdentifier.VARARGS, true);
-	public final static FunctionIdentifier OPEN_RECORD_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "open-record-constructor",
-			FunctionIdentifier.VARARGS, true);
-	public final static FunctionIdentifier RECORD_TYPE_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "record-type-constructor",
-			FunctionIdentifier.VARARGS, true);
-	public final static FunctionIdentifier FIELD_ACCESS_BY_INDEX = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "field-access-by-index", 2, true);
-	public final static FunctionIdentifier FIELD_ACCESS_BY_NAME = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "field-access-by-name", 2, true);
-
-	public final static FunctionIdentifier NUMERIC_UNARY_MINUS = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "numeric-unary-minus", 1, true);
-
-	public final static FunctionIdentifier NUMERIC_SUBTRACT = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "numeric-subtract", 2, true);
-	public final static FunctionIdentifier NUMERIC_MULTIPLY = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "numeric-multiply", 2, true);
-	public final static FunctionIdentifier NUMERIC_DIVIDE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "numeric-divide", 2, true);
-	public final static FunctionIdentifier NUMERIC_MOD = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "numeric-mod", 2, true);
-	public final static FunctionIdentifier NUMERIC_IDIV = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "numeric-idiv", 2, true);
-	public final static FunctionIdentifier CARET = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "caret", 2, true);
-
-	public final static FunctionIdentifier DATASET = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "dataset", 1, true);
-	public final static FunctionIdentifier FEED_INGEST = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "feed-ingest", 1,
+    public final static FunctionIdentifier TYPE_OF = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "type-of", 1,
             true);
-	
-	public final static FunctionIdentifier INDEX_SEARCH = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "index-search",
-			FunctionIdentifier.VARARGS, true);
+    public final static FunctionIdentifier GET_HANDLE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "get-handle", 2, true);
+    public final static FunctionIdentifier GET_DATA = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "get-data",
+            2, true);
+    public final static FunctionIdentifier EMBED_TYPE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "embed-type", 1, true);
 
-	public final static FunctionIdentifier MAKE_FIELD_INDEX_HANDLE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "make-field-index-handle", 2, true);
-	public final static FunctionIdentifier MAKE_FIELD_NAME_HANDLE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "make-field-name-handle", 1, true);
+    public final static FunctionIdentifier GET_ITEM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "get-item",
+            2, true);
+    public final static FunctionIdentifier ANY_COLLECTION_MEMBER = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "any-collection-member", 1, true);
+    public final static FunctionIdentifier LISTIFY = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "listify", 1,
+            true);
+    // public final static FunctionIdentifier BAGIFY = new
+    // FunctionIdentifier(ASTERIX_NS, "bagify", 1, true);
+    public final static FunctionIdentifier LEN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "len", 1, true);
 
-	public final static FunctionIdentifier SUBSTRING = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "substring", 3, true);
-	public final static FunctionIdentifier LIKE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "like", 2, true);
-	public final static FunctionIdentifier CONTAINS = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "contains", 2, true);
-	private final static FunctionIdentifier STARTS_WITH = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "starts-with", 2, true);
-	private final static FunctionIdentifier ENDS_WITH = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "ends-with", 2, true);
+    public final static FunctionIdentifier CONCAT_NON_NULL = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "concat-non-null", FunctionIdentifier.VARARGS, true);
+    public final static FunctionIdentifier EMPTY_STREAM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "empty-stream", 0, true);
+    public final static FunctionIdentifier NON_EMPTY_STREAM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "non-empty-stream", 0, true);
+    public final static FunctionIdentifier ORDERED_LIST_CONSTRUCTOR = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "ordered-list-constructor", FunctionIdentifier.VARARGS, true);
+    public final static FunctionIdentifier UNORDERED_LIST_CONSTRUCTOR = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "unordered-list-constructor", FunctionIdentifier.VARARGS, true);
 
-	public final static FunctionIdentifier AVG = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "agg-avg", 1, true);
-	public final static FunctionIdentifier COUNT = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "agg-count", 1, true);
-	public final static FunctionIdentifier SUM = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "agg-sum", 1, true);
-	public final static FunctionIdentifier MAX = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "agg-max", 1, true);
-	public final static FunctionIdentifier MIN = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "agg-min", 1, true);
-	public final static FunctionIdentifier GLOBAL_AVG = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "agg-global-avg", 1, true);
-	public final static FunctionIdentifier LOCAL_AVG = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "agg-local-avg", 1, true);
+    // records
+    public final static FunctionIdentifier CLOSED_RECORD_CONSTRUCTOR = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "closed-record-constructor", FunctionIdentifier.VARARGS, true);
+    public final static FunctionIdentifier OPEN_RECORD_CONSTRUCTOR = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "open-record-constructor", FunctionIdentifier.VARARGS, true);
+    public final static FunctionIdentifier RECORD_TYPE_CONSTRUCTOR = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "record-type-constructor", FunctionIdentifier.VARARGS, true);
+    public final static FunctionIdentifier FIELD_ACCESS_BY_INDEX = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "field-access-by-index", 2, true);
+    public final static FunctionIdentifier FIELD_ACCESS_BY_NAME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "field-access-by-name", 2, true);
 
-	public final static FunctionIdentifier SCALAR_AVG = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "avg", 1, true);
-	public final static FunctionIdentifier SCALAR_COUNT = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "count", 1, true);
-	public final static FunctionIdentifier SCALAR_SUM = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "sum", 1, true);
-	public final static FunctionIdentifier SCALAR_MAX = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "max", 1, true);
-	public final static FunctionIdentifier SCALAR_MIN = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "min", 1, true);
-	public final static FunctionIdentifier SCALAR_GLOBAL_AVG = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "global-avg", 1, true);
-	public final static FunctionIdentifier SCALAR_LOCAL_AVG = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "local-avg", 1, true);
+    public final static FunctionIdentifier NUMERIC_UNARY_MINUS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "numeric-unary-minus", 1, true);
 
-	// serializable aggregate functions
-	public final static FunctionIdentifier SERIAL_AVG = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "avg-serial", 1, true);
-	public final static FunctionIdentifier SERIAL_COUNT = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "count-serial", 1, true);
-	public final static FunctionIdentifier SERIAL_SUM = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "sum-serial", 1, true);
-	public final static FunctionIdentifier SERIAL_GLOBAL_AVG = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "global-avg-serial", 1, true);
-	public final static FunctionIdentifier SERIAL_LOCAL_AVG = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "local-avg-serial", 1, true);
+    public final static FunctionIdentifier NUMERIC_SUBTRACT = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "numeric-subtract", 2, true);
+    public final static FunctionIdentifier NUMERIC_MULTIPLY = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "numeric-multiply", 2, true);
+    public final static FunctionIdentifier NUMERIC_DIVIDE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "numeric-divide", 2, true);
+    public final static FunctionIdentifier NUMERIC_MOD = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "numeric-mod", 2, true);
+    public final static FunctionIdentifier NUMERIC_IDIV = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "numeric-idiv", 2, true);
+    public final static FunctionIdentifier CARET = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "caret", 2,
+            true);
 
-	public final static FunctionIdentifier YEAR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "year", 1, true);
+    public final static FunctionIdentifier DATASET = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "dataset", 1,
+            true);
+    public final static FunctionIdentifier FEED_INGEST = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "feed-ingest", 1, true);
 
-	public final static FunctionIdentifier SCAN_COLLECTION = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "scan-collection", 1, true);
-	public final static FunctionIdentifier SUBSET_COLLECTION = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "subset-collection", 3, true);
+    public final static FunctionIdentifier INDEX_SEARCH = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "index-search", FunctionIdentifier.VARARGS, true);
 
-	public final static FunctionIdentifier RANGE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "range", 2, true);
+    public final static FunctionIdentifier MAKE_FIELD_INDEX_HANDLE = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "make-field-index-handle", 2, true);
+    public final static FunctionIdentifier MAKE_FIELD_NAME_HANDLE = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "make-field-name-handle", 1, true);
 
-	// fuzzy functions:
-	public final static FunctionIdentifier FUZZY_EQ = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "fuzzy-eq", 2, true);
+    public final static FunctionIdentifier SUBSTRING = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "substring", 3, true);
+    public final static FunctionIdentifier LIKE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "like", 2, true);
+    public final static FunctionIdentifier CONTAINS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "contains",
+            2, true);
+    private final static FunctionIdentifier STARTS_WITH = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "starts-with", 2, true);
+    private final static FunctionIdentifier ENDS_WITH = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "ends-with", 2, true);
 
-	public final static FunctionIdentifier PREFIX_LEN_JACCARD = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "prefix-len-jaccard", 2, true);
+    public final static FunctionIdentifier AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-avg", 1,
+            true);
+    public final static FunctionIdentifier COUNT = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-count", 1,
+            true);
+    public final static FunctionIdentifier SUM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-sum", 1,
+            true);
+    public final static FunctionIdentifier MAX = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-max", 1,
+            true);
+    public final static FunctionIdentifier MIN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-min", 1,
+            true);
+    public final static FunctionIdentifier GLOBAL_AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "agg-global-avg", 1, true);
+    public final static FunctionIdentifier LOCAL_AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "agg-local-avg", 1, true);
 
-	public final static FunctionIdentifier SIMILARITY_JACCARD = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "similarity-jaccard", 2, true);
-	public final static FunctionIdentifier SIMILARITY_JACCARD_CHECK = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "similarity-jaccard-check", 3, true);
-	public final static FunctionIdentifier SIMILARITY_JACCARD_PREFIX = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "similarity-jaccard-prefix", 6, true);
-	public final static FunctionIdentifier SIMILARITY_JACCARD_PREFIX_CHECK = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "similarity-jaccard-prefix-check", 6,
-			true);
+    public final static FunctionIdentifier SCALAR_AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "avg", 1,
+            true);
+    public final static FunctionIdentifier SCALAR_COUNT = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "count",
+            1, true);
+    public final static FunctionIdentifier SCALAR_SUM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "sum", 1,
+            true);
+    public final static FunctionIdentifier SCALAR_MAX = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "max", 1,
+            true);
+    public final static FunctionIdentifier SCALAR_MIN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "min", 1,
+            true);
+    public final static FunctionIdentifier SCALAR_GLOBAL_AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "global-avg", 1, true);
+    public final static FunctionIdentifier SCALAR_LOCAL_AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "local-avg", 1, true);
 
-	public final static FunctionIdentifier EDIT_DISTANCE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "edit-distance", 2, true);
-	public final static FunctionIdentifier EDIT_DISTANCE_CHECK = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "edit-distance-check", 3, true);
+    // serializable aggregate functions
+    public final static FunctionIdentifier SERIAL_AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "avg-serial", 1, true);
+    public final static FunctionIdentifier SERIAL_COUNT = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "count-serial", 1, true);
+    public final static FunctionIdentifier SERIAL_SUM = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "sum-serial", 1, true);
+    public final static FunctionIdentifier SERIAL_GLOBAL_AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "global-avg-serial", 1, true);
+    public final static FunctionIdentifier SERIAL_LOCAL_AVG = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "local-avg-serial", 1, true);
 
-	// tokenizers:
-	public final static FunctionIdentifier WORD_TOKENS = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "word-tokens", 1, true);
-	public final static FunctionIdentifier HASHED_WORD_TOKENS = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "hashed-word-tokens", 1, true);
-	public final static FunctionIdentifier COUNTHASHED_WORD_TOKENS = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "counthashed-word-tokens", 1, true);
-	public final static FunctionIdentifier GRAM_TOKENS = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "gram-tokens", 3, true);
-	public final static FunctionIdentifier HASHED_GRAM_TOKENS = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "hashed-gram-tokens", 3, true);
-	public final static FunctionIdentifier COUNTHASHED_GRAM_TOKENS = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "counthashed-gram-tokens", 3, true);
+    public final static FunctionIdentifier YEAR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "year", 1, true);
 
-	public final static FunctionIdentifier TID = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "tid", 0, true);
+    public final static FunctionIdentifier SCAN_COLLECTION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "scan-collection", 1, true);
+    public final static FunctionIdentifier SUBSET_COLLECTION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "subset-collection", 3, true);
 
-	// constructors:
-	public final static FunctionIdentifier BOOLEAN_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "boolean", 1, false);
-	public final static FunctionIdentifier NULL_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "null", 1, false);
-	public final static FunctionIdentifier STRING_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "string", 1, false);
-	public final static FunctionIdentifier INT8_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "int8", 1, false);
-	public final static FunctionIdentifier INT16_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "int16", 1, false);
-	public final static FunctionIdentifier INT32_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "int32", 1, false);
-	public final static FunctionIdentifier INT64_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "int64", 1, false);
-	public final static FunctionIdentifier FLOAT_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "float", 1, false);
-	public final static FunctionIdentifier DOUBLE_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "double", 1, false);
-	public final static FunctionIdentifier POINT_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "point", 1, false);
-	public final static FunctionIdentifier POINT3D_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "point3d", 1, false);
-	public final static FunctionIdentifier LINE_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "line", 1, false);
-	public final static FunctionIdentifier CIRCLE_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "circle", 1, false);
-	public final static FunctionIdentifier RECTANGLE_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "rectangle", 1, false);
-	public final static FunctionIdentifier POLYGON_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "polygon", 1, false);
-	public final static FunctionIdentifier TIME_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "time", 1, false);
-	public final static FunctionIdentifier DATE_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "date", 1, false);
-	public final static FunctionIdentifier DATETIME_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "datetime", 1, false);
-	public final static FunctionIdentifier DURATION_CONSTRUCTOR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "duration", 1, false);
+    public final static FunctionIdentifier RANGE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "range", 2,
+            true);
 
-	// spatial
-	public final static FunctionIdentifier CREATE_POINT = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "create-point", 2, true);
-	public final static FunctionIdentifier CREATE_LINE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "create-line", 2, true);
-	public final static FunctionIdentifier CREATE_POLYGON = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "create-polygon",
-			FunctionIdentifier.VARARGS, true);
-	public final static FunctionIdentifier CREATE_CIRCLE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "create-circle", 2, true);
-	public final static FunctionIdentifier CREATE_RECTANGLE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "create-rectangle", 2, true);
-	public final static FunctionIdentifier SPATIAL_INTERSECT = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "spatial-intersect", 2, true);
-	public final static FunctionIdentifier SPATIAL_AREA = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "spatial-area", 1, true);
-	public final static FunctionIdentifier SPATIAL_DISTANCE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "spatial-distance", 2, true);
-	public final static FunctionIdentifier CREATE_MBR = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "create-mbr", 3, true);
-	public final static FunctionIdentifier SPATIAL_CELL = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "spatial-cell", 4, true);
-	public final static FunctionIdentifier SWITCH_CASE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "switch-case",
-			FunctionIdentifier.VARARGS, true);
-	public final static FunctionIdentifier REG_EXP = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "reg-exp", 2, true);
-	public final static FunctionIdentifier INJECT_FAILURE = new FunctionIdentifier(
-			FunctionConstants.ASTERIX_NS, "inject-failure", 2, true);
+    // fuzzy functions:
+    public final static FunctionIdentifier FUZZY_EQ = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "fuzzy-eq",
+            2, true);
 
-	static {
-		// first, take care of Algebricks builtin functions
-		for (FunctionIdentifier fi : AlgebricksBuiltinFunctions
-				.getAlgebricksBuiltinFunctions()) {
-			builtinFunctionsSet.put(fi, fi);
-		}
-		funTypeComputer.put(AlgebricksBuiltinFunctions.AND,
-				BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		funTypeComputer.put(AlgebricksBuiltinFunctions.EQ,
-				BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		funTypeComputer.put(AlgebricksBuiltinFunctions.GE,
-				BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		funTypeComputer.put(AlgebricksBuiltinFunctions.GT,
-				BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		funTypeComputer.put(AlgebricksBuiltinFunctions.IS_NULL,
-				ABooleanTypeComputer.INSTANCE);
-		funTypeComputer.put(AlgebricksBuiltinFunctions.LE,
-				BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		funTypeComputer.put(AlgebricksBuiltinFunctions.LT,
-				BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		funTypeComputer.put(AlgebricksBuiltinFunctions.NEQ,
-				BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		funTypeComputer.put(AlgebricksBuiltinFunctions.NOT,
-				UnaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		funTypeComputer.put(AlgebricksBuiltinFunctions.OR,
-				BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		funTypeComputer.put(AlgebricksBuiltinFunctions.NUMERIC_ADD,
-				NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
+    public final static FunctionIdentifier PREFIX_LEN_JACCARD = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "prefix-len-jaccard", 2, true);
 
-		// and then, Asterix builtin functions
-		add(ANY_COLLECTION_MEMBER, NonTaggedCollectionMemberResultType.INSTANCE);
-		add(AVG, OptionalADoubleTypeComputer.INSTANCE);
-		add(BOOLEAN_CONSTRUCTOR,
-				UnaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		add(CARET, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
-		add(CIRCLE_CONSTRUCTOR, OptionalACircleTypeComputer.INSTANCE);
-		add(CLOSED_RECORD_CONSTRUCTOR,
-				ClosedRecordConstructorResultType.INSTANCE);
-		add(CONCAT_NON_NULL, new IResultTypeComputer() {
-			@Override
-			public IAType computeType(ILogicalExpression expression,
-					IVariableTypeEnvironment env,
-					IMetadataProvider<?, ?> metadataProvider)
-					throws AlgebricksException {
-				AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression;
-				if (f.getArguments().size() < 1) {
-					return BuiltinType.ANULL;
-				}
-				ILogicalExpression a0 = f.getArguments().get(0).getValue();
-				IAType t0 = (IAType) env.getType(a0);
-				if (TypeHelper.canBeNull(t0)) {
-					return t0;
-				}
-				return AUnionType.createNullableType(t0);
-			}
-		});
-		add(CONTAINS, ABooleanTypeComputer.INSTANCE);
-		add(COUNT, AInt32TypeComputer.INSTANCE);
-		add(COUNTHASHED_GRAM_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
-		add(COUNTHASHED_WORD_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
-		add(CREATE_CIRCLE, ACircleTypeComputer.INSTANCE);
-		add(CREATE_LINE, ALineTypeComputer.INSTANCE);
-		add(CREATE_MBR, ADoubleTypeComputer.INSTANCE);
-		add(CREATE_POINT, APointTypeComputer.INSTANCE);
-		add(CREATE_POLYGON, APolygonTypeComputer.INSTANCE);
-		add(CREATE_RECTANGLE, ARectangleTypeComputer.INSTANCE);
+    public final static FunctionIdentifier SIMILARITY_JACCARD = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "similarity-jaccard", 2, true);
+    public final static FunctionIdentifier SIMILARITY_JACCARD_CHECK = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "similarity-jaccard-check", 3, true);
+    public final static FunctionIdentifier SIMILARITY_JACCARD_PREFIX = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "similarity-jaccard-prefix", 6, true);
+    public final static FunctionIdentifier SIMILARITY_JACCARD_PREFIX_CHECK = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "similarity-jaccard-prefix-check", 6, true);
 
-		add(DATE_CONSTRUCTOR, OptionalADateTypeComputer.INSTANCE);
-		add(DATETIME_CONSTRUCTOR, OptionalADateTimeTypeComputer.INSTANCE);
-		add(DOUBLE_CONSTRUCTOR, OptionalADoubleTypeComputer.INSTANCE);
-		add(DURATION_CONSTRUCTOR, OptionalADurationTypeComputer.INSTANCE);
-		add(EDIT_DISTANCE, AInt32TypeComputer.INSTANCE);
-		add(EDIT_DISTANCE_CHECK, OrderedListOfAnyTypeComputer.INSTANCE);
-		add(EMBED_TYPE, new IResultTypeComputer() {
-			@Override
-			public IAType computeType(ILogicalExpression expression,
-					IVariableTypeEnvironment env, IMetadataProvider<?, ?> mp)
-					throws AlgebricksException {
-				return (IAType) BuiltinType.ANY;
-			}
-		});
-		add(EMPTY_STREAM, ABooleanTypeComputer.INSTANCE);
-		add(ENDS_WITH, ABooleanTypeComputer.INSTANCE);
-		// add(FIELD_ACCESS, NonTaggedFieldAccessByNameResultType.INSTANCE);
-		add(FIELD_ACCESS_BY_INDEX, FieldAccessByIndexResultType.INSTANCE);
-		add(FIELD_ACCESS_BY_NAME, NonTaggedFieldAccessByNameResultType.INSTANCE);
-		add(FLOAT_CONSTRUCTOR, OptionalAFloatTypeComputer.INSTANCE);
-		add(FUZZY_EQ, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		add(GET_HANDLE, null); // TODO
-		add(GET_ITEM, NonTaggedGetItemResultType.INSTANCE);
-		add(GET_DATA, null); // TODO
-		add(GLOBAL_AVG, OptionalADoubleTypeComputer.INSTANCE);
-		add(GRAM_TOKENS, OrderedListOfAStringTypeComputer.INSTANCE);
-		add(GLOBAL_AVG, OptionalADoubleTypeComputer.INSTANCE);
-		add(HASHED_GRAM_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
-		add(HASHED_WORD_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
-		add(INDEX_SEARCH, new IResultTypeComputer() {
+    public final static FunctionIdentifier EDIT_DISTANCE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "edit-distance", 2, true);
+    public final static FunctionIdentifier EDIT_DISTANCE_CHECK = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "edit-distance-check", 3, true);
 
-			@Override
-			public IAType computeType(ILogicalExpression expression,
-					IVariableTypeEnvironment env, IMetadataProvider<?, ?> mp)
-					throws AlgebricksException {
-				return BuiltinType.ANY; // TODO
-			}
-		});
-		add(INT8_CONSTRUCTOR, OptionalAInt8TypeComputer.INSTANCE);
-		add(INT16_CONSTRUCTOR, OptionalAInt16TypeComputer.INSTANCE);
-		add(INT32_CONSTRUCTOR, OptionalAInt32TypeComputer.INSTANCE);
-		add(INT64_CONSTRUCTOR, OptionalAInt64TypeComputer.INSTANCE);
-		add(LEN, OptionalAInt32TypeComputer.INSTANCE);
-		add(LIKE, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
-		add(LINE_CONSTRUCTOR, OptionalALineTypeComputer.INSTANCE);
-		add(LISTIFY, OrderedListConstructorResultType.INSTANCE);
-		add(LOCAL_AVG, NonTaggedLocalAvgTypeComputer.INSTANCE);
-		add(MAKE_FIELD_INDEX_HANDLE, null); // TODO
-		add(MAKE_FIELD_NAME_HANDLE, null); // TODO
-		add(MAX, NonTaggedSumTypeComputer.INSTANCE);
-		add(MIN, NonTaggedSumTypeComputer.INSTANCE);
-		add(NON_EMPTY_STREAM, ABooleanTypeComputer.INSTANCE);
-		add(NULL_CONSTRUCTOR, ANullTypeComputer.INSTANCE);
-		add(NUMERIC_UNARY_MINUS, NonTaggedUnaryMinusTypeComputer.INSTANCE);
-		add(NUMERIC_SUBTRACT, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
-		add(NUMERIC_MULTIPLY, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
-		add(NUMERIC_DIVIDE, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
-		add(NUMERIC_MOD, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
-		add(NUMERIC_IDIV, AInt32TypeComputer.INSTANCE);
-		add(OPEN_RECORD_CONSTRUCTOR, OpenRecordConstructorResultType.INSTANCE);
-		add(ORDERED_LIST_CONSTRUCTOR, OrderedListConstructorResultType.INSTANCE);
-		add(POINT_CONSTRUCTOR, OptionalAPointTypeComputer.INSTANCE);
-		add(POINT3D_CONSTRUCTOR, OptionalAPoint3DTypeComputer.INSTANCE);
-		add(POLYGON_CONSTRUCTOR, OptionalAPolygonTypeComputer.INSTANCE);
-		add(PREFIX_LEN_JACCARD, AInt32TypeComputer.INSTANCE);
-		add(RANGE, AInt32TypeComputer.INSTANCE);
-		add(RECTANGLE_CONSTRUCTOR, OptionalARectangleTypeComputer.INSTANCE);
-		// add(RECORD_TYPE_CONSTRUCTOR, null);
-		add(SCALAR_AVG, ScalarVersionOfAggregateResultType.INSTANCE);
-		add(SCALAR_COUNT, ScalarVersionOfAggregateResultType.INSTANCE);
-		add(SCALAR_GLOBAL_AVG, ScalarVersionOfAggregateResultType.INSTANCE);
-		add(SCALAR_LOCAL_AVG, ScalarVersionOfAggregateResultType.INSTANCE);
-		add(SCALAR_MAX, ScalarVersionOfAggregateResultType.INSTANCE);
-		add(SCALAR_MIN, ScalarVersionOfAggregateResultType.INSTANCE);
-		add(SCALAR_SUM, ScalarVersionOfAggregateResultType.INSTANCE);
-		add(SCAN_COLLECTION, NonTaggedCollectionMemberResultType.INSTANCE);
-		add(SERIAL_AVG, OptionalADoubleTypeComputer.INSTANCE);
-		add(SERIAL_COUNT, AInt32TypeComputer.INSTANCE);
-		add(SERIAL_GLOBAL_AVG, OptionalADoubleTypeComputer.INSTANCE);
-		add(SERIAL_LOCAL_AVG, NonTaggedLocalAvgTypeComputer.INSTANCE);
-		add(SERIAL_SUM, NonTaggedSumTypeComputer.INSTANCE);
-		add(SIMILARITY_JACCARD, AFloatTypeComputer.INSTANCE);
-		add(SIMILARITY_JACCARD_CHECK, OrderedListOfAnyTypeComputer.INSTANCE);
-		add(SIMILARITY_JACCARD_PREFIX, AFloatTypeComputer.INSTANCE);
-		add(SIMILARITY_JACCARD_PREFIX_CHECK,
-				OrderedListOfAnyTypeComputer.INSTANCE);
-		add(SPATIAL_AREA, ADoubleTypeComputer.INSTANCE);
-		add(SPATIAL_CELL, ARectangleTypeComputer.INSTANCE);
-		add(SPATIAL_DISTANCE, ADoubleTypeComputer.INSTANCE);
-		add(SPATIAL_INTERSECT, ABooleanTypeComputer.INSTANCE);
-		add(STARTS_WITH, ABooleanTypeComputer.INSTANCE);
-		add(STRING_CONSTRUCTOR, OptionalAStringTypeComputer.INSTANCE);
-		add(SUBSET_COLLECTION, new IResultTypeComputer() {
+    // tokenizers:
+    public final static FunctionIdentifier WORD_TOKENS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "word-tokens", 1, true);
+    public final static FunctionIdentifier HASHED_WORD_TOKENS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "hashed-word-tokens", 1, true);
+    public final static FunctionIdentifier COUNTHASHED_WORD_TOKENS = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "counthashed-word-tokens", 1, true);
+    public final static FunctionIdentifier GRAM_TOKENS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "gram-tokens", 3, true);
+    public final static FunctionIdentifier HASHED_GRAM_TOKENS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "hashed-gram-tokens", 3, true);
+    public final static FunctionIdentifier COUNTHASHED_GRAM_TOKENS = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "counthashed-gram-tokens", 3, true);
 
-			@Override
-			public IAType computeType(ILogicalExpression expression,
-					IVariableTypeEnvironment env, IMetadataProvider<?, ?> mp)
-					throws AlgebricksException {
-				AbstractFunctionCallExpression fun = (AbstractFunctionCallExpression) expression;
-				IAType t;
-				try {
-					t = (IAType) env.getType(fun.getArguments().get(0)
-							.getValue());
-				} catch (AlgebricksException e) {
-					throw new AlgebricksException(e);
-				}
-				switch (t.getTypeTag()) {
-				case UNORDEREDLIST:
-				case ORDEREDLIST: {
-					AbstractCollectionType act = (AbstractCollectionType) t;
-					return act.getItemType();
-				}
-				case UNION: {
-					AUnionType ut = (AUnionType) t;
-					if (!ut.isNullableType()) {
-						throw new AlgebricksException(
-								"Expecting collection type. Found " + t);
-					}
-					IAType t2 = ut.getUnionList().get(1);
-					ATypeTag tag2 = t2.getTypeTag();
-					if (tag2 == ATypeTag.UNORDEREDLIST
-							|| tag2 == ATypeTag.ORDEREDLIST) {
-						AbstractCollectionType act = (AbstractCollectionType) t2;
-						return act.getItemType();
-					}
-					throw new AlgebricksException(
-							"Expecting collection type. Found " + t);
-				}
-				default: {
-					throw new AlgebricksException(
-							"Expecting collection type. Found " + t);
-				}
-				}
-			}
-		});
-		add(SUBSTRING, AStringTypeComputer.INSTANCE);
-		add(SUM, NonTaggedSumTypeComputer.INSTANCE);
-		add(SWITCH_CASE, NonTaggedSwitchCaseComputer.INSTANCE);
-		add(REG_EXP, ABooleanTypeComputer.INSTANCE);
-		add(INJECT_FAILURE, InjectFailureTypeComputer.INSTANCE);
+    public final static FunctionIdentifier TID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "tid", 0, true);
 
-		add(TID, AInt32TypeComputer.INSTANCE);
-		add(TIME_CONSTRUCTOR, OptionalATimeTypeComputer.INSTANCE);
-		add(TYPE_OF, null); // TODO
-		add(UNORDERED_LIST_CONSTRUCTOR,
-				UnorderedListConstructorResultType.INSTANCE);
-		add(YEAR, OptionalAInt32TypeComputer.INSTANCE);
-		add(WORD_TOKENS, new IResultTypeComputer() {
+    // constructors:
+    public final static FunctionIdentifier BOOLEAN_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "boolean", 1, false);
+    public final static FunctionIdentifier NULL_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "null", 1, false);
+    public final static FunctionIdentifier STRING_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "string", 1, false);
+    public final static FunctionIdentifier INT8_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "int8", 1, false);
+    public final static FunctionIdentifier INT16_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "int16", 1, false);
+    public final static FunctionIdentifier INT32_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "int32", 1, false);
+    public final static FunctionIdentifier INT64_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "int64", 1, false);
+    public final static FunctionIdentifier FLOAT_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "float", 1, false);
+    public final static FunctionIdentifier DOUBLE_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "double", 1, false);
+    public final static FunctionIdentifier POINT_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "point", 1, false);
+    public final static FunctionIdentifier POINT3D_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "point3d", 1, false);
+    public final static FunctionIdentifier LINE_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "line", 1, false);
+    public final static FunctionIdentifier CIRCLE_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "circle", 1, false);
+    public final static FunctionIdentifier RECTANGLE_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "rectangle", 1, false);
+    public final static FunctionIdentifier POLYGON_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "polygon", 1, false);
+    public final static FunctionIdentifier TIME_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "time", 1, false);
+    public final static FunctionIdentifier DATE_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "date", 1, false);
+    public final static FunctionIdentifier DATETIME_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "datetime", 1, false);
+    public final static FunctionIdentifier DURATION_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "duration", 1, false);
 
-			@Override
-			public IAType computeType(ILogicalExpression expression,
-					IVariableTypeEnvironment env, IMetadataProvider<?, ?> mp)
-					throws AlgebricksException {
-				return new AOrderedListType(BuiltinType.ASTRING, "string");
-			}
-		});
+    // spatial
+    public final static FunctionIdentifier CREATE_POINT = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "create-point", 2, true);
+    public final static FunctionIdentifier CREATE_LINE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "create-line", 2, true);
+    public final static FunctionIdentifier CREATE_POLYGON = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "create-polygon", FunctionIdentifier.VARARGS, true);
+    public final static FunctionIdentifier CREATE_CIRCLE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "create-circle", 2, true);
+    public final static FunctionIdentifier CREATE_RECTANGLE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "create-rectangle", 2, true);
+    public final static FunctionIdentifier SPATIAL_INTERSECT = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "spatial-intersect", 2, true);
+    public final static FunctionIdentifier SPATIAL_AREA = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "spatial-area", 1, true);
+    public final static FunctionIdentifier SPATIAL_DISTANCE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "spatial-distance", 2, true);
+    public final static FunctionIdentifier CREATE_MBR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "create-mbr", 3, true);
+    public final static FunctionIdentifier SPATIAL_CELL = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "spatial-cell", 4, true);
+    public final static FunctionIdentifier SWITCH_CASE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "switch-case", FunctionIdentifier.VARARGS, true);
+    public final static FunctionIdentifier REG_EXP = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "reg-exp", 2,
+            true);
+    public final static FunctionIdentifier INJECT_FAILURE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "inject-failure", 2, true);
 
-		String metadataFunctionLoaderClassName = "edu.uci.ics.asterix.metadata.functions.MetadataBuiltinFunctions";
-		try {
-			Class.forName(metadataFunctionLoaderClassName);
-		} catch (ClassNotFoundException e) {
-			throw new RuntimeException(e);
-		}
-	}
+    public static final FunctionIdentifier EQ = AlgebricksBuiltinFunctions.EQ;
+    public static final FunctionIdentifier LE = AlgebricksBuiltinFunctions.LE;
+    public static final FunctionIdentifier GE = AlgebricksBuiltinFunctions.GE;
+    public static final FunctionIdentifier LT = AlgebricksBuiltinFunctions.LT;
+    public static final FunctionIdentifier GT = AlgebricksBuiltinFunctions.GT;
+    public static final FunctionIdentifier NEQ = AlgebricksBuiltinFunctions.NEQ;
+    public static final FunctionIdentifier AND = AlgebricksBuiltinFunctions.AND;
+    public static final FunctionIdentifier OR = AlgebricksBuiltinFunctions.OR;
+    public static final FunctionIdentifier NOT = AlgebricksBuiltinFunctions.NOT;
+    public static final FunctionIdentifier NUMERIC_ADD = AlgebricksBuiltinFunctions.NUMERIC_ADD;
+    public static final FunctionIdentifier IS_NULL = AlgebricksBuiltinFunctions.IS_NULL;
 
-	static {
-		scalarToAggregateFunctionMap.put(SCALAR_AVG, AVG);
-		scalarToAggregateFunctionMap.put(SCALAR_COUNT, COUNT);
-		scalarToAggregateFunctionMap.put(SCALAR_GLOBAL_AVG, GLOBAL_AVG);
-		scalarToAggregateFunctionMap.put(SCALAR_LOCAL_AVG, LOCAL_AVG);
-		scalarToAggregateFunctionMap.put(SCALAR_MAX, MAX);
-		scalarToAggregateFunctionMap.put(SCALAR_MIN, MIN);
-		scalarToAggregateFunctionMap.put(SCALAR_SUM, SUM);
-	}
+    public static IFunctionInfo getAsterixFunctionInfo(FunctionIdentifier fid) {
+        IFunctionInfo finfo = asterixFunctionIdToInfo.get(fid);
+        if (finfo == null) {
+            finfo = new AsterixFunctionInfo(fid, fid.isBuiltin());
+            if(fid.isBuiltin()){
+                asterixFunctionIdToInfo.put(fid, finfo);
+            }
+        }
+        return finfo;
+    }
 
-	static {
-		addAgg(AVG);
-		addAgg(LOCAL_AVG);
-		addAgg(GLOBAL_AVG);
-		addLocalAgg(AVG, LOCAL_AVG);
-		addGlobalAgg(AVG, GLOBAL_AVG);
+    static {
 
-		addAgg(COUNT);
-		addLocalAgg(COUNT, COUNT);
-		addGlobalAgg(COUNT, SUM);
+        // first, take care of Algebricks builtin functions
+        add(EQ, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(LE, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(GE, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(LT, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(GT, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(IS_NULL, ABooleanTypeComputer.INSTANCE);
+        add(AND, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(NEQ, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(NOT, UnaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(OR, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(NUMERIC_ADD, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
 
-		addAgg(MAX);
-		addLocalAgg(MAX, MAX);
-		addGlobalAgg(MAX, MAX);
+        // and then, Asterix builtin functions
+        add(ANY_COLLECTION_MEMBER, NonTaggedCollectionMemberResultType.INSTANCE);
+        add(AVG, OptionalADoubleTypeComputer.INSTANCE);
+        add(BOOLEAN_CONSTRUCTOR, UnaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(CARET, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
+        add(CIRCLE_CONSTRUCTOR, OptionalACircleTypeComputer.INSTANCE);
+        add(CLOSED_RECORD_CONSTRUCTOR, ClosedRecordConstructorResultType.INSTANCE);
+        add(CONCAT_NON_NULL, new IResultTypeComputer() {
+            @Override
+            public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+                    IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+                AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression;
+                if (f.getArguments().size() < 1) {
+                    return BuiltinType.ANULL;
+                }
+                ILogicalExpression a0 = f.getArguments().get(0).getValue();
+                IAType t0 = (IAType) env.getType(a0);
+                if (TypeHelper.canBeNull(t0)) {
+                    return t0;
+                }
+                return AUnionType.createNullableType(t0);
+            }
+        });
+        add(CONTAINS, ABooleanTypeComputer.INSTANCE);
+        add(COUNT, AInt32TypeComputer.INSTANCE);
+        add(COUNTHASHED_GRAM_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
+        add(COUNTHASHED_WORD_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
+        add(CREATE_CIRCLE, ACircleTypeComputer.INSTANCE);
+        add(CREATE_LINE, ALineTypeComputer.INSTANCE);
+        add(CREATE_MBR, ADoubleTypeComputer.INSTANCE);
+        add(CREATE_POINT, APointTypeComputer.INSTANCE);
+        add(CREATE_POLYGON, APolygonTypeComputer.INSTANCE);
+        add(CREATE_RECTANGLE, ARectangleTypeComputer.INSTANCE);
 
-		addAgg(MIN);
-		addLocalAgg(MIN, MIN);
-		addGlobalAgg(MIN, MIN);
+        add(DATE_CONSTRUCTOR, OptionalADateTypeComputer.INSTANCE);
+        add(DATETIME_CONSTRUCTOR, OptionalADateTimeTypeComputer.INSTANCE);
+        add(DOUBLE_CONSTRUCTOR, OptionalADoubleTypeComputer.INSTANCE);
+        add(DURATION_CONSTRUCTOR, OptionalADurationTypeComputer.INSTANCE);
+        add(EDIT_DISTANCE, AInt32TypeComputer.INSTANCE);
+        add(EDIT_DISTANCE_CHECK, OrderedListOfAnyTypeComputer.INSTANCE);
+        add(EMBED_TYPE, new IResultTypeComputer() {
+            @Override
+            public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+                    IMetadataProvider<?, ?> mp) throws AlgebricksException {
+                return (IAType) BuiltinType.ANY;
+            }
+        });
+        add(EMPTY_STREAM, ABooleanTypeComputer.INSTANCE);
+        add(ENDS_WITH, ABooleanTypeComputer.INSTANCE);
+        // add(FIELD_ACCESS, NonTaggedFieldAccessByNameResultType.INSTANCE);
+        add(FIELD_ACCESS_BY_INDEX, FieldAccessByIndexResultType.INSTANCE);
+        add(FIELD_ACCESS_BY_NAME, NonTaggedFieldAccessByNameResultType.INSTANCE);
+        add(FLOAT_CONSTRUCTOR, OptionalAFloatTypeComputer.INSTANCE);
+        add(FUZZY_EQ, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(GET_HANDLE, null); // TODO
+        add(GET_ITEM, NonTaggedGetItemResultType.INSTANCE);
+        add(GET_DATA, null); // TODO
+        add(GLOBAL_AVG, OptionalADoubleTypeComputer.INSTANCE);
+        add(GRAM_TOKENS, OrderedListOfAStringTypeComputer.INSTANCE);
+        add(GLOBAL_AVG, OptionalADoubleTypeComputer.INSTANCE);
+        add(HASHED_GRAM_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
+        add(HASHED_WORD_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
+        add(INDEX_SEARCH, new IResultTypeComputer() {
 
-		addAgg(SUM);
-		addLocalAgg(SUM, SUM);
-		addGlobalAgg(SUM, SUM);
+            @Override
+            public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+                    IMetadataProvider<?, ?> mp) throws AlgebricksException {
+                return BuiltinType.ANY; // TODO
+            }
+        });
+        add(INT8_CONSTRUCTOR, OptionalAInt8TypeComputer.INSTANCE);
+        add(INT16_CONSTRUCTOR, OptionalAInt16TypeComputer.INSTANCE);
+        add(INT32_CONSTRUCTOR, OptionalAInt32TypeComputer.INSTANCE);
+        add(INT64_CONSTRUCTOR, OptionalAInt64TypeComputer.INSTANCE);
+        add(LEN, OptionalAInt32TypeComputer.INSTANCE);
+        add(LIKE, BinaryBooleanOrNullFunctionTypeComputer.INSTANCE);
+        add(LINE_CONSTRUCTOR, OptionalALineTypeComputer.INSTANCE);
+        add(LISTIFY, OrderedListConstructorResultType.INSTANCE);
+        add(LOCAL_AVG, NonTaggedLocalAvgTypeComputer.INSTANCE);
+        add(MAKE_FIELD_INDEX_HANDLE, null); // TODO
+        add(MAKE_FIELD_NAME_HANDLE, null); // TODO
+        add(MAX, NonTaggedSumTypeComputer.INSTANCE);
+        add(MIN, NonTaggedSumTypeComputer.INSTANCE);
+        add(NON_EMPTY_STREAM, ABooleanTypeComputer.INSTANCE);
+        add(NULL_CONSTRUCTOR, ANullTypeComputer.INSTANCE);
+        add(NUMERIC_UNARY_MINUS, NonTaggedUnaryMinusTypeComputer.INSTANCE);
+        add(NUMERIC_SUBTRACT, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
+        add(NUMERIC_MULTIPLY, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
+        add(NUMERIC_DIVIDE, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
+        add(NUMERIC_MOD, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
+        add(NUMERIC_IDIV, AInt32TypeComputer.INSTANCE);
+        add(OPEN_RECORD_CONSTRUCTOR, OpenRecordConstructorResultType.INSTANCE);
+        add(ORDERED_LIST_CONSTRUCTOR, OrderedListConstructorResultType.INSTANCE);
+        add(POINT_CONSTRUCTOR, OptionalAPointTypeComputer.INSTANCE);
+        add(POINT3D_CONSTRUCTOR, OptionalAPoint3DTypeComputer.INSTANCE);
+        add(POLYGON_CONSTRUCTOR, OptionalAPolygonTypeComputer.INSTANCE);
+        add(PREFIX_LEN_JACCARD, AInt32TypeComputer.INSTANCE);
+        add(RANGE, AInt32TypeComputer.INSTANCE);
+        add(RECTANGLE_CONSTRUCTOR, OptionalARectangleTypeComputer.INSTANCE);
+        // add(RECORD_TYPE_CONSTRUCTOR, null);
+        add(SCALAR_AVG, ScalarVersionOfAggregateResultType.INSTANCE);
+        add(SCALAR_COUNT, ScalarVersionOfAggregateResultType.INSTANCE);
+        add(SCALAR_GLOBAL_AVG, ScalarVersionOfAggregateResultType.INSTANCE);
+        add(SCALAR_LOCAL_AVG, ScalarVersionOfAggregateResultType.INSTANCE);
+        add(SCALAR_MAX, ScalarVersionOfAggregateResultType.INSTANCE);
+        add(SCALAR_MIN, ScalarVersionOfAggregateResultType.INSTANCE);
+        add(SCALAR_SUM, ScalarVersionOfAggregateResultType.INSTANCE);
+        add(SCAN_COLLECTION, NonTaggedCollectionMemberResultType.INSTANCE);
+        add(SERIAL_AVG, OptionalADoubleTypeComputer.INSTANCE);
+        add(SERIAL_COUNT, AInt32TypeComputer.INSTANCE);
+        add(SERIAL_GLOBAL_AVG, OptionalADoubleTypeComputer.INSTANCE);
+        add(SERIAL_LOCAL_AVG, NonTaggedLocalAvgTypeComputer.INSTANCE);
+        add(SERIAL_SUM, NonTaggedSumTypeComputer.INSTANCE);
+        add(SIMILARITY_JACCARD, AFloatTypeComputer.INSTANCE);
+        add(SIMILARITY_JACCARD_CHECK, OrderedListOfAnyTypeComputer.INSTANCE);
+        add(SIMILARITY_JACCARD_PREFIX, AFloatTypeComputer.INSTANCE);
+        add(SIMILARITY_JACCARD_PREFIX_CHECK, OrderedListOfAnyTypeComputer.INSTANCE);
+        add(SPATIAL_AREA, ADoubleTypeComputer.INSTANCE);
+        add(SPATIAL_CELL, ARectangleTypeComputer.INSTANCE);
+        add(SPATIAL_DISTANCE, ADoubleTypeComputer.INSTANCE);
+        add(SPATIAL_INTERSECT, ABooleanTypeComputer.INSTANCE);
+        add(STARTS_WITH, ABooleanTypeComputer.INSTANCE);
+        add(STRING_CONSTRUCTOR, OptionalAStringTypeComputer.INSTANCE);
+        add(SUBSET_COLLECTION, new IResultTypeComputer() {
 
-		addAgg(LISTIFY);
+            @Override
+            public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+                    IMetadataProvider<?, ?> mp) throws AlgebricksException {
+                AbstractFunctionCallExpression fun = (AbstractFunctionCallExpression) expression;
+                IAType t;
+                try {
+                    t = (IAType) env.getType(fun.getArguments().get(0).getValue());
+                } catch (AlgebricksException e) {
+                    throw new AlgebricksException(e);
+                }
+                switch (t.getTypeTag()) {
+                    case UNORDEREDLIST:
+                    case ORDEREDLIST: {
+                        AbstractCollectionType act = (AbstractCollectionType) t;
+                        return act.getItemType();
+                    }
+                    case UNION: {
+                        AUnionType ut = (AUnionType) t;
+                        if (!ut.isNullableType()) {
+                            throw new AlgebricksException("Expecting collection type. Found " + t);
+                        }
+                        IAType t2 = ut.getUnionList().get(1);
+                        ATypeTag tag2 = t2.getTypeTag();
+                        if (tag2 == ATypeTag.UNORDEREDLIST || tag2 == ATypeTag.ORDEREDLIST) {
+                            AbstractCollectionType act = (AbstractCollectionType) t2;
+                            return act.getItemType();
+                        }
+                        throw new AlgebricksException("Expecting collection type. Found " + t);
+                    }
+                    default: {
+                        throw new AlgebricksException("Expecting collection type. Found " + t);
+                    }
+                }
+            }
+        });
+        add(SUBSTRING, AStringTypeComputer.INSTANCE);
+        add(SUM, NonTaggedSumTypeComputer.INSTANCE);
+        add(SWITCH_CASE, NonTaggedSwitchCaseComputer.INSTANCE);
+        add(REG_EXP, ABooleanTypeComputer.INSTANCE);
+        add(INJECT_FAILURE, InjectFailureTypeComputer.INSTANCE);
 
-		// serializable aggregate functions
-		addSerialAgg(AVG, SERIAL_AVG);
-		addSerialAgg(COUNT, SERIAL_COUNT);
-		addSerialAgg(SUM, SERIAL_SUM);
-		addSerialAgg(LOCAL_AVG, SERIAL_LOCAL_AVG);
-		addSerialAgg(GLOBAL_AVG, SERIAL_GLOBAL_AVG);
+        add(TID, AInt32TypeComputer.INSTANCE);
+        add(TIME_CONSTRUCTOR, OptionalATimeTypeComputer.INSTANCE);
+        add(TYPE_OF, null); // TODO
+        add(UNORDERED_LIST_CONSTRUCTOR, UnorderedListConstructorResultType.INSTANCE);
+        add(YEAR, OptionalAInt32TypeComputer.INSTANCE);
+        add(WORD_TOKENS, new IResultTypeComputer() {
 
-		addAgg(SERIAL_COUNT);
-		addLocalAgg(SERIAL_COUNT, SERIAL_COUNT);
-		addGlobalAgg(SERIAL_COUNT, SERIAL_SUM);
+            @Override
+            public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+                    IMetadataProvider<?, ?> mp) throws AlgebricksException {
+                return new AOrderedListType(BuiltinType.ASTRING, "string");
+            }
+        });
 
-		addAgg(SERIAL_AVG);
-		addAgg(SERIAL_LOCAL_AVG);
-		addAgg(SERIAL_GLOBAL_AVG);
-		addLocalAgg(SERIAL_AVG, SERIAL_LOCAL_AVG);
-		addGlobalAgg(SERIAL_AVG, SERIAL_GLOBAL_AVG);
+        String metadataFunctionLoaderClassName = "edu.uci.ics.asterix.metadata.functions.MetadataBuiltinFunctions";
+        try {
+            Class.forName(metadataFunctionLoaderClassName);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
 
-		addAgg(SERIAL_SUM);
-		addLocalAgg(SERIAL_SUM, SERIAL_SUM);
-		addGlobalAgg(SERIAL_SUM, SERIAL_SUM);
-	}
+    static {
+        scalarToAggregateFunctionMap.put(getAsterixFunctionInfo(SCALAR_AVG), getAsterixFunctionInfo(AVG));
+        scalarToAggregateFunctionMap.put(getAsterixFunctionInfo(SCALAR_COUNT), getAsterixFunctionInfo(COUNT));
+        scalarToAggregateFunctionMap.put(getAsterixFunctionInfo(SCALAR_GLOBAL_AVG), getAsterixFunctionInfo(GLOBAL_AVG));
+        scalarToAggregateFunctionMap.put(getAsterixFunctionInfo(SCALAR_LOCAL_AVG), getAsterixFunctionInfo(LOCAL_AVG));
+        scalarToAggregateFunctionMap.put(getAsterixFunctionInfo(SCALAR_MAX), getAsterixFunctionInfo(MAX));
+        scalarToAggregateFunctionMap.put(getAsterixFunctionInfo(SCALAR_MIN), getAsterixFunctionInfo(MIN));
+        scalarToAggregateFunctionMap.put(getAsterixFunctionInfo(SCALAR_SUM), getAsterixFunctionInfo(SUM));
+    }
 
-	static {
-		datasetFunctions.add(DATASET);
-		datasetFunctions.add(FEED_INGEST);
-		datasetFunctions.add(INDEX_SEARCH);
-	}
+    static {
+        addAgg(AVG);
+        addAgg(LOCAL_AVG);
+        addAgg(GLOBAL_AVG);
+        addLocalAgg(AVG, LOCAL_AVG);
+        addGlobalAgg(AVG, GLOBAL_AVG);
 
-	static {
-		addUnnestFun(DATASET, false);
-		addUnnestFun(RANGE, true);
-		addUnnestFun(SCAN_COLLECTION, false);
-		addUnnestFun(SUBSET_COLLECTION, false);
-	}
+        addAgg(COUNT);
+        addLocalAgg(COUNT, COUNT);
+        addGlobalAgg(COUNT, SUM);
 
-	public static void addDatasetFunction(FunctionIdentifier fi) {
-		datasetFunctions.add(fi);
-	}
+        addAgg(MAX);
+        addLocalAgg(MAX, MAX);
+        addGlobalAgg(MAX, MAX);
 
-	public static boolean isDatasetFunction(FunctionIdentifier fi) {
-		return datasetFunctions.contains(fi);
-	}
+        addAgg(MIN);
+        addLocalAgg(MIN, MIN);
+        addGlobalAgg(MIN, MIN);
 
-	public static boolean isBuiltinCompilerFunction(FunctionIdentifier fi) {
-		return builtinFunctionsSet.get(fi) != null;
-	}
+        addAgg(SUM);
+        addLocalAgg(SUM, SUM);
+        addGlobalAgg(SUM, SUM);
 
-	public static boolean isBuiltinAggregateFunction(FunctionIdentifier fi) {
-		return builtinAggregateFunctions.contains(fi);
-	}
+        addAgg(LISTIFY);
 
-	public static boolean isBuiltinUnnestingFunction(FunctionIdentifier fi) {
-		return builtinUnnestingFunctions.get(fi) != null;
-	}
+        // serializable aggregate functions
+        addSerialAgg(AVG, SERIAL_AVG);
+        addSerialAgg(COUNT, SERIAL_COUNT);
+        addSerialAgg(SUM, SERIAL_SUM);
+        addSerialAgg(LOCAL_AVG, SERIAL_LOCAL_AVG);
+        addSerialAgg(GLOBAL_AVG, SERIAL_GLOBAL_AVG);
 
-	public static boolean returnsUniqueValues(FunctionIdentifier fi) {
-		Boolean ruv = builtinUnnestingFunctions.get(fi);
-		if (ruv != null && ruv.booleanValue()) {
-			return true;
-		} else {
-			return false;
-		}
-	}
+        addAgg(SERIAL_COUNT);
+        addLocalAgg(SERIAL_COUNT, SERIAL_COUNT);
+        addGlobalAgg(SERIAL_COUNT, SERIAL_SUM);
 
-	public static FunctionIdentifier getLocalAggregateFunction(
-			FunctionIdentifier fi) {
-		return aggregateToLocalAggregate.get(fi);
-	}
+        addAgg(SERIAL_AVG);
+        addAgg(SERIAL_LOCAL_AVG);
+        addAgg(SERIAL_GLOBAL_AVG);
+        addLocalAgg(SERIAL_AVG, SERIAL_LOCAL_AVG);
+        addGlobalAgg(SERIAL_AVG, SERIAL_GLOBAL_AVG);
 
-	public static FunctionIdentifier getGlobalAggregateFunction(
-			FunctionIdentifier fi) {
-		return aggregateToGlobalAggregate.get(fi);
-	}
+        addAgg(SERIAL_SUM);
+        addLocalAgg(SERIAL_SUM, SERIAL_SUM);
+        addGlobalAgg(SERIAL_SUM, SERIAL_SUM);
+    }
 
-	public static FunctionIdentifier getBuiltinFunctionIdentifier(
-			FunctionIdentifier fi) {
-		return builtinFunctionsSet.get(fi);
-	}
+    static {
+        datasetFunctions.add(getAsterixFunctionInfo(DATASET));
+        datasetFunctions.add(getAsterixFunctionInfo(FEED_INGEST));
+        datasetFunctions.add(getAsterixFunctionInfo(INDEX_SEARCH));
+    }
 
-	public static AggregateFunctionCallExpression makeAggregateFunctionExpression(
-			FunctionIdentifier fi, List<Mutable<ILogicalExpression>> args) {
-		IFunctionInfo finfo = FunctionUtils.getFunctionInfo(fi);
-		FunctionIdentifier fiLocal = aggregateToLocalAggregate.get(fi);
-		FunctionIdentifier fiGlobal = aggregateToGlobalAggregate.get(fi);
-		if (fiLocal != null && fiGlobal != null) {
-			AggregateFunctionCallExpression fun = new AggregateFunctionCallExpression(
-					finfo, true, args);
-			fun.setStepTwoAggregate(FunctionUtils.getFunctionInfo(fiGlobal));
-			fun.setStepOneAggregate(FunctionUtils.getFunctionInfo(fiLocal));
-			return fun;
-		} else {
-			return new AggregateFunctionCallExpression(finfo, false, args);
-		}
-	}
+    static {
+        addUnnestFun(DATASET, false);
+        addUnnestFun(RANGE, true);
+        addUnnestFun(SCAN_COLLECTION, false);
+        addUnnestFun(SUBSET_COLLECTION, false);
+    }
 
-	public static boolean isAggregateFunctionSerializable(FunctionIdentifier fi) {
-		return aggregateToSerializableAggregate.get(fi) == null ? false : true;
-	}
+    public static void addDatasetFunction(FunctionIdentifier fi) {
+        datasetFunctions.add(getAsterixFunctionInfo(fi));
+    }
 
-	public static AggregateFunctionCallExpression makeSerializableAggregateFunctionExpression(
-			FunctionIdentifier fi, List<Mutable<ILogicalExpression>> args) {
-		FunctionIdentifier serializableFid = aggregateToSerializableAggregate
-				.get(fi);
-		if (serializableFid == null)
-			throw new IllegalStateException(
-					"no serializable implementation for aggregate function "
-							+ fi);
-		IFunctionInfo finfo = FunctionUtils.getFunctionInfo(serializableFid);
-		FunctionIdentifier fiLocal = aggregateToLocalAggregate
-				.get(serializableFid);
-		FunctionIdentifier fiGlobal = aggregateToGlobalAggregate
-				.get(serializableFid);
+    public static boolean isDatasetFunction(FunctionIdentifier fi) {
+        return datasetFunctions.contains(getAsterixFunctionInfo(fi));
+    }
 
-		if (fiLocal != null && fiGlobal != null) {
-			AggregateFunctionCallExpression fun = new AggregateFunctionCallExpression(
-					finfo, true, args);
-			fun.setStepTwoAggregate(FunctionUtils.getFunctionInfo(fiGlobal));
-			fun.setStepOneAggregate(FunctionUtils.getFunctionInfo(fiLocal));
-			return fun;
-		} else {
-			return new AggregateFunctionCallExpression(finfo, false, args);
-		}
-	}
+    public static boolean isBuiltinCompilerFunction(FunctionIdentifier fi) {
+        return builtinFunctionsSet.keySet().contains(getAsterixFunctionInfo(fi));
+    }
 
-	public static IResultTypeComputer getResultTypeComputer(
-			FunctionIdentifier fi) {
-		return funTypeComputer.get(fi);
-	}
+    public static boolean isBuiltinAggregateFunction(FunctionIdentifier fi) {
+        return builtinAggregateFunctions.contains(getAsterixFunctionInfo(fi));
+    }
 
-	public static FunctionIdentifier getAggregateFunction(
-			FunctionIdentifier scalarVersionOfAggregate) {
-		return scalarToAggregateFunctionMap.get(scalarVersionOfAggregate);
-	}
+    public static boolean isBuiltinUnnestingFunction(FunctionIdentifier fi) {
+        return builtinUnnestingFunctions.get(getAsterixFunctionInfo(fi)) != null;
+    }
 
-	public static void add(FunctionIdentifier fi,
-			IResultTypeComputer typeComputer) {
-		builtinFunctionsSet.put(fi, fi);
-		funTypeComputer.put(fi, typeComputer);
-	}
+    public static boolean returnsUniqueValues(FunctionIdentifier fi) {
+        Boolean ruv = builtinUnnestingFunctions.get(getAsterixFunctionInfo(fi));
+        if (ruv != null && ruv.booleanValue()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
 
-	private static void addAgg(FunctionIdentifier fi) {
-		builtinAggregateFunctions.add(fi);
-	}
+    public static FunctionIdentifier getLocalAggregateFunction(FunctionIdentifier fi) {
+        return aggregateToLocalAggregate.get(getAsterixFunctionInfo(fi)).getFunctionIdentifier();
+    }
 
-	private static void addLocalAgg(FunctionIdentifier fi,
-			FunctionIdentifier localfi) {
-		aggregateToLocalAggregate.put(fi, localfi);
-	}
+    public static FunctionIdentifier getGlobalAggregateFunction(FunctionIdentifier fi) {
+        return aggregateToGlobalAggregate.get(getAsterixFunctionInfo(fi)).getFunctionIdentifier();
+    }
 
-	private static void addGlobalAgg(FunctionIdentifier fi,
-			FunctionIdentifier globalfi) {
-		aggregateToGlobalAggregate.put(fi, globalfi);
-	}
+    public static FunctionIdentifier getBuiltinFunctionIdentifier(FunctionIdentifier fi) {
+        IFunctionInfo finfo = getAsterixFunctionInfo(fi);
+        return finfo == null ? null : finfo.getFunctionIdentifier();
+    }
+    
+    
 
-	public static void addUnnestFun(FunctionIdentifier fi,
-			boolean returnsUniqueValues) {
-		builtinUnnestingFunctions.put(fi, returnsUniqueValues);
-	}
+    public static AggregateFunctionCallExpression makeAggregateFunctionExpression(FunctionIdentifier fi,
+            List<Mutable<ILogicalExpression>> args) {
+        IFunctionInfo finfo = getAsterixFunctionInfo(fi);
+        IFunctionInfo fiLocal = aggregateToLocalAggregate.get(finfo);
+        IFunctionInfo fiGlobal = aggregateToGlobalAggregate.get(finfo);
 
-	private static void addSerialAgg(FunctionIdentifier fi,
-			FunctionIdentifier serialfi) {
-		aggregateToSerializableAggregate.put(fi, serialfi);
-	}
+        if (fiLocal != null && fiGlobal != null) {
+            AggregateFunctionCallExpression fun = new AggregateFunctionCallExpression(finfo, true, args);
+            fun.setStepTwoAggregate(fiGlobal);
+            fun.setStepOneAggregate(fiLocal);
+            return fun;
+        } else {
+            return new AggregateFunctionCallExpression(finfo, false, args);
+        }
+    }
 
-	static {
-		spatialFilterFunctions.put(AsterixBuiltinFunctions.SPATIAL_INTERSECT,
-				SpatialFilterKind.SI);
-	}
+    public static boolean isAggregateFunctionSerializable(FunctionIdentifier fi) {
+        IFunctionInfo finfo = getAsterixFunctionInfo(fi);
+        return aggregateToSerializableAggregate.get(finfo) != null ;
+    }
 
-	public static boolean isSpatialFilterFunction(FunctionIdentifier fi) {
-		return spatialFilterFunctions.get(fi) != null;
-	}
+    public static AggregateFunctionCallExpression makeSerializableAggregateFunctionExpression(FunctionIdentifier fi,
+            List<Mutable<ILogicalExpression>> args) {
+
+        IFunctionInfo finfo = getAsterixFunctionInfo(fi);
+        IFunctionInfo serializableFinfo = aggregateToSerializableAggregate.get(finfo);
+        if (serializableFinfo == null)
+            throw new IllegalStateException("no serializable implementation for aggregate function " + serializableFinfo);
+       
+        IFunctionInfo fiLocal = aggregateToLocalAggregate.get(serializableFinfo);
+        IFunctionInfo fiGlobal = aggregateToGlobalAggregate.get(serializableFinfo);
+
+        if (fiLocal != null && fiGlobal != null) {
+            AggregateFunctionCallExpression fun = new AggregateFunctionCallExpression(serializableFinfo, true, args);
+            fun.setStepTwoAggregate(fiGlobal);
+            fun.setStepOneAggregate(fiLocal);
+            return fun;
+        } else {
+            return new AggregateFunctionCallExpression(serializableFinfo, false, args);
+        }
+    }
+
+    public static IResultTypeComputer getResultTypeComputer(FunctionIdentifier fi) {
+        return funTypeComputer.get(getAsterixFunctionInfo(fi));
+    }
+
+    public static FunctionIdentifier getAggregateFunction(FunctionIdentifier scalarVersionOfAggregate) {
+        IFunctionInfo finfo = scalarToAggregateFunctionMap.get(getAsterixFunctionInfo(scalarVersionOfAggregate));
+        return finfo == null ? null : finfo.getFunctionIdentifier();
+    }
+
+    public static void add(FunctionIdentifier fi, IResultTypeComputer typeComputer) {
+        IFunctionInfo functionInfo = getAsterixFunctionInfo(fi);
+        builtinFunctionsSet.put(functionInfo, functionInfo);
+        funTypeComputer.put(functionInfo, typeComputer);
+        asterixFunctionIdToInfo.put(fi, functionInfo);
+       // AsterixFunction asterixFunction = new AsterixFunction(fi.getName(), fi.getArity());
+    }
+
+    private static void addAgg(FunctionIdentifier fi) {
+        builtinAggregateFunctions.add(getAsterixFunctionInfo(fi));
+    }
+
+    private static void addLocalAgg(FunctionIdentifier fi, FunctionIdentifier localfi) {
+        aggregateToLocalAggregate.put(getAsterixFunctionInfo(fi), getAsterixFunctionInfo(localfi));
+    }
+
+    private static void addGlobalAgg(FunctionIdentifier fi, FunctionIdentifier globalfi) {
+        aggregateToGlobalAggregate.put(getAsterixFunctionInfo(fi), getAsterixFunctionInfo(globalfi));
+    }
+
+    public static void addUnnestFun(FunctionIdentifier fi, boolean returnsUniqueValues) {
+        builtinUnnestingFunctions.put(getAsterixFunctionInfo(fi), returnsUniqueValues);
+    }
+
+    private static void addSerialAgg(FunctionIdentifier fi, FunctionIdentifier serialfi) {
+        aggregateToSerializableAggregate.put(getAsterixFunctionInfo(fi), getAsterixFunctionInfo(serialfi));
+    }
+
+    static {
+        spatialFilterFunctions.put(getAsterixFunctionInfo(AsterixBuiltinFunctions.SPATIAL_INTERSECT),
+                SpatialFilterKind.SI);
+    }
+
+    public static boolean isSpatialFilterFunction(FunctionIdentifier fi) {
+        return spatialFilterFunctions.get(getAsterixFunctionInfo(fi)) != null;
+    }
 
 }
\ No newline at end of file
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixFunction.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixFunction.java
new file mode 100644
index 0000000..23d5d58
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixFunction.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.functions;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+
+public class AsterixFunction {
+
+    private final String functionName;
+    private final int arity;
+    public final static int VARARGS = -1;
+
+    public AsterixFunction(String functionName, int arity) {
+        this.functionName = functionName;
+        this.arity = arity;
+    }
+    
+    public AsterixFunction(FunctionIdentifier fid) {
+        this.functionName = fid.getName();
+        this.arity = fid.getArity();
+    }
+
+    public String getFunctionName() {
+        return functionName;
+    }
+
+    public int getArity() {
+        return arity;
+    }
+
+    public String toString() {
+        return functionName + "@" + arity;
+    }
+
+    @Override
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof AsterixFunction)) {
+            return false;
+        }
+        if (functionName.equals(((AsterixFunction) o).getFunctionName())
+                && (arity == ((AsterixFunction) o).getArity() || arity == VARARGS)) {
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixFunctionInfo.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixFunctionInfo.java
new file mode 100644
index 0000000..c5e4b99
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixFunctionInfo.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2009-2011 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.om.functions;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
+
+public class AsterixFunctionInfo implements IFunctionInfo {
+
+    private final FunctionIdentifier functionIdentifier;
+    
+
+    public AsterixFunctionInfo(String namespace, AsterixFunction asterixFunction, boolean isBuiltin) {
+        this.functionIdentifier = new FunctionIdentifier(namespace, asterixFunction.getFunctionName(),
+                asterixFunction.getArity(), isBuiltin);
+    }
+
+    public AsterixFunctionInfo(FunctionIdentifier functionIdentifier,
+            boolean isBuiltin) {
+        this.functionIdentifier = functionIdentifier;
+    }
+
+    @Override
+    public FunctionIdentifier getFunctionIdentifier() {
+        return functionIdentifier;
+    }
+
+    
+    @Override
+    public Object getInfo() {
+        throw new IllegalStateException();
+    }
+
+    @Override
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof AsterixFunctionInfo)) {
+            return false;
+        }
+        AsterixFunctionInfo info = (AsterixFunctionInfo) o;
+        return functionIdentifier.equals(info.getFunctionIdentifier());
+    }
+
+    @Override
+    public String toString() {
+        return this.functionIdentifier.getNamespace() + ":" + this.functionIdentifier.getName() + "@"
+                + this.functionIdentifier.getArity();
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
index 959a135..1221f7f 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
@@ -11,7 +11,6 @@
 
 import edu.uci.ics.asterix.common.config.GlobalConfig;
 import edu.uci.ics.asterix.common.exceptions.AsterixRuntimeException;
-import edu.uci.ics.asterix.common.functions.FunctionUtils;
 import edu.uci.ics.asterix.common.parse.IParseFileSplitsDecl;
 import edu.uci.ics.asterix.dataflow.data.nontagged.AqlNullWriterFactory;
 import edu.uci.ics.asterix.formats.base.IDataFormat;
@@ -363,8 +362,8 @@
                 } catch (HyracksDataException e) {
                     throw new AlgebricksException(e);
                 }
-                IEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs.getBytes(),
-                        abvs.getLength()));
+                IEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs.getBytes(), abvs
+                        .getLength()));
                 IEvaluatorFactory evalFactory = new FieldAccessByIndexEvalFactory(recordEvalFactory,
                         fldIndexEvalFactory, recType);
                 return evalFactory;
@@ -389,8 +388,8 @@
         } catch (HyracksDataException e) {
             throw new AlgebricksException(e);
         }
-        IEvaluatorFactory dimensionEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs1.getBytes(),
-                abvs1.getLength()));
+        IEvaluatorFactory dimensionEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs1.getBytes(), abvs1
+                .getLength()));
 
         for (int i = 0; i < numOfFields; i++) {
             ArrayBackedValueStorage abvs2 = new ArrayBackedValueStorage();
@@ -401,8 +400,8 @@
             } catch (HyracksDataException e) {
                 throw new AlgebricksException(e);
             }
-            IEvaluatorFactory coordinateEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs2.getBytes(),
-                    abvs2.getLength()));
+            IEvaluatorFactory coordinateEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs2.getBytes(), abvs2
+                    .getLength()));
 
             evalFactories[i] = new CreateMBREvalFactory(evalFactory, dimensionEvalFactory, coordinateEvalFactory);
         }
@@ -428,15 +427,17 @@
                 } catch (HyracksDataException e) {
                     throw new AlgebricksException(e);
                 }
-                IEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs.getBytes(),
-                        abvs.getLength()));
+                IEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(Arrays.copyOf(abvs.getBytes(), abvs
+                        .getLength()));
                 IEvaluatorFactory evalFactory = new FieldAccessByIndexEvalFactory(recordEvalFactory,
                         fldIndexEvalFactory, recType);
-                IFunctionInfo finfoAccess = FunctionUtils
-                        .getFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX);
+                IFunctionInfo finfoAccess = AsterixBuiltinFunctions
+                        .getAsterixFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX);
+
                 ScalarFunctionCallExpression partitionFun = new ScalarFunctionCallExpression(finfoAccess,
                         new MutableObject<ILogicalExpression>(new VariableReferenceExpression(METADATA_DUMMY_VAR)),
-                        new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(new AInt32(i)))));
+                        new MutableObject<ILogicalExpression>(new ConstantExpression(new AsterixConstantValue(
+                                new AInt32(i)))));
                 return new Triple<IEvaluatorFactory, ScalarFunctionCallExpression, IAType>(evalFactory, partitionFun,
                         recType.getFieldTypes()[i]);
             }
@@ -470,8 +471,8 @@
         }
         if (fd.getIdentifier().equals(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR)) {
             ARecordType rt = (ARecordType) context.getType(expr);
-            ((OpenRecordConstructorDescriptor) fd).reset(rt,
-                    computeOpenFields((AbstractFunctionCallExpression) expr, rt));
+            ((OpenRecordConstructorDescriptor) fd).reset(rt, computeOpenFields((AbstractFunctionCallExpression) expr,
+                    rt));
         }
         if (fd.getIdentifier().equals(AsterixBuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR)) {
             ((ClosedRecordConstructorDescriptor) fd).reset((ARecordType) context.getType(expr));