Added asterix project

git-svn-id: https://asterixdb.googlecode.com/svn/trunk/asterix@12 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-aql/pom.xml b/asterix-aql/pom.xml
new file mode 100644
index 0000000..a4d7f8c
--- /dev/null
+++ b/asterix-aql/pom.xml
@@ -0,0 +1,76 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>asterix</artifactId>
+		<groupId>edu.uci.ics.asterix</groupId>
+		<version>0.0.4-SNAPSHOT</version>
+	</parent>
+	<groupId>edu.uci.ics.asterix</groupId>
+	<artifactId>asterix-aql</artifactId>
+	<version>0.0.4-SNAPSHOT</version>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.0.2</version>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>javacc-maven-plugin</artifactId>
+				<version>2.6</version>
+				<executions>
+					<execution>
+						<id>javacc</id>
+						<goals>
+							<goal>javacc</goal>
+						</goals>
+						<configuration>
+							<isStatic>false</isStatic>
+						</configuration>
+					</execution>
+					<execution>
+						<id>javacc-jjdoc</id>
+						<goals>
+							<goal>jjdoc</goal>
+						</goals>
+                        <phase>process-sources</phase>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>edu.uci.ics.asterix</groupId>
+			<artifactId>asterix-common</artifactId>
+			<version>0.0.4-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>edu.uci.ics.asterix</groupId>
+			<artifactId>asterix-om</artifactId>
+			<version>0.0.4-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>edu.uci.ics.asterix</groupId>
+			<artifactId>asterix-metadata</artifactId>
+			<version>0.0.4-SNAPSHOT</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>edu.uci.ics.fuzzyjoin</groupId>
+			<artifactId>fuzzyjoin-core</artifactId>
+			<version>0.0.3</version>
+			<scope>compile</scope>
+		</dependency>
+	</dependencies>
+
+</project>
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Clause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Clause.java
new file mode 100644
index 0000000..8be2d40
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Clause.java
@@ -0,0 +1,18 @@
+package edu.uci.ics.asterix.aql.base;
+
+public interface Clause extends IAqlExpression {
+    public ClauseType getClauseType();
+
+    public enum ClauseType {
+        FOR_CLAUSE,
+        LET_CLAUSE,
+        WHERE_CLAUSE,
+        ORDER_BY_CLAUSE,
+        LIMIT_CLAUSE,
+        DIE_CLAUSE,
+        GROUP_BY_CLAUSE,
+        DISTINCT_BY_CLAUSE,
+        UPDATE_CLAUSE
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Expression.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Expression.java
new file mode 100644
index 0000000..d45a500
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Expression.java
@@ -0,0 +1,24 @@
+package edu.uci.ics.asterix.aql.base;
+
+public interface Expression extends IAqlExpression {
+    public abstract Kind getKind();
+
+    public enum Kind {
+        LITERAL_EXPRESSION,
+        FLWOGR_EXPRESSION,
+        IF_EXPRESSION,
+        QUANTIFIED_EXPRESSION,
+        // PARENTHESIZED_EXPRESSION,
+        LIST_CONSTRUCTOR_EXPRESSION,
+        RECORD_CONSTRUCTOR_EXPRESSION,
+        VARIABLE_EXPRESSION,
+        METAVARIABLE_EXPRESSION,
+        CALL_EXPRESSION,
+        OP_EXPRESSION,
+        FIELD_ACCESSOR_EXPRESSION,
+        INDEX_ACCESSOR_EXPRESSION,
+        UNARY_EXPRESSION,
+        UNION_EXPRESSION
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/IAqlExpression.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/IAqlExpression.java
new file mode 100644
index 0000000..c92b1ec
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/IAqlExpression.java
@@ -0,0 +1,11 @@
+package edu.uci.ics.asterix.aql.base;
+
+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;
+
+public interface IAqlExpression {
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException;
+
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException;
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/ILiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/ILiteral.java
new file mode 100644
index 0000000..31cb27e
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/ILiteral.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2009-2010 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.aql.base;
+
+import java.io.Serializable;
+
+public interface ILiteral extends Serializable {
+    public enum Type {
+        STRING,
+        INTEGER,
+        NULL,
+        TRUE,
+        FALSE,
+        FLOAT,
+        DOUBLE
+    }
+
+    public Type getLiteralType();
+
+    public String getStringValue();
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Statement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Statement.java
new file mode 100644
index 0000000..03baabe
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/base/Statement.java
@@ -0,0 +1,35 @@
+package edu.uci.ics.asterix.aql.base;
+
+public interface Statement extends IAqlExpression {
+    public enum Kind {
+        DATASET_DECL,
+        DATAVERSE_DECL,
+        DATAVERSE_DROP,
+        DATASET_DROP,
+        DELETE,
+        INSERT,
+        UPDATE,
+        DML_CMD_LIST,
+        FUNCTION_DECL,
+        LOAD_FROM_FILE,
+        WRITE_FROM_QUERY_RESULT,
+        NODEGROUP_DECL,
+        NODEGROUP_DROP,
+        QUERY,
+        SET,
+        TYPE_DECL,
+        TYPE_DROP,
+        WRITE,
+        CREATE_INDEX,
+        INDEX_DECL,
+        CREATE_DATAVERSE,
+        INDEX_DROP,
+        BEGIN_FEED,
+        CONTROL_FEED,
+        CREATE_FUNCTION,
+        FUNCTION_DROP
+    }
+
+    public abstract Kind getKind();
+
+}
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
new file mode 100644
index 0000000..e082fee
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/FunctionExpressionMap.java
@@ -0,0 +1,42 @@
+package edu.uci.ics.asterix.aql.context;
+
+import java.util.HashMap;
+
+import edu.uci.ics.asterix.aql.expression.FunIdentifier;
+
+public class FunctionExpressionMap extends HashMap<Integer, FunIdentifier> {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+    private boolean varargs;
+
+    public boolean isVarargs() {
+        return varargs;
+    }
+
+    public void setVarargs(boolean varargs) {
+        this.varargs = varargs;
+    }
+
+    public FunctionExpressionMap(boolean varargs) {
+        super();
+        this.varargs = varargs;
+    }
+
+    public FunIdentifier get(int arity) {
+        if (varargs) {
+            return super.get(-1);
+        } else {
+            return super.get(arity);
+        }
+    }
+
+    public FunIdentifier put(int arity, FunIdentifier fd) {
+        if (varargs) {
+            return super.put(-1, fd);
+        } else {
+            return super.put(arity, fd);
+        }
+    }
+}
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
new file mode 100644
index 0000000..fa3e8fc
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/FunctionSignatures.java
@@ -0,0 +1,33 @@
+package edu.uci.ics.asterix.aql.context;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import edu.uci.ics.asterix.aql.expression.FunIdentifier;
+
+public class FunctionSignatures {
+    private final Map<String, FunctionExpressionMap> functionMap;
+
+    public FunctionSignatures() {
+        functionMap = new HashMap<String, FunctionExpressionMap>();
+    }
+
+    public FunIdentifier get(String name, int arity) {
+        FunctionExpressionMap possibleFD = functionMap.get(name);
+        if (possibleFD == null) {
+            return null;
+        } else {
+            return possibleFD.get(arity);
+        }
+    }
+
+    public void put(FunIdentifier fd, boolean varargs) {
+        String name = fd.getValue();
+        FunctionExpressionMap func = functionMap.get(name);
+        if (func == null) {
+            func = new FunctionExpressionMap(varargs);
+            functionMap.put(name, func);
+        }
+        func.put(fd.getArity(), fd);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/RootScopeFactory.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/RootScopeFactory.java
new file mode 100644
index 0000000..dc4f36c
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/RootScopeFactory.java
@@ -0,0 +1,12 @@
+package edu.uci.ics.asterix.aql.context;
+
+import edu.uci.ics.asterix.aql.parser.ScopeChecker;
+
+public class RootScopeFactory {
+
+    public static Scope createRootScope(ScopeChecker sc) {
+        Scope rootScope = new Scope(sc);
+        return rootScope;
+    }
+
+}
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
new file mode 100644
index 0000000..3f9c2be
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/context/Scope.java
@@ -0,0 +1,108 @@
+package edu.uci.ics.asterix.aql.context;
+
+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;
+
+public final class Scope {
+    private Scope parent;
+    private HashMap<String, Identifier> symbols = null;
+    private FunctionSignatures functionSignatures = null;
+    private final ScopeChecker scopeChecker;
+    private boolean maskParentScope = false;
+
+    public Scope(ScopeChecker scopeChecker, Scope parent) {
+        this.scopeChecker = scopeChecker;
+        this.parent = parent;
+    }
+
+    public Scope(ScopeChecker scopeChecker) {
+        this(scopeChecker, null);
+    }
+
+    public Scope(ScopeChecker scopeChecker, Scope parent, boolean maskParentScope) {
+        this(scopeChecker, parent);
+        this.maskParentScope = maskParentScope;
+    }
+
+    /**
+     * Find a symbol in the scope
+     * 
+     * @param name
+     * @return the Identifier of this symbol; otherwise null;
+     */
+    public Identifier findSymbol(String name) {
+        Identifier ident = null;
+        if (symbols != null) {
+            ident = symbols.get(name);
+        }
+        if (ident == null && !maskParentScope && parent != null) {
+            ident = parent.findSymbol(name);
+        }
+        return ident;
+    }
+
+    public Identifier findLocalSymbol(String name) {
+        if (symbols != null) {
+            return symbols.get(name);
+        }
+        return null;
+    }
+
+    /**
+     * Add a symbol into scope
+     * 
+     * @param ident
+     */
+    public void addSymbolToScope(Identifier ident) {
+        if (symbols == null) {
+            symbols = new HashMap<String, Identifier>();
+        }
+        symbols.put(ident.getValue(), ident);
+    }
+
+    public void addNewVarSymbolToScope(VarIdentifier ident) {
+        scopeChecker.incVarCounter();
+        ident.setId(scopeChecker.getVarCounter());
+        addSymbolToScope(ident);
+    }
+
+    /**
+     * Add a FunctionDescriptor into functionSignatures
+     * 
+     * @param fd
+     *            FunctionDescriptor
+     * @param varargs
+     *            whether this function has varargs
+     */
+    public void addFunctionDescriptor(FunIdentifier fd, boolean varargs) {
+        if (functionSignatures == null) {
+            functionSignatures = new FunctionSignatures();
+        }
+        functionSignatures.put(fd, varargs);
+    }
+
+    /**
+     * find a function signature
+     * 
+     * @param name
+     *            name of the function
+     * @param arity
+     *            # of arguments
+     * @return FunctionDescriptor of the function found; otherwise null
+     */
+    public FunIdentifier findFunctionSignature(String name, int arity) {
+        FunIdentifier fd = null;
+        if (functionSignatures != null) {
+            fd = functionSignatures.get(name, arity);
+        }
+        if (fd == null && parent != null) {
+            fd = parent.findFunctionSignature(name, arity);
+        }
+        return fd;
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/AbstractAccessor.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/AbstractAccessor.java
new file mode 100644
index 0000000..1d31800
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/AbstractAccessor.java
@@ -0,0 +1,21 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+
+public abstract class AbstractAccessor implements Expression {
+    protected Expression expr;
+
+    public AbstractAccessor(Expression expr) {
+        super();
+        this.expr = expr;
+    }
+
+    public Expression getExpr() {
+        return expr;
+    }
+
+    public void setExpr(Expression expr) {
+        this.expr = expr;
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/AdmSplitInfo.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/AdmSplitInfo.java
new file mode 100644
index 0000000..fdca8b4
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/AdmSplitInfo.java
@@ -0,0 +1,19 @@
+/**
+ * 
+ */
+package edu.uci.ics.asterix.aql.expression;
+
+public class AdmSplitInfo {
+    public Identifier nodeName;
+    public String fileName;
+
+    public AdmSplitInfo(Identifier nodeName, String fileName) {
+        this.nodeName = nodeName;
+        this.fileName = fileName;
+    }
+
+    @Override
+    public String toString() {
+        return nodeName.value + ":" + fileName;
+    }
+}
\ No newline at end of file
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/BeginFeedStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/BeginFeedStatement.java
new file mode 100644
index 0000000..a142534
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/BeginFeedStatement.java
@@ -0,0 +1,72 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.io.StringReader;
+
+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.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.FeedDatasetDetails;
+
+public class BeginFeedStatement implements Statement {
+
+    private Identifier datasetName;
+    private Query query;
+    private int varCounter;
+
+    public BeginFeedStatement(Identifier datasetName, int varCounter) {
+        this.datasetName = datasetName;
+        this.varCounter = varCounter;
+    }
+    
+    public void initialize(FeedDatasetDetails feedDetails){
+        query = new Query();
+        String functionName = feedDetails.getFunctionIdentifier();
+        String stmt;
+        if(functionName == null){
+         stmt = "insert into dataset " + datasetName + " (" + " for $x in feed-ingest ('" + datasetName + "')"
+                + " return $x" + " );";
+        } else {
+           stmt = "insert into dataset " + datasetName + " (" + " for $x in feed-ingest ('" + datasetName + "')"
+           + " return " + functionName + "(" + "$x" + ")" + ");";
+        }
+        AQLParser parser = new AQLParser(new StringReader(stmt));
+        try {
+            query = (Query) parser.Statement();
+        } catch (ParseException pe) {
+            throw new RuntimeException(pe);
+        }
+
+        query = ((InsertStatement) query.getPrologDeclList().get(0)).getQuery();
+    }
+
+    public Identifier getDatasetName() {
+        return datasetName;
+    }
+
+    public Query getQuery() {
+        return query;
+    }
+
+    public int getVarCounter() {
+        return varCounter;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.BEGIN_FEED;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitBeginFeedStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
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
new file mode 100644
index 0000000..39a21e3
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CallExpr.java
@@ -0,0 +1,61 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class CallExpr implements Expression {
+    private FunIdentifier ident;
+    private List<Expression> exprList;
+    private boolean isBuiltin;
+
+    public CallExpr() {
+    }
+
+    public CallExpr(FunIdentifier ident, List<Expression> exprList) {
+        this.ident = ident;
+        this.exprList = exprList;
+    }
+
+    public FunIdentifier getIdent() {
+        return ident;
+    }
+
+    public void setIdent(FunIdentifier ident) {
+        this.ident = ident;
+    }
+
+    public List<Expression> getExprList() {
+        return exprList;
+    }
+
+    public void setExprList(List<Expression> exprList) {
+        this.exprList = exprList;
+    }
+
+    public boolean isBuiltin() {
+        return isBuiltin;
+    }
+
+    public void setIsBuiltin(boolean builtin) {
+        this.isBuiltin = builtin;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.CALL_EXPRESSION;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitCallExpr(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ConstructorType.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ConstructorType.java
new file mode 100644
index 0000000..b1d6d5a
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ConstructorType.java
@@ -0,0 +1,7 @@
+package edu.uci.ics.asterix.aql.expression;
+
+public enum ConstructorType {
+    ORDERED_LIST_CONSTRUCTOR,
+    UNORDERED_LIST_CONSTRUCTOR,
+    RECORD_CONSTRUCTOR,
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ControlFeedStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ControlFeedStatement.java
new file mode 100644
index 0000000..844fec6
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ControlFeedStatement.java
@@ -0,0 +1,68 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.Map;
+
+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.common.exceptions.AsterixException;
+
+public class ControlFeedStatement implements Statement {
+
+    private Identifier datasetName;
+
+    public enum OperationType {
+        BEGIN,
+        SUSPEND,
+        RESUME,
+        END,
+        ALTER
+    }
+
+    private OperationType operationType;
+    private Map<String, String> alterAdapterConfParams;
+
+    public ControlFeedStatement(OperationType operation, Identifier datasetName) {
+        this.operationType = operation;
+        this.datasetName = datasetName;
+    }
+
+    public ControlFeedStatement(OperationType operation, Identifier datasetName,
+            Map<String, String> alterAdapterConfParams) {
+        this.operationType = operation;
+        this.datasetName = datasetName;
+        this.alterAdapterConfParams = alterAdapterConfParams;
+    }
+    
+    public Identifier getDatasetName() {
+        return datasetName;
+    }
+
+    public OperationType getOperationType() {
+        return operationType;
+    }
+
+    public void setOperation(OperationType operationType) {
+        this.operationType = operationType;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.CONTROL_FEED;
+    }
+
+    public Map<String, String> getAlterAdapterConfParams() {
+        return alterAdapterConfParams;
+    }
+    
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitControlFeedStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CreateDataverseStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CreateDataverseStatement.java
new file mode 100644
index 0000000..c202e5b
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CreateDataverseStatement.java
@@ -0,0 +1,51 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class CreateDataverseStatement implements Statement {
+
+    private Identifier dataverseName;
+    private String format;
+    private boolean ifNotExists;
+
+    public CreateDataverseStatement(Identifier dataverseName, String format, boolean ifNotExists) {
+        this.dataverseName = dataverseName;
+        if (format == null)
+            this.format = "edu.uci.ics.asterix.runtime.formats.NonTaggedDataFormat";
+        else
+            this.format = format;
+        this.ifNotExists = ifNotExists;
+    }
+
+    public Identifier getDataverseName() {
+        return dataverseName;
+    }
+
+    public String getFormat() {
+        return format;
+    }
+
+    public boolean getIfNotExists() {
+        return this.ifNotExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.CREATE_DATAVERSE;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
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
new file mode 100644
index 0000000..e18200f
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CreateFunctionStatement.java
@@ -0,0 +1,79 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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;
+
+public class CreateFunctionStatement implements Statement {
+
+    private FunIdentifier funIdentifier;
+    private String functionBody;
+    private boolean ifNotExists;
+    private List<String> paramList;
+
+    public FunIdentifier getFunctionIdentifier() {
+        return funIdentifier;
+    }
+
+    public void setFunctionIdentifier(FunIdentifier funIdentifier) {
+        this.funIdentifier = funIdentifier;
+    }
+
+    public String getFunctionBody() {
+        return functionBody;
+    }
+
+    public void setFunctionBody(String functionBody) {
+        this.functionBody = functionBody;
+    }
+
+    public void setIfNotExists(boolean ifNotExists) {
+        this.ifNotExists = ifNotExists;
+    }
+
+    public CreateFunctionStatement(FunIdentifier funIdentifier, List<VarIdentifier> parameterList, String functionBody,
+            boolean ifNotExists) {
+        
+        this.funIdentifier = funIdentifier;
+        this.functionBody = functionBody;
+        this.ifNotExists = ifNotExists;
+        this.paramList = new ArrayList<String>();
+        for (VarIdentifier varId : parameterList) {
+            this.paramList.add(varId.getValue());
+        }
+    }
+
+    public boolean getIfNotExists() {
+        return this.ifNotExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.CREATE_FUNCTION;
+    }
+
+    public List<String> getParamList() {
+        return paramList;
+    }
+
+    public void setParamList(List<String> paramList) {
+        this.paramList = paramList;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visit(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CreateIndexStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CreateIndexStatement.java
new file mode 100644
index 0000000..399092e
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/CreateIndexStatement.java
@@ -0,0 +1,87 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.config.DatasetConfig.IndexType;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+
+public class CreateIndexStatement implements Statement {
+
+    private Identifier indexName;
+    private boolean needToCreate = true;
+    private Identifier datasetName;
+    private List<String> fieldExprs = new ArrayList<String>();
+    private IndexType indexType = IndexType.BTREE;
+    private boolean ifNotExists;
+
+    public CreateIndexStatement() {
+    }
+
+    public void setNeedToCreate(boolean needToCreate) {
+        this.needToCreate = needToCreate;
+    }
+
+    public boolean getNeedToCreate() {
+        return needToCreate;
+    }
+
+    public Identifier getIndexName() {
+        return indexName;
+    }
+
+    public void setIndexName(Identifier indexName) {
+        this.indexName = indexName;
+    }
+
+    public Identifier getDatasetName() {
+        return datasetName;
+    }
+
+    public void setDatasetName(Identifier datasetName) {
+        this.datasetName = datasetName;
+    }
+
+    public List<String> getFieldExprs() {
+        return fieldExprs;
+    }
+
+    public void addFieldExpr(String fe) {
+        this.fieldExprs.add(fe);
+    }
+
+    public IndexType getIndexType() {
+        return indexType;
+    }
+
+    public void setIndexType(IndexType indexType) {
+        this.indexType = indexType;
+    }
+
+    public void setIfNotExists(boolean ifNotExists) {
+        this.ifNotExists = ifNotExists;
+    }
+
+    public boolean getIfNotExists() {
+        return this.ifNotExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.CREATE_INDEX;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitCreateIndexStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DatasetDecl.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DatasetDecl.java
new file mode 100644
index 0000000..7996062
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DatasetDecl.java
@@ -0,0 +1,88 @@
+/*
+ * 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.aql.expression;
+
+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.common.config.DatasetConfig.DatasetType;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+
+public class DatasetDecl implements Statement {
+    protected Identifier name;
+    protected Identifier itemTypeName;
+    protected DatasetType datasetType;
+    protected IDatasetDetailsDecl datasetDetailsDecl;
+
+    public boolean ifNotExists;
+
+    public DatasetDecl(Identifier name, Identifier itemTypeName, IDatasetDetailsDecl idd, boolean ifNotExists) {
+        this.name = name;
+        this.itemTypeName = itemTypeName;
+        this.ifNotExists = ifNotExists;
+        datasetDetailsDecl = idd;
+    }
+
+    public boolean getIfNotExists() {
+        return this.ifNotExists;
+    }
+
+    public void setDatasetType(DatasetType datasetType) {
+        this.datasetType = datasetType;
+    }
+
+    public DatasetType getDatasetType() {
+        return datasetType;
+    }
+
+    public Identifier getName() {
+        return name;
+    }
+
+    public void setName(Identifier name) {
+        this.name = name;
+    }
+
+    public Identifier getItemTypeName() {
+        return itemTypeName;
+    }
+
+    public void setItemTypeName(Identifier itemTypeName) {
+        this.itemTypeName = itemTypeName;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitDatasetDecl(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.DATASET_DECL;
+    }
+
+    public IDatasetDetailsDecl getDatasetDetailsDecl() {
+        return datasetDetailsDecl;
+    }
+
+    public void setDatasetDetailsDecl(IDatasetDetailsDecl datasetDetailsDecl) {
+        this.datasetDetailsDecl = datasetDetailsDecl;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DataverseDecl.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DataverseDecl.java
new file mode 100644
index 0000000..c0b33d1
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DataverseDecl.java
@@ -0,0 +1,36 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class DataverseDecl implements Statement {
+
+    private Identifier dataverseName;
+
+    public DataverseDecl(Identifier dataverseName) {
+        this.dataverseName = dataverseName;
+    }
+
+    public Identifier getDataverseName() {
+        return dataverseName;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.DATAVERSE_DECL;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        // TODO
+        return null;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DataverseDropStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DataverseDropStatement.java
new file mode 100644
index 0000000..e95b045
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DataverseDropStatement.java
@@ -0,0 +1,41 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class DataverseDropStatement implements Statement {
+
+    private Identifier dataverseName;
+    private boolean ifExists;
+
+    public DataverseDropStatement(Identifier dataverseName, boolean ifExists) {
+        this.dataverseName = dataverseName;
+        this.ifExists = ifExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.DATAVERSE_DROP;
+    }
+
+    public Identifier getDataverseName() {
+        return dataverseName;
+    }
+
+    public boolean getIfExists() {
+        return ifExists;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitDataverseDropStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DeleteStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DeleteStatement.java
new file mode 100644
index 0000000..9d957cf
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DeleteStatement.java
@@ -0,0 +1,62 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+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.common.exceptions.AsterixException;
+
+public class DeleteStatement implements Statement {
+
+    private VariableExpr vars;
+    private Identifier datasetName;
+    private Expression condition;
+    private Clause dieClause;
+    private int varCounter;
+
+    public DeleteStatement(VariableExpr vars, Identifier datasetName, Expression condition, Clause dieClause,
+            int varCounter) {
+        this.vars = vars;
+        this.datasetName = datasetName;
+        this.condition = condition;
+        this.dieClause = dieClause;
+        this.varCounter = varCounter;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.DELETE;
+    }
+
+    public VariableExpr getVariableExpr() {
+        return vars;
+    }
+
+    public Identifier getDatasetName() {
+        return datasetName;
+    }
+
+    public Expression getCondition() {
+        return condition;
+    }
+
+    public Clause getDieClause() {
+        return dieClause;
+    }
+
+    public int getVarCounter() {
+        return varCounter;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitDeleteStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DieClause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DieClause.java
new file mode 100644
index 0000000..3a77d58
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DieClause.java
@@ -0,0 +1,41 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class DieClause implements Clause {
+    private Expression expr;
+
+    public DieClause() {
+    }
+
+    public DieClause(Expression dieexpr) {
+        this.expr = dieexpr;
+    }
+
+    public Expression getDieExpr() {
+        return expr;
+    }
+
+    public void setDieExpr(Expression dieexpr) {
+        this.expr = dieexpr;
+    }
+
+    @Override
+    public ClauseType getClauseType() {
+        return ClauseType.DIE_CLAUSE;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitDieClause(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DistinctClause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DistinctClause.java
new file mode 100644
index 0000000..c60ad0f
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DistinctClause.java
@@ -0,0 +1,38 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class DistinctClause implements Clause {
+
+    private List<Expression> distinctByExprs;
+
+    public DistinctClause(List<Expression> distinctByExpr) {
+        this.distinctByExprs = distinctByExpr;
+    }
+
+    public List<Expression> getDistinctByExpr() {
+        return distinctByExprs;
+    }
+
+    @Override
+    public ClauseType getClauseType() {
+        return ClauseType.DISTINCT_BY_CLAUSE;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitDistinctClause(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DropStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DropStatement.java
new file mode 100644
index 0000000..9ddec0e
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/DropStatement.java
@@ -0,0 +1,41 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class DropStatement implements Statement {
+
+    private Identifier datasetName;
+    private boolean ifExists;
+
+    public DropStatement(Identifier datasetName, boolean ifExists) {
+        this.datasetName = datasetName;
+        this.ifExists = ifExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.DATASET_DROP;
+    }
+
+    public Identifier getDatasetName() {
+        return datasetName;
+    }
+
+    public boolean getIfExists() {
+        return ifExists;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitDropStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ExternalDetailsDecl.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ExternalDetailsDecl.java
new file mode 100644
index 0000000..c17d893
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ExternalDetailsDecl.java
@@ -0,0 +1,24 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.Map;
+
+public class ExternalDetailsDecl implements IDatasetDetailsDecl {
+    private Map<String, String> properties;
+    private String adapter;
+
+    public void setAdapter(String adapter) {
+        this.adapter = adapter;
+    }
+
+    public void setProperties(Map<String, String> properties) {
+        this.properties = properties;
+    }
+
+    public String getAdapter() {
+        return adapter;
+    }
+
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FLWOGRExpression.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FLWOGRExpression.java
new file mode 100644
index 0000000..85998d7
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FLWOGRExpression.java
@@ -0,0 +1,66 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Clause.ClauseType;
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class FLWOGRExpression implements Expression {
+    private List<Clause> clauseList;
+    private Expression returnExpr;
+
+    public FLWOGRExpression() {
+        super();
+    }
+
+    public FLWOGRExpression(List<Clause> clauseList, Expression returnExpr) {
+        super();
+        this.clauseList = clauseList;
+        this.returnExpr = returnExpr;
+    }
+
+    public List<Clause> getClauseList() {
+        return clauseList;
+    }
+
+    public void setClauseList(List<Clause> clauseList) {
+        this.clauseList = clauseList;
+    }
+
+    public Expression getReturnExpr() {
+        return returnExpr;
+    }
+
+    public void setReturnExpr(Expression returnExpr) {
+        this.returnExpr = returnExpr;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.FLWOGR_EXPRESSION;
+    }
+
+    public boolean noForClause() {
+        for (Clause c : clauseList) {
+            if (c.getClauseType() == ClauseType.FOR_CLAUSE) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitFlworExpression(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FeedDetailsDecl.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FeedDetailsDecl.java
new file mode 100644
index 0000000..cb32ac6
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FeedDetailsDecl.java
@@ -0,0 +1,47 @@
+/*
+ * 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.aql.expression;
+
+import java.util.Map;
+
+public class FeedDetailsDecl extends InternalDetailsDecl {
+    private Map<String, String> properties;
+    private String adapterClassname;
+    private String functionIdentifier;
+
+    public void setFunctionIdentifier(String functionIdentifier) {
+        this.functionIdentifier = functionIdentifier;
+    }
+
+    public void setAdapterClassname(String adapter) {
+        this.adapterClassname = adapter;
+    }
+
+    public void setProperties(Map<String, String> properties) {
+        this.properties = properties;
+    }
+
+    public String getAdapterClassname() {
+        return adapterClassname;
+    }
+
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
+    public String getFunctionIdentifier() {
+        return functionIdentifier;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FieldAccessor.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FieldAccessor.java
new file mode 100644
index 0000000..26f948e
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FieldAccessor.java
@@ -0,0 +1,39 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class FieldAccessor extends AbstractAccessor {
+    private Identifier ident;
+
+    public FieldAccessor(Expression expr, Identifier ident) {
+        super(expr);
+        this.ident = ident;
+    }
+
+    public Identifier getIdent() {
+        return ident;
+    }
+
+    public void setIdent(Identifier ident) {
+        this.ident = ident;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.FIELD_ACCESSOR_EXPRESSION;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitFieldAccessor(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FieldBinding.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FieldBinding.java
new file mode 100644
index 0000000..84563be
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FieldBinding.java
@@ -0,0 +1,34 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+
+public class FieldBinding {
+    private Expression leftExpr;
+    private Expression rightExpr;
+
+    public FieldBinding() {
+    }
+
+    public FieldBinding(Expression leftExpr, Expression rightExpr) {
+        super();
+        this.leftExpr = leftExpr;
+        this.rightExpr = rightExpr;
+    }
+
+    public Expression getLeftExpr() {
+        return leftExpr;
+    }
+
+    public void setLeftExpr(Expression leftExpr) {
+        this.leftExpr = leftExpr;
+    }
+
+    public Expression getRightExpr() {
+        return rightExpr;
+    }
+
+    public void setRightExpr(Expression rightExpr) {
+        this.rightExpr = rightExpr;
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ForClause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ForClause.java
new file mode 100644
index 0000000..d9feaa42
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ForClause.java
@@ -0,0 +1,62 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class ForClause implements Clause {
+    private VariableExpr varExpr;
+    private VariableExpr posExpr;
+    private Expression inExpr;
+
+    public ForClause() {
+        super();
+    }
+
+    public ForClause(VariableExpr varExpr, Expression inExpr) {
+        super();
+        this.varExpr = varExpr;
+        this.inExpr = inExpr;
+    }
+
+    public VariableExpr getVarExpr() {
+        return varExpr;
+    }
+
+    public void setVarExpr(VariableExpr varExpr) {
+        this.varExpr = varExpr;
+    }
+
+    public Expression getInExpr() {
+        return inExpr;
+    }
+
+    public void setInExpr(Expression inExpr) {
+        this.inExpr = inExpr;
+    }
+
+    @Override
+    public ClauseType getClauseType() {
+        return ClauseType.FOR_CLAUSE;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitForClause(this, arg);
+    }
+
+    public void setPosExpr(VariableExpr posExpr) {
+        this.posExpr = posExpr;
+    }
+
+    public VariableExpr getPosVarExpr() {
+        return posExpr;
+    }
+}
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
new file mode 100644
index 0000000..85651fe
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunIdentifier.java
@@ -0,0 +1,40 @@
+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
new file mode 100644
index 0000000..1428a54
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunctionDecl.java
@@ -0,0 +1,63 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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.common.exceptions.AsterixException;
+
+public class FunctionDecl implements Statement {
+    private FunIdentifier ident;
+    private List<VarIdentifier> paramList;
+    private Expression funcBody;
+
+    public FunctionDecl() {
+    }
+
+    public FunctionDecl(FunIdentifier ident, List<VarIdentifier> paramList, Expression funcBody) {
+        this.ident = ident;
+        this.paramList = paramList;
+        this.funcBody = funcBody;
+    }
+
+    public FunIdentifier getIdent() {
+        return ident;
+    }
+
+    public void setIdent(FunIdentifier ident) {
+        this.ident = ident;
+    }
+
+    public List<VarIdentifier> getParamList() {
+        return paramList;
+    }
+
+    public void setParamList(List<VarIdentifier> paramList) {
+        this.paramList = paramList;
+    }
+
+    public Expression getFuncBody() {
+        return funcBody;
+    }
+
+    public void setFuncBody(Expression funcBody) {
+        this.funcBody = funcBody;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.FUNCTION_DECL;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitFunctionDecl(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunctionDropStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunctionDropStatement.java
new file mode 100644
index 0000000..4b96143
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/FunctionDropStatement.java
@@ -0,0 +1,51 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class FunctionDropStatement implements Statement {
+
+    private Identifier functionName;
+    private int arity;
+    private boolean ifExists;
+
+    public FunctionDropStatement(Identifier functionName, int arity, boolean ifExists) {
+        this.functionName = functionName;
+        this.arity = arity;
+        this.ifExists = ifExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.FUNCTION_DROP;
+    }
+
+    public Identifier getFunctionName() {
+        return functionName;
+    }
+
+    public boolean getIfExists() {
+        return ifExists;
+    }
+
+    public int getArity() {
+        return arity;
+    }
+
+    public void setArity(int arity) {
+        this.arity = arity;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitFunctionDropStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/GbyVariableExpressionPair.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/GbyVariableExpressionPair.java
new file mode 100644
index 0000000..ed52e7a
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/GbyVariableExpressionPair.java
@@ -0,0 +1,35 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+
+public class GbyVariableExpressionPair {
+    private VariableExpr var; // can be null
+    private Expression expr;
+
+    public GbyVariableExpressionPair() {
+        super();
+    }
+
+    public GbyVariableExpressionPair(VariableExpr var, Expression expr) {
+        super();
+        this.var = var;
+        this.expr = expr;
+    }
+
+    public VariableExpr getVar() {
+        return var;
+    }
+
+    public void setVar(VariableExpr var) {
+        this.var = var;
+    }
+
+    public Expression getExpr() {
+        return expr;
+    }
+
+    public void setExpr(Expression expr) {
+        this.expr = expr;
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/GroupbyClause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/GroupbyClause.java
new file mode 100644
index 0000000..7eaf23f
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/GroupbyClause.java
@@ -0,0 +1,74 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+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;
+
+public class GroupbyClause implements Clause {
+
+    private List<GbyVariableExpressionPair> gbyPairList;
+    private List<GbyVariableExpressionPair> decorPairList;
+    private List<VariableExpr> withVarList;
+    private boolean hashGroupByHint;
+
+    public GroupbyClause() {
+    }
+
+    public GroupbyClause(List<GbyVariableExpressionPair> gbyPairList, List<GbyVariableExpressionPair> decorPairList,
+            List<VariableExpr> withVarList, boolean hashGroupByHint) {
+        this.gbyPairList = gbyPairList;
+        this.setDecorPairList(decorPairList);
+        this.withVarList = withVarList;
+        this.hashGroupByHint = hashGroupByHint;
+    }
+
+    public List<GbyVariableExpressionPair> getGbyPairList() {
+        return gbyPairList;
+    }
+
+    public void setGbyPairList(List<GbyVariableExpressionPair> vePairList) {
+        this.gbyPairList = vePairList;
+    }
+
+    public List<VariableExpr> getWithVarList() {
+        return withVarList;
+    }
+
+    public void setWithVarList(List<VariableExpr> withVarList) {
+        this.withVarList = withVarList;
+    }
+
+    @Override
+    public ClauseType getClauseType() {
+        return ClauseType.GROUP_BY_CLAUSE;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitGroupbyClause(this, arg);
+    }
+
+    public void setDecorPairList(List<GbyVariableExpressionPair> decorPairList) {
+        this.decorPairList = decorPairList;
+    }
+
+    public List<GbyVariableExpressionPair> getDecorPairList() {
+        return decorPairList;
+    }
+
+    public void setHashGroupByHint(boolean hashGroupByHint) {
+        this.hashGroupByHint = hashGroupByHint;
+    }
+
+    public boolean hasHashGroupByHint() {
+        return hashGroupByHint;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/HdfsPathInfo.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/HdfsPathInfo.java
new file mode 100644
index 0000000..f4041db
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/HdfsPathInfo.java
@@ -0,0 +1,13 @@
+package edu.uci.ics.asterix.aql.expression;
+
+public class HdfsPathInfo {
+    public String hdfsPath;
+
+    public HdfsPathInfo(String hdfsPath) {
+        this.hdfsPath = hdfsPath;
+    }
+
+    public String getHdfsPathInfo() {
+        return hdfsPath;
+    }
+}
\ No newline at end of file
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IDatasetDetailsDecl.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IDatasetDetailsDecl.java
new file mode 100644
index 0000000..ccc83b6
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IDatasetDetailsDecl.java
@@ -0,0 +1,19 @@
+/*
+ * 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.aql.expression;
+
+public interface IDatasetDetailsDecl {
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/Identifier.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/Identifier.java
new file mode 100644
index 0000000..bbca259
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/Identifier.java
@@ -0,0 +1,39 @@
+package edu.uci.ics.asterix.aql.expression;
+
+public class Identifier {
+    protected String value;
+
+    public Identifier() {
+    }
+
+    public Identifier(String value) {
+        this.value = value;
+    }
+
+    public final String getValue() {
+        return value;
+    }
+
+    public final void setValue(String value) {
+        this.value = value;
+    }
+
+    public String toString() {
+        return value;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Identifier)) {
+            return false;
+        } else {
+            Identifier i = (Identifier) o;
+            return this.value.equals(i.value);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return value.hashCode();
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IfExpr.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IfExpr.java
new file mode 100644
index 0000000..753a8dd
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IfExpr.java
@@ -0,0 +1,61 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class IfExpr implements Expression {
+    private Expression condExpr;
+    private Expression thenExpr;
+    private Expression elseExpr;
+
+    public IfExpr() {
+    }
+
+    public IfExpr(Expression condExpr, Expression thenExpr, Expression elseExpr) {
+        this.condExpr = condExpr;
+        this.thenExpr = thenExpr;
+        this.elseExpr = elseExpr;
+    }
+
+    public Expression getCondExpr() {
+        return condExpr;
+    }
+
+    public void setCondExpr(Expression condExpr) {
+        this.condExpr = condExpr;
+    }
+
+    public Expression getThenExpr() {
+        return thenExpr;
+    }
+
+    public void setThenExpr(Expression thenExpr) {
+        this.thenExpr = thenExpr;
+    }
+
+    public Expression getElseExpr() {
+        return elseExpr;
+    }
+
+    public void setElseExpr(Expression elseExpr) {
+        this.elseExpr = elseExpr;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.IF_EXPRESSION;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitIfExpr(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IndexAccessor.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IndexAccessor.java
new file mode 100644
index 0000000..4d2c916
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IndexAccessor.java
@@ -0,0 +1,51 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class IndexAccessor extends AbstractAccessor {
+    private boolean any;
+    private int index;
+
+    public final static int ANY = -1;
+
+    public IndexAccessor(Expression expr, int index) {
+        super(expr);
+        if (index == -1)
+            this.any = true;
+        this.index = index;
+    }
+
+    public boolean isAny() {
+        return any;
+    }
+
+    public void setAny(boolean any) {
+        this.any = any;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+
+    public void setIndex(int index) {
+        this.index = index;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.INDEX_ACCESSOR_EXPRESSION;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitIndexAccessor(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IndexDecl.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IndexDecl.java
new file mode 100644
index 0000000..b40220e
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IndexDecl.java
@@ -0,0 +1,8 @@
+package edu.uci.ics.asterix.aql.expression;
+
+public class IndexDecl extends CreateIndexStatement {
+    @Override
+    public Kind getKind() {
+        return Kind.INDEX_DECL;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IndexDropStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IndexDropStatement.java
new file mode 100644
index 0000000..b69ccd1
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/IndexDropStatement.java
@@ -0,0 +1,46 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class IndexDropStatement implements Statement {
+
+    private Identifier datasetName;
+    private Identifier indexName;
+    private boolean ifExists;
+
+    public IndexDropStatement(Identifier dataverseName, Identifier indexName, boolean ifExists) {
+        this.datasetName = dataverseName;
+        this.indexName = indexName;
+        this.ifExists = ifExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.INDEX_DROP;
+    }
+
+    public Identifier getDatasetName() {
+        return datasetName;
+    }
+
+    public Identifier getIndexName() {
+        return indexName;
+    }
+
+    public boolean getIfExists() {
+        return ifExists;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitIndexDropStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/InsertStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/InsertStatement.java
new file mode 100644
index 0000000..7faa33e
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/InsertStatement.java
@@ -0,0 +1,47 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class InsertStatement implements Statement {
+
+    private Identifier datasetName;
+    private Query query;
+    private int varCounter;
+
+    public InsertStatement(Identifier datasetName, Query query, int varCounter) {
+        this.datasetName = datasetName;
+        this.query = query;
+        this.varCounter = varCounter;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.INSERT;
+    }
+
+    public Identifier getDatasetName() {
+        return datasetName;
+    }
+
+    public Query getQuery() {
+        return query;
+    }
+
+    public int getVarCounter() {
+        return varCounter;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitInsertStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/InternalDetailsDecl.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/InternalDetailsDecl.java
new file mode 100644
index 0000000..a680e48
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/InternalDetailsDecl.java
@@ -0,0 +1,45 @@
+/*
+ * 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.aql.expression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.metadata.bootstrap.MetadataConstants;
+
+public class InternalDetailsDecl implements IDatasetDetailsDecl {
+    private Identifier nodegroupName = new Identifier(MetadataConstants.METADATA_DEFAULT_NODEGROUP_NAME);
+    private List<String> partitioningExprs = new ArrayList<String>();
+
+    public void addPartitioningExpr(String pe) {
+        this.partitioningExprs.add(pe);
+    }
+
+    public void addPartitioningExprList(List<String> peList) {
+        this.partitioningExprs = peList;
+    }
+
+    public List<String> getPartitioningExprs() {
+        return partitioningExprs;
+    }
+
+    public void setNodegroupName(Identifier nodegroupName) {
+        this.nodegroupName = nodegroupName;
+    }
+
+    public Identifier getNodegroupName() {
+        return nodegroupName;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/JoinClause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/JoinClause.java
new file mode 100644
index 0000000..f04c4ae
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/JoinClause.java
@@ -0,0 +1,74 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlPlusExpressionVisitor;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlVisitorWithVoidReturn;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+
+public class JoinClause implements Clause {
+
+    public static enum JoinKind {
+        INNER,
+        LEFT_OUTER
+    }
+
+    private Expression whereExpr;
+    private List<Clause> leftClauses, rightClauses;
+    private final JoinKind kind;
+
+    public JoinClause() {
+        kind = JoinKind.INNER;
+    }
+
+    public JoinClause(JoinKind kind) {
+        this.kind = kind;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return ((IAqlPlusExpressionVisitor<R, T>) visitor).visitJoinClause(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        throw new NotImplementedException();
+    }
+
+    @Override
+    public ClauseType getClauseType() {
+        return null;
+    }
+
+    public List<Clause> getLeftClauses() {
+        return leftClauses;
+    }
+
+    public List<Clause> getRightClauses() {
+        return rightClauses;
+    }
+
+    public Expression getWhereExpr() {
+        return whereExpr;
+    }
+
+    public void setLeftClauses(List<Clause> leftClauses) {
+        this.leftClauses = leftClauses;
+    }
+
+    public void setRightClauses(List<Clause> righClauses) {
+        this.rightClauses = righClauses;
+    }
+
+    public void setWhereExpr(Expression whereExpr) {
+        this.whereExpr = whereExpr;
+    }
+
+    public JoinKind getKind() {
+        return kind;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LetClause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LetClause.java
new file mode 100644
index 0000000..85a3bb7
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LetClause.java
@@ -0,0 +1,57 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class LetClause implements Clause {
+    private VariableExpr varExpr;
+    private Expression bindExpr;
+
+    public LetClause() {
+        super();
+    }
+
+    public LetClause(VariableExpr varExpr, Expression bindExpr) {
+        super();
+        this.varExpr = varExpr;
+        this.bindExpr = bindExpr;
+    }
+
+    public VariableExpr getVarExpr() {
+        return varExpr;
+    }
+
+    public void setVarExpr(VariableExpr varExpr) {
+        this.varExpr = varExpr;
+    }
+
+    public Expression getBindingExpr() {
+        return bindExpr;
+    }
+
+    public void setBindingExpr(Expression bindExpr) {
+        this.bindExpr = bindExpr;
+    }
+
+    public void setBeExpr(Expression beExpr) {
+        this.bindExpr = beExpr;
+    }
+
+    @Override
+    public ClauseType getClauseType() {
+        return ClauseType.LET_CLAUSE;
+    }
+
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitLetClause(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LimitClause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LimitClause.java
new file mode 100644
index 0000000..404ce91
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LimitClause.java
@@ -0,0 +1,51 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class LimitClause implements Clause {
+    private Expression limitexpr;
+    private Expression offset;
+
+    public LimitClause() {
+    }
+
+    public LimitClause(Expression limitexpr, Expression offset) {
+        this.limitexpr = limitexpr;
+        this.offset = offset;
+    }
+
+    public Expression getLimitExpr() {
+        return limitexpr;
+    }
+
+    public void setLimitExpr(Expression limitexpr) {
+        this.limitexpr = limitexpr;
+    }
+
+    public Expression getOffset() {
+        return offset;
+    }
+
+    public void setOffset(Expression offset) {
+        this.offset = offset;
+    }
+
+    @Override
+    public ClauseType getClauseType() {
+        return ClauseType.LIMIT_CLAUSE;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitLimitClause(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ListConstructor.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ListConstructor.java
new file mode 100644
index 0000000..d333402
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/ListConstructor.java
@@ -0,0 +1,58 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class ListConstructor implements Expression {
+    private List<Expression> exprList;
+    private Type type;
+
+    public ListConstructor() {
+    }
+
+    public ListConstructor(Type type, List<Expression> exprList) {
+        this.type = type;
+        this.exprList = exprList;
+    }
+
+    public List<Expression> getExprList() {
+        return exprList;
+    }
+
+    public void setExprList(List<Expression> exprList) {
+        this.exprList = exprList;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public void setType(Type type) {
+        this.type = type;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.LIST_CONSTRUCTOR_EXPRESSION;
+    }
+
+    public enum Type {
+        ORDERED_LIST_CONSTRUCTOR,
+        UNORDERED_LIST_CONSTRUCTOR
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitListConstructor(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LiteralExpr.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LiteralExpr.java
new file mode 100644
index 0000000..ba94cfc
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LiteralExpr.java
@@ -0,0 +1,41 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+import edu.uci.ics.asterix.aql.base.ILiteral;
+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;
+
+public class LiteralExpr implements Expression {
+    private ILiteral value;
+
+    public LiteralExpr() {
+    }
+
+    public LiteralExpr(ILiteral value) {
+        this.value = value;
+    }
+
+    public ILiteral getValue() {
+        return value;
+    }
+
+    public void setValue(ILiteral value) {
+        this.value = value;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.LITERAL_EXPRESSION;
+    }
+
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitLiteralExpr(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LoadFromFileStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LoadFromFileStatement.java
new file mode 100644
index 0000000..011ee898
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/LoadFromFileStatement.java
@@ -0,0 +1,64 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.Map;
+
+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.common.exceptions.AsterixException;
+
+public class LoadFromFileStatement implements Statement {
+
+    private Identifier datasetName;
+    private String adapter;
+    private Map<String, String> properties;
+    private boolean dataIsLocallySorted;
+
+    public LoadFromFileStatement(Identifier datasetName, String adapter, Map<String, String> propertiees,
+            boolean dataIsLocallySorted) {
+        this.datasetName = datasetName;
+        this.adapter = adapter;
+        this.properties = propertiees;
+        this.dataIsLocallySorted = dataIsLocallySorted;
+    }
+
+    public String getAdapter() {
+        return adapter;
+    }
+
+    public void setAdapter(String adapter) {
+        this.adapter = adapter;
+    }
+
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(Map<String, String> properties) {
+        this.properties = properties;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.LOAD_FROM_FILE;
+    }
+
+    public Identifier getDatasetName() {
+        return datasetName;
+    }
+
+    public boolean dataIsAlreadySorted() {
+        return dataIsLocallySorted;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitLoadFromFileStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/MetaVariableClause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/MetaVariableClause.java
new file mode 100644
index 0000000..b5c8a8a
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/MetaVariableClause.java
@@ -0,0 +1,35 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlPlusExpressionVisitor;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlVisitorWithVoidReturn;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+
+public class MetaVariableClause implements Clause {
+    private VarIdentifier var;
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return ((IAqlPlusExpressionVisitor<R, T>) visitor).visitMetaVariableClause(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        throw new NotImplementedException();
+    }
+
+    @Override
+    public ClauseType getClauseType() {
+        return null;
+    }
+
+    public VarIdentifier getVar() {
+        return var;
+    }
+
+    public void setVar(VarIdentifier var) {
+        this.var = var;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/MetaVariableExpr.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/MetaVariableExpr.java
new file mode 100644
index 0000000..cb78d24
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/MetaVariableExpr.java
@@ -0,0 +1,29 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlPlusExpressionVisitor;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlVisitorWithVoidReturn;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
+
+public class MetaVariableExpr extends VariableExpr {
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return ((IAqlPlusExpressionVisitor<R, T>) visitor).visitMetaVariableExpr(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        throw new NotImplementedException();
+    }
+
+    public boolean getIsNewVar() {
+        return false;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.METAVARIABLE_EXPRESSION;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/NodeGroupDropStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/NodeGroupDropStatement.java
new file mode 100644
index 0000000..1606388
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/NodeGroupDropStatement.java
@@ -0,0 +1,41 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class NodeGroupDropStatement implements Statement {
+
+    private Identifier nodeGroupName;
+    private boolean ifExists;
+
+    public NodeGroupDropStatement(Identifier nodeGroupName, boolean ifExists) {
+        this.nodeGroupName = nodeGroupName;
+        this.ifExists = ifExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.NODEGROUP_DROP;
+    }
+
+    public Identifier getNodeGroupName() {
+        return nodeGroupName;
+    }
+
+    public boolean getIfExists() {
+        return ifExists;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitNodeGroupDropStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/NodegroupDecl.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/NodegroupDecl.java
new file mode 100644
index 0000000..0889571
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/NodegroupDecl.java
@@ -0,0 +1,52 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class NodegroupDecl implements Statement {
+
+    private Identifier nodegroupName;
+    private List<Identifier> nodeControllerNames;
+    private boolean ifNotExists;
+
+    public NodegroupDecl(Identifier nodegroupName, List<Identifier> nodeControllerNames, boolean ifNotExists) {
+        this.nodegroupName = nodegroupName;
+        this.nodeControllerNames = nodeControllerNames;
+        this.ifNotExists = ifNotExists;
+    }
+
+    public Identifier getNodegroupName() {
+        return nodegroupName;
+    }
+
+    public List<Identifier> getNodeControllerNames() {
+        return nodeControllerNames;
+    }
+
+    public void setNodeControllerNames(List<Identifier> nodeControllerNames) {
+        this.nodeControllerNames = nodeControllerNames;
+    }
+
+    public boolean getIfNotExists() {
+        return this.ifNotExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.NODEGROUP_DECL;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitNodegroupDecl(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OperatorExpr.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OperatorExpr.java
new file mode 100644
index 0000000..b6bb55b
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OperatorExpr.java
@@ -0,0 +1,129 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.ArrayList;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class OperatorExpr implements Expression {
+    private ArrayList<Expression> exprList;
+    private ArrayList<OperatorType> opList;
+    private ArrayList<Integer> exprBroadcastIdx;
+    private boolean currentop = false;
+
+    public OperatorExpr() {
+        super();
+        exprList = new ArrayList<Expression>();
+        exprBroadcastIdx = new ArrayList<Integer>();
+        opList = new ArrayList<OperatorType>();
+    }
+
+    public OperatorExpr(ArrayList<Expression> exprList, ArrayList<Integer> exprBroadcastIdx,
+            ArrayList<OperatorType> opList) {
+        this.exprList = exprList;
+        this.exprBroadcastIdx = exprBroadcastIdx;
+        this.opList = opList;
+    }
+
+    public boolean isCurrentop() {
+        return currentop;
+    }
+
+    public void setCurrentop(boolean currentop) {
+        this.currentop = currentop;
+    }
+
+    public ArrayList<Expression> getExprList() {
+        return exprList;
+    }
+
+    public ArrayList<Integer> getExprBroadcastIdx() {
+        return exprBroadcastIdx;
+    }
+
+    public ArrayList<OperatorType> getOpList() {
+        return opList;
+    }
+
+    public void setExprList(ArrayList<Expression> exprList) {
+        this.exprList = exprList;
+    }
+
+    public void addOperand(Expression operand) {
+        addOperand(operand, false);
+    }
+
+    public void addOperand(Expression operand, boolean broadcast) {
+        if (broadcast) {
+            exprBroadcastIdx.add(exprList.size());
+        }
+        exprList.add(operand);
+    }
+
+    public final static boolean opIsComparison(OperatorType t) {
+        return t == OperatorType.EQ || t == OperatorType.NEQ || t == OperatorType.GT || t == OperatorType.GE
+                || t == OperatorType.LT || t == OperatorType.LE;
+    }
+
+    public void addOperator(String strOp) {
+        if ("or".equals(strOp))
+            opList.add(OperatorType.OR);
+        else if ("and".equals(strOp))
+            opList.add(OperatorType.AND);
+        else if ("<".equals(strOp))
+            opList.add(OperatorType.LT);
+        else if (">".equals(strOp))
+            opList.add(OperatorType.GT);
+        else if ("<=".equals(strOp))
+            opList.add(OperatorType.LE);
+        else if ("<=".equals(strOp))
+            opList.add(OperatorType.LE);
+        else if (">=".equals(strOp))
+            opList.add(OperatorType.GE);
+        else if ("=".equals(strOp))
+            opList.add(OperatorType.EQ);
+        else if ("!=".equals(strOp))
+            opList.add(OperatorType.NEQ);
+        else if ("+".equals(strOp))
+            opList.add(OperatorType.PLUS);
+        else if ("-".equals(strOp))
+            opList.add(OperatorType.MINUS);
+        else if ("*".equals(strOp))
+            opList.add(OperatorType.MUL);
+        else if ("/".equals(strOp))
+            opList.add(OperatorType.DIV);
+        else if ("%".equals(strOp))
+            opList.add(OperatorType.MOD);
+        else if ("^".equals(strOp))
+            opList.add(OperatorType.CARET);
+        else if ("idiv".equals(strOp))
+            opList.add(OperatorType.IDIV);
+        else if ("~=".equals(strOp))
+            opList.add(OperatorType.FUZZY_EQ);
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.OP_EXPRESSION;
+    }
+
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitOperatorExpr(this, arg);
+    }
+
+    public boolean isBroadcastOperand(int idx) {
+        for (Integer i : exprBroadcastIdx) {
+            if (i == idx) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OperatorType.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OperatorType.java
new file mode 100644
index 0000000..4bb62aa
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OperatorType.java
@@ -0,0 +1,21 @@
+package edu.uci.ics.asterix.aql.expression;
+
+public enum OperatorType {
+    OR,
+    AND,
+    LT,
+    GT,
+    LE,
+    GE,
+    EQ,
+    NEQ,
+    PLUS,
+    MINUS,
+    MUL,
+    DIV, // float/double
+         // divide
+    MOD,
+    CARET,
+    IDIV, // integer divide
+    FUZZY_EQ
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OrderbyClause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OrderbyClause.java
new file mode 100644
index 0000000..719bfa7
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OrderbyClause.java
@@ -0,0 +1,75 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class OrderbyClause implements Clause {
+    private List<Expression> orderbyList;
+    private List<OrderModifier> modifierList;
+    private int numFrames = -1;
+    private int numTuples = -1;
+
+    public OrderbyClause() {
+    }
+
+    public OrderbyClause(List<Expression> orderbyList, List<OrderModifier> modifierList) {
+        this.orderbyList = orderbyList;
+        this.modifierList = modifierList;
+    }
+
+    public List<Expression> getOrderbyList() {
+        return orderbyList;
+    }
+
+    public void setOrderbyList(List<Expression> orderbyList) {
+        this.orderbyList = orderbyList;
+    }
+
+    public List<OrderModifier> getModifierList() {
+        return modifierList;
+    }
+
+    public void setModifierList(List<OrderModifier> modifierList) {
+        this.modifierList = modifierList;
+    }
+
+    @Override
+    public ClauseType getClauseType() {
+        return ClauseType.ORDER_BY_CLAUSE;
+    }
+
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    public enum OrderModifier {
+        ASC,
+        DESC
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitOrderbyClause(this, arg);
+    }
+
+    public int getNumFrames() {
+        return numFrames;
+    }
+
+    public void setNumFrames(int numFrames) {
+        this.numFrames = numFrames;
+    }
+
+    public int getNumTuples() {
+        return numTuples;
+    }
+
+    public void setNumTuples(int numTuples) {
+        this.numTuples = numTuples;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OrderedListTypeDefinition.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OrderedListTypeDefinition.java
new file mode 100644
index 0000000..fa531fb
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/OrderedListTypeDefinition.java
@@ -0,0 +1,34 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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;
+
+public class OrderedListTypeDefinition extends TypeExpression {
+
+    private TypeExpression itemTypeExpression;
+
+    public OrderedListTypeDefinition(TypeExpression itemTypeExpression) {
+        this.itemTypeExpression = itemTypeExpression;
+    }
+
+    @Override
+    public TypeExprKind getTypeKind() {
+        return TypeExprKind.ORDEREDLIST;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitOrderedListTypeDefiniton(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    public TypeExpression getItemTypeExpression() {
+        return itemTypeExpression;
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/QuantifiedExpression.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/QuantifiedExpression.java
new file mode 100644
index 0000000..0e97eab
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/QuantifiedExpression.java
@@ -0,0 +1,69 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class QuantifiedExpression implements Expression {
+    private List<QuantifiedPair> quantifiedList;
+    private Expression satisfiesExpr;
+    private Quantifier quantifier;
+
+    public QuantifiedExpression() {
+        super();
+    }
+
+    public QuantifiedExpression(Quantifier quantifier, List<QuantifiedPair> quantifiedList, Expression satisfiesExpr) {
+        super();
+        this.quantifier = quantifier;
+        this.quantifiedList = quantifiedList;
+        this.satisfiesExpr = satisfiesExpr;
+    }
+
+    public Quantifier getQuantifier() {
+        return quantifier;
+    }
+
+    public void setQuantifier(Quantifier quantifier) {
+        this.quantifier = quantifier;
+    }
+
+    public List<QuantifiedPair> getQuantifiedList() {
+        return quantifiedList;
+    }
+
+    public void setQuantifiedList(List<QuantifiedPair> quantifiedList) {
+        this.quantifiedList = quantifiedList;
+    }
+
+    public Expression getSatisfiesExpr() {
+        return satisfiesExpr;
+    }
+
+    public void setSatisfiesExpr(Expression satisfiesExpr) {
+        this.satisfiesExpr = satisfiesExpr;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.QUANTIFIED_EXPRESSION;
+    }
+
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitQuantifiedExpression(this, arg);
+    }
+
+    public enum Quantifier {
+        EVERY,
+        SOME
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/QuantifiedPair.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/QuantifiedPair.java
new file mode 100644
index 0000000..ae1124e
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/QuantifiedPair.java
@@ -0,0 +1,33 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+
+public class QuantifiedPair {
+    private VariableExpr varExpr;
+    private Expression expr;
+
+    public QuantifiedPair() {
+    }
+
+    public QuantifiedPair(VariableExpr varExpr, Expression expr) {
+        this.varExpr = varExpr;
+        this.expr = expr;
+    }
+
+    public VariableExpr getVarExpr() {
+        return varExpr;
+    }
+
+    public void setVarExpr(VariableExpr varExpr) {
+        this.varExpr = varExpr;
+    }
+
+    public Expression getExpr() {
+        return expr;
+    }
+
+    public void setExpr(Expression expr) {
+        this.expr = expr;
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/Query.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/Query.java
new file mode 100644
index 0000000..6e851b0
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/Query.java
@@ -0,0 +1,68 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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.common.exceptions.AsterixException;
+
+public class Query implements Statement {
+    private Expression body;
+    private List<Statement> prologDeclList = new ArrayList<Statement>();
+    private boolean isDummyQuery = false;
+
+    public Query() {
+    }
+
+    public Query(boolean isDummyQuery) {
+        this.isDummyQuery = isDummyQuery;
+    }
+
+    public boolean isDummyQuery() {
+        return isDummyQuery;
+    }
+
+    public Expression getBody() {
+        return body;
+    }
+
+    public void setBody(Expression body) {
+        this.body = body;
+    }
+
+    public void addPrologDecl(Statement stmt) {
+        this.prologDeclList.add(stmt);
+    }
+
+    public List<Statement> getPrologDeclList() {
+        return prologDeclList;
+    }
+
+    public void setPrologDeclList(List<Statement> prologDeclList) {
+        this.prologDeclList = prologDeclList;
+    }
+
+    // public void addFunctionDecl(FunctionDeclClass fc){
+    // if(functionDeclList == null){
+    // functionDeclList = new ArrayList<FunctionDeclClass>();
+    // }
+    // functionDeclList.add(fc);
+    // }
+    @Override
+    public Kind getKind() {
+        return Kind.QUERY;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T step) throws AsterixException {
+        visitor.visit(this, step);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitQuery(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/RecordConstructor.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/RecordConstructor.java
new file mode 100644
index 0000000..e5795d5c
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/RecordConstructor.java
@@ -0,0 +1,44 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class RecordConstructor implements Expression {
+    private List<FieldBinding> fbList;
+
+    public RecordConstructor() {
+        super();
+    }
+
+    public RecordConstructor(List<FieldBinding> fbList) {
+        super();
+        this.fbList = fbList;
+    }
+
+    public List<FieldBinding> getFbList() {
+        return fbList;
+    }
+
+    public void setFbList(List<FieldBinding> fbList) {
+        this.fbList = fbList;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.RECORD_CONSTRUCTOR_EXPRESSION;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitRecordConstructor(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/RecordTypeDefinition.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/RecordTypeDefinition.java
new file mode 100644
index 0000000..3f4e239
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/RecordTypeDefinition.java
@@ -0,0 +1,92 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.ArrayList;
+
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlVisitorWithVoidReturn;
+import edu.uci.ics.asterix.common.annotations.IRecordFieldDataGen;
+import edu.uci.ics.asterix.common.annotations.UndeclaredFieldsDataGen;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+
+public class RecordTypeDefinition extends TypeExpression {
+
+    public enum RecordKind {
+        OPEN,
+        CLOSED
+    }
+
+    private ArrayList<String> fieldNames;
+    private ArrayList<TypeExpression> fieldTypes;
+    private ArrayList<IRecordFieldDataGen> fieldDataGen;
+    private ArrayList<Boolean> nullableFields;
+    private RecordKind recordKind;
+    private UndeclaredFieldsDataGen undeclaredFieldsDataGen;
+
+    public RecordTypeDefinition() {
+        fieldNames = new ArrayList<String>();
+        fieldTypes = new ArrayList<TypeExpression>();
+        nullableFields = new ArrayList<Boolean>();
+        fieldDataGen = new ArrayList<IRecordFieldDataGen>();
+    }
+
+    @Override
+    public TypeExprKind getTypeKind() {
+        return TypeExprKind.RECORD;
+    }
+
+    public void addField(String name, TypeExpression type, Boolean nullable, IRecordFieldDataGen fldDataGen) {
+        fieldNames.add(name);
+        fieldTypes.add(type);
+        nullableFields.add(nullable);
+        fieldDataGen.add(fldDataGen);
+    }
+
+    public void addField(String name, TypeExpression type, Boolean nullable) {
+        fieldNames.add(name);
+        fieldTypes.add(type);
+        nullableFields.add(nullable);
+    }
+
+    public ArrayList<String> getFieldNames() {
+        return fieldNames;
+    }
+
+    public ArrayList<TypeExpression> getFieldTypes() {
+        return fieldTypes;
+    }
+
+    public ArrayList<Boolean> getNullableFields() {
+        return nullableFields;
+    }
+
+    public ArrayList<IRecordFieldDataGen> getFieldDataGen() {
+        return fieldDataGen;
+    }
+
+    public RecordKind getRecordKind() {
+        return recordKind;
+    }
+
+    public void setRecordKind(RecordKind recordKind) {
+        this.recordKind = recordKind;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitRecordTypeDefiniton(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    public void setUndeclaredFieldsDataGen(UndeclaredFieldsDataGen undeclaredFieldsDataGen) {
+        this.undeclaredFieldsDataGen = undeclaredFieldsDataGen;
+    }
+
+    public UndeclaredFieldsDataGen getUndeclaredFieldsDataGen() {
+        return undeclaredFieldsDataGen;
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/SetStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/SetStatement.java
new file mode 100644
index 0000000..94c8ad9
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/SetStatement.java
@@ -0,0 +1,42 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class SetStatement implements Statement {
+
+    private String propName;
+    private String propValue;
+
+    public SetStatement(String propName, String propValue) {
+        this.propName = propName;
+        this.propValue = propValue;
+    }
+
+    public String getPropName() {
+        return propName;
+    }
+
+    public String getPropValue() {
+        return propValue;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.SET;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeDecl.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeDecl.java
new file mode 100644
index 0000000..b7ccc8f
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeDecl.java
@@ -0,0 +1,58 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.annotations.TypeDataGen;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+
+public class TypeDecl implements Statement {
+
+    private final Identifier ident;
+    private final TypeExpression typeDef;
+    private final TypeDataGen datagenAnnotation;
+    private final boolean ifNotExists;
+
+    public TypeDecl(Identifier ident, TypeExpression typeDef, TypeDataGen datagen, boolean ifNotExists) {
+        this.ident = ident;
+        this.typeDef = typeDef;
+        this.datagenAnnotation = datagen;
+        this.ifNotExists = ifNotExists;
+    }
+
+    public TypeDecl(Identifier ident, TypeExpression typeDef) {
+        this(ident, typeDef, null, false);
+    }
+
+    public Identifier getIdent() {
+        return ident;
+    }
+
+    public TypeExpression getTypeDef() {
+        return typeDef;
+    }
+
+    public boolean getIfNotExists() {
+        return this.ifNotExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.TYPE_DECL;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitTypeDecl(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    public TypeDataGen getDatagenAnnotation() {
+        return datagenAnnotation;
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeDropStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeDropStatement.java
new file mode 100644
index 0000000..b50dbdd
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeDropStatement.java
@@ -0,0 +1,41 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class TypeDropStatement implements Statement {
+
+    private Identifier typeName;
+    private boolean ifExists;
+
+    public TypeDropStatement(Identifier typeName, boolean ifExists) {
+        this.typeName = typeName;
+        this.ifExists = ifExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.TYPE_DROP;
+    }
+
+    public Identifier getTypeName() {
+        return typeName;
+    }
+
+    public boolean getIfExists() {
+        return ifExists;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitTypeDropStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeExpression.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeExpression.java
new file mode 100644
index 0000000..26f7e6e
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeExpression.java
@@ -0,0 +1,16 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.IAqlExpression;
+
+public abstract class TypeExpression implements IAqlExpression {
+
+    public enum TypeExprKind {
+        RECORD,
+        TYPEREFERENCE,
+        ORDEREDLIST,
+        UNORDEREDLIST
+    }
+
+    public abstract TypeExprKind getTypeKind();
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeReferenceExpression.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeReferenceExpression.java
new file mode 100644
index 0000000..88673fa
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/TypeReferenceExpression.java
@@ -0,0 +1,34 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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;
+
+public class TypeReferenceExpression extends TypeExpression {
+
+    private Identifier ident;
+
+    public TypeReferenceExpression(Identifier ident) {
+        this.ident = ident;
+    }
+
+    public Identifier getIdent() {
+        return ident;
+    }
+
+    @Override
+    public TypeExprKind getTypeKind() {
+        return TypeExprKind.TYPEREFERENCE;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitTypeReferenceExpression(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UnaryExpr.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UnaryExpr.java
new file mode 100644
index 0000000..6d84c82
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UnaryExpr.java
@@ -0,0 +1,55 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class UnaryExpr implements Expression {
+    private Sign sign;
+    private Expression expr;
+
+    public UnaryExpr() {
+    }
+
+    public UnaryExpr(Sign sign, Expression expr) {
+        this.sign = sign;
+        this.expr = expr;
+    }
+
+    public Sign getSign() {
+        return sign;
+    }
+
+    public void setSign(Sign sign) {
+        this.sign = sign;
+    }
+
+    public Expression getExpr() {
+        return expr;
+    }
+
+    public void setExpr(Expression expr) {
+        this.expr = expr;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.UNARY_EXPRESSION;
+    }
+
+    public enum Sign {
+        POSITIVE,
+        NEGATIVE
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitUnaryExpr(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UnionExpr.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UnionExpr.java
new file mode 100644
index 0000000..f98b25b
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UnionExpr.java
@@ -0,0 +1,50 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class UnionExpr implements Expression {
+
+    private List<Expression> exprs;
+
+    public UnionExpr() {
+        exprs = new ArrayList<Expression>();
+    }
+
+    public UnionExpr(List<Expression> exprs) {
+        this.exprs = exprs;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.UNION_EXPRESSION;
+    }
+
+    public List<Expression> getExprs() {
+        return exprs;
+    }
+
+    public void setExprs(List<Expression> exprs) {
+        this.exprs = exprs;
+    }
+
+    public void addExpr(Expression exp) {
+        exprs.add(exp);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitUnionExpr(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UnorderedListTypeDefinition.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UnorderedListTypeDefinition.java
new file mode 100644
index 0000000..cceb090
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UnorderedListTypeDefinition.java
@@ -0,0 +1,34 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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;
+
+public class UnorderedListTypeDefinition extends TypeExpression {
+
+    private TypeExpression itemTypeExpression;
+
+    public UnorderedListTypeDefinition(TypeExpression itemTypeExpression) {
+        this.itemTypeExpression = itemTypeExpression;
+    }
+
+    @Override
+    public TypeExprKind getTypeKind() {
+        return TypeExprKind.UNORDEREDLIST;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitUnorderedListTypeDefiniton(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    public TypeExpression getItemTypeExpression() {
+        return itemTypeExpression;
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UpdateClause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UpdateClause.java
new file mode 100644
index 0000000..d264a47
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UpdateClause.java
@@ -0,0 +1,79 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class UpdateClause implements Clause {
+
+    private Expression target;
+    private Expression value;
+    private InsertStatement is;
+    private DeleteStatement ds;
+    private UpdateStatement us;
+    private Expression condition;
+    private UpdateClause ifbranch;
+    private UpdateClause elsebranch;
+
+    public UpdateClause(Expression target, Expression value, InsertStatement is, DeleteStatement ds,
+            UpdateStatement us, Expression condition, UpdateClause ifbranch, UpdateClause elsebranch) {
+        this.target = target;
+        this.value = value;
+        this.is = is;
+        this.ds = ds;
+        this.us = us;
+        this.condition = condition;
+        this.ifbranch = ifbranch;
+        this.elsebranch = elsebranch;
+    }
+
+    public Expression getTarget() {
+        return target;
+    }
+
+    public Expression getValue() {
+        return value;
+    }
+
+    public InsertStatement getInsertStatement() {
+        return is;
+    }
+
+    public DeleteStatement getDeleteStatement() {
+        return ds;
+    }
+
+    public UpdateStatement getUpdateStatement() {
+        return us;
+    }
+
+    public Expression getCondition() {
+        return condition;
+    }
+
+    public UpdateClause getIfBranch() {
+        return ifbranch;
+    }
+
+    public UpdateClause getElseBranch() {
+        return elsebranch;
+    }
+
+    @Override
+    public ClauseType getClauseType() {
+        return ClauseType.UPDATE_CLAUSE;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitUpdateClause(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UpdateStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UpdateStatement.java
new file mode 100644
index 0000000..7aa4d6b
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/UpdateStatement.java
@@ -0,0 +1,56 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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.common.exceptions.AsterixException;
+
+public class UpdateStatement implements Statement {
+
+    private VariableExpr vars;
+    private Expression target;
+    private Expression condition;
+    private List<UpdateClause> ucs;
+
+    public UpdateStatement(VariableExpr vars, Expression target, Expression condition, List<UpdateClause> ucs) {
+        this.vars = vars;
+        this.target = target;
+        this.condition = condition;
+        this.ucs = ucs;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.UPDATE;
+    }
+
+    public VariableExpr getVariableExpr() {
+        return vars;
+    }
+
+    public Expression getTarget() {
+        return target;
+    }
+
+    public Expression getCondition() {
+        return condition;
+    }
+
+    public List<UpdateClause> getUpdateClauses() {
+        return ucs;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitUpdateStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/VarIdentifier.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/VarIdentifier.java
new file mode 100644
index 0000000..f606296
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/VarIdentifier.java
@@ -0,0 +1,35 @@
+package edu.uci.ics.asterix.aql.expression;
+
+public final class VarIdentifier extends Identifier {
+    private int id;
+
+    public VarIdentifier() {
+        super();
+    }
+
+    public VarIdentifier(String value) {
+        super();
+        this.value = value;
+    }
+
+    public VarIdentifier(String value, int id) {
+        super();
+        this.value = value;
+        this.id = id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    @Override
+    public VarIdentifier clone() {
+        VarIdentifier vi = new VarIdentifier(this.value);
+        vi.setId(this.id);
+        return vi;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/VariableExpr.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/VariableExpr.java
new file mode 100644
index 0000000..d217849
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/VariableExpr.java
@@ -0,0 +1,53 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class VariableExpr implements Expression {
+    private VarIdentifier var;
+    private boolean isNewVar;
+
+    public VariableExpr() {
+        super();
+        isNewVar = true;
+    }
+
+    public VariableExpr(VarIdentifier var) {
+        super();
+        this.var = var;
+        isNewVar = true;
+    }
+
+    public boolean getIsNewVar() {
+        return isNewVar;
+    }
+
+    public void setIsNewVar(boolean isNewVar) {
+        this.isNewVar = isNewVar;
+    }
+
+    public VarIdentifier getVar() {
+        return var;
+    }
+
+    public void setVar(VarIdentifier var) {
+        this.var = var;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.VARIABLE_EXPRESSION;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitVariableExpr(this, arg);
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/WhereClause.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/WhereClause.java
new file mode 100644
index 0000000..d229453
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/WhereClause.java
@@ -0,0 +1,43 @@
+package edu.uci.ics.asterix.aql.expression;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+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;
+
+public class WhereClause implements Clause {
+    private Expression whereExpr;
+
+    public Expression getWhereExpr() {
+        return whereExpr;
+    }
+
+    public void setWhereExpr(Expression whereExpr) {
+        this.whereExpr = whereExpr;
+    }
+
+    public WhereClause(Expression whereExpr) {
+        super();
+        this.whereExpr = whereExpr;
+    }
+
+    public WhereClause() {
+    }
+
+    @Override
+    public ClauseType getClauseType() {
+        return ClauseType.WHERE_CLAUSE;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitWhereClause(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/WriteFromQueryResultStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/WriteFromQueryResultStatement.java
new file mode 100644
index 0000000..b45f5da
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/WriteFromQueryResultStatement.java
@@ -0,0 +1,48 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class WriteFromQueryResultStatement implements Statement {
+
+    private Identifier datasetName;
+
+    private Query query;
+    private int varCounter;
+
+    public WriteFromQueryResultStatement(Identifier datasetName, Query query, int varCounter) {
+        this.datasetName = datasetName;
+        this.query = query;
+        this.varCounter = varCounter;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.WRITE_FROM_QUERY_RESULT;
+    }
+
+    public Identifier getDatasetName() {
+        return datasetName;
+    }
+
+    public Query getQuery() {
+        return query;
+    }
+
+    public int getVarCounter() {
+        return varCounter;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        return visitor.visitLoadFromQueryResultStatement(this, arg);
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/WriteStatement.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/WriteStatement.java
new file mode 100644
index 0000000..151e155
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/WriteStatement.java
@@ -0,0 +1,48 @@
+package edu.uci.ics.asterix.aql.expression;
+
+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.common.exceptions.AsterixException;
+
+public class WriteStatement implements Statement {
+
+    private final Identifier ncName;
+    private final String fileName;
+    private final String writerClassName;
+
+    public WriteStatement(Identifier ncName, String fileName, String writerClassName) {
+        this.ncName = ncName;
+        this.fileName = fileName;
+        this.writerClassName = writerClassName;
+    }
+
+    public Identifier getNcName() {
+        return ncName;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public String getWriterClassName() {
+        return writerClassName;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.WRITE;
+    }
+
+    @Override
+    public <R, T> R accept(IAqlExpressionVisitor<R, T> visitor, T arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T> void accept(IAqlVisitorWithVoidReturn<T> visitor, T arg) throws AsterixException {
+        visitor.visit(this, arg);
+    }
+
+}
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
new file mode 100644
index 0000000..f4b895b
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/AQLPrintVisitor.java
@@ -0,0 +1,540 @@
+package edu.uci.ics.asterix.aql.expression.visitor;
+
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.base.Statement;
+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.CreateDataverseStatement;
+import edu.uci.ics.asterix.aql.expression.CreateFunctionStatement;
+import edu.uci.ics.asterix.aql.expression.CreateIndexStatement;
+import edu.uci.ics.asterix.aql.expression.DatasetDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDropStatement;
+import edu.uci.ics.asterix.aql.expression.DeleteStatement;
+import edu.uci.ics.asterix.aql.expression.DieClause;
+import edu.uci.ics.asterix.aql.expression.DistinctClause;
+import edu.uci.ics.asterix.aql.expression.DropStatement;
+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.FunctionDecl;
+import edu.uci.ics.asterix.aql.expression.FunctionDropStatement;
+import edu.uci.ics.asterix.aql.expression.GbyVariableExpressionPair;
+import edu.uci.ics.asterix.aql.expression.GroupbyClause;
+import edu.uci.ics.asterix.aql.expression.IfExpr;
+import edu.uci.ics.asterix.aql.expression.IndexAccessor;
+import edu.uci.ics.asterix.aql.expression.IndexDropStatement;
+import edu.uci.ics.asterix.aql.expression.InsertStatement;
+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.LiteralExpr;
+import edu.uci.ics.asterix.aql.expression.LoadFromFileStatement;
+import edu.uci.ics.asterix.aql.expression.NodeGroupDropStatement;
+import edu.uci.ics.asterix.aql.expression.NodegroupDecl;
+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.QuantifiedPair;
+import edu.uci.ics.asterix.aql.expression.Query;
+import edu.uci.ics.asterix.aql.expression.RecordConstructor;
+import edu.uci.ics.asterix.aql.expression.RecordTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.RecordTypeDefinition.RecordKind;
+import edu.uci.ics.asterix.aql.expression.SetStatement;
+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.UnaryExpr;
+import edu.uci.ics.asterix.aql.expression.UnionExpr;
+import edu.uci.ics.asterix.aql.expression.UnorderedListTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.UpdateClause;
+import edu.uci.ics.asterix.aql.expression.UpdateStatement;
+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.WriteStatement;
+import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.aql.expression.InternalDetailsDecl;
+
+public class AQLPrintVisitor implements IAqlVisitorWithVoidReturn<Integer> {
+    // private int level =0;
+    private final PrintWriter out;
+
+    public AQLPrintVisitor() {
+        out = new PrintWriter(System.out);
+    }
+
+    public AQLPrintVisitor(PrintWriter out) {
+        this.out = out;
+    }
+
+    private String skip(int step) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < step; i++)
+            sb.append("  ");
+        return sb.toString();
+    }
+
+    @Override
+    public void visit(Query q, Integer step) throws AsterixException {
+        for (Statement d : q.getPrologDeclList()) {
+            d.accept(this, step);
+        }
+        if (q.getBody() != null) {
+            out.println("Query:");
+            q.getBody().accept(this, step);
+        } else {
+            out.println("No query.");
+        }
+    }
+
+    @Override
+    public void visit(LiteralExpr l, Integer step) {
+        ILiteral lc = l.getValue();
+        if (lc.getLiteralType().equals(ILiteral.Type.TRUE) || lc.getLiteralType().equals(ILiteral.Type.FALSE)
+                || lc.getLiteralType().equals(ILiteral.Type.NULL)) {
+            out.println(skip(step) + "LiteralExpr [" + l.getValue().getLiteralType() + "]");
+        } else {
+            out.println(skip(step) + "LiteralExpr [" + l.getValue().getLiteralType() + "] ["
+                    + l.getValue().getStringValue() + "] ");
+        }
+    }
+
+    @Override
+    public void visit(VariableExpr v, Integer step) {
+        out.println(skip(step) + "Variable [ Name=" + v.getVar().getValue() + " Id=" + v.getVar().getId() + " ]");
+    }
+
+    @Override
+    public void visit(ListConstructor lc, Integer step) throws AsterixException {
+        boolean ordered = false;
+        if (lc.getType().equals(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR)) {
+            ordered = true;
+        }
+
+        out.println(skip(step) + (ordered == true ? "OrderedListConstructor " : "UnorderedListConstructor ") + "[");
+        for (Expression e : lc.getExprList()) {
+            e.accept(this, step + 1);
+        }
+        out.println(skip(step) + "]");
+    }
+
+    @Override
+    public void visit(RecordConstructor rc, Integer step) throws AsterixException {
+        out.println(skip(step) + "RecordConstructor [");
+        // fbList accept visitor
+        for (FieldBinding fb : rc.getFbList()) {
+            out.println(skip(step + 1) + "(");
+            fb.getLeftExpr().accept(this, step + 2);
+            out.println(skip(step + 2) + ":");
+            fb.getRightExpr().accept(this, step + 2);
+            out.println(skip(step + 1) + ")");
+        }
+        out.println(skip(step) + "]");
+    }
+
+    @Override
+    public void visit(CallExpr pf, Integer step) throws AsterixException {
+        out.println(skip(step) + "FunctionCall " + pf.getIdent().toString() + "[");
+        for (Expression expr : pf.getExprList()) {
+            expr.accept(this, step + 1);
+        }
+        out.println(skip(step) + "]");
+    }
+
+    @Override
+    public void visit(OperatorExpr ifbo, Integer step) throws AsterixException {
+        List<Expression> exprList = ifbo.getExprList();
+        List<OperatorType> opList = ifbo.getOpList();
+        if (ifbo.isCurrentop()) {
+            out.println(skip(step) + "OperatorExpr [");
+            exprList.get(0).accept(this, step + 1);
+            for (int i = 1; i < exprList.size(); i++) {
+                out.println(skip(step + 1) + opList.get(i - 1));
+                exprList.get(i).accept(this, step + 1);
+            }
+            out.println(skip(step) + "]");
+        } else {
+            exprList.get(0).accept(this, step);
+        }
+
+    }
+
+    @Override
+    public void visit(IfExpr ifexpr, Integer step) throws AsterixException {
+        out.println(skip(step) + "IfExpr [");
+        out.println(skip(step + 1) + "Condition:");
+        ifexpr.getCondExpr().accept(this, step + 2);
+        out.println(skip(step + 1) + "Then:");
+        ifexpr.getThenExpr().accept(this, step + 2);
+        out.println(skip(step + 1) + "Else:");
+        ifexpr.getElseExpr().accept(this, step + 2);
+        out.println(skip(step) + "]");
+    }
+
+    @Override
+    public void visit(FLWOGRExpression flwor, Integer step) throws AsterixException {
+        out.println(skip(step) + "FLWOGR [");
+        for (Clause cl : flwor.getClauseList()) {
+            cl.accept(this, step + 1);
+        }
+        out.println(skip(step + 1) + "Return");
+        flwor.getReturnExpr().accept(this, step + 2);
+        out.println(skip(step) + "]");
+    }
+
+    @Override
+    public void visit(QuantifiedExpression qe, Integer step) throws AsterixException {
+        out.println(skip(step) + "QuantifiedExpression " + qe.getQuantifier() + " [");
+        // quantifiedList accept visitor
+        for (QuantifiedPair pair : qe.getQuantifiedList()) {
+            out.print(skip(step + 1) + "[");
+            pair.getVarExpr().accept(this, 0);
+            out.println(skip(step + 1) + "In");
+            pair.getExpr().accept(this, step + 2);
+            out.println(skip(step + 1) + "]");
+        }
+        out.println(skip(step + 1) + "Satifies [");
+        qe.getSatisfiesExpr().accept(this, step + 2);
+        out.println(skip(step + 1) + "]");// for satifies
+        out.println(skip(step) + "]");// for quantifiedExpr
+    }
+
+    @Override
+    public void visit(ForClause fc, Integer step) throws AsterixException {
+        out.print(skip(step) + "For ");
+        fc.getVarExpr().accept(this, 0);
+        out.println(skip(step + 1) + "In ");
+        fc.getInExpr().accept(this, step + 1);
+    }
+
+    @Override
+    public void visit(LetClause lc, Integer step) throws AsterixException {
+        out.print(skip(step) + "Let ");
+        lc.getVarExpr().accept(this, 0);
+        out.println(skip(step + 1) + ":= ");
+        lc.getBindingExpr().accept(this, step + 1);
+    }
+
+    @Override
+    public void visit(WhereClause wc, Integer step) throws AsterixException {
+        out.println(skip(step) + "Where ");
+        wc.getWhereExpr().accept(this, step + 1);
+    }
+
+    @Override
+    public void visit(OrderbyClause oc, Integer step) throws AsterixException {
+        out.println(skip(step) + "Orderby");
+        List<OrderModifier> mlist = oc.getModifierList();
+        List<Expression> list = oc.getOrderbyList();
+        for (int i = 0; i < list.size(); i++) {
+            list.get(i).accept(this, step + 1);
+            out.println(skip(step + 1) + mlist.get(i).toString());
+        }
+        out.println(skip(step));
+    }
+
+    @Override
+    public void visit(GroupbyClause gc, Integer step) throws AsterixException {
+        out.println(skip(step) + "Groupby");
+        for (GbyVariableExpressionPair pair : gc.getGbyPairList()) {
+
+            if (pair.getVar() != null) {
+                pair.getVar().accept(this, step + 1);
+                out.println(skip(step + 1) + ":=");
+            }
+
+            pair.getExpr().accept(this, step + 1);
+        }
+        if (!gc.getDecorPairList().isEmpty()) {
+            out.println(skip(step + 1) + "Decor");
+            for (GbyVariableExpressionPair pair : gc.getDecorPairList()) {
+                if (pair.getVar() != null) {
+                    pair.getVar().accept(this, step + 1);
+                    out.println(skip(step + 1) + ":=");
+                }
+                pair.getExpr().accept(this, step + 1);
+            }
+        }
+        out.println(skip(step + 1) + "With");
+        for (VariableExpr exp : gc.getWithVarList()) {
+            exp.accept(this, step + 1);
+        }
+        out.println(skip(step));
+    }
+
+    @Override
+    public void visit(LimitClause lc, Integer step) throws AsterixException {
+        out.println(skip(step) + "Limit");
+        lc.getLimitExpr().accept(this, step + 1);
+        if (lc.getOffset() != null) {
+            out.println(skip(step + 1) + "Offset");
+            lc.getOffset().accept(this, step + 2);
+        }
+    }
+
+    @Override
+    public void visit(DieClause lc, Integer step) throws AsterixException {
+        out.println(skip(step) + "Limit");
+        lc.getDieExpr().accept(this, step + 1);
+    }
+
+    @Override
+    public void visit(FunctionDecl fd, Integer step) throws AsterixException {
+        out.println(skip(step) + "FunctionDecl " + fd.getIdent().getValue() + "(" + fd.getParamList().toString()
+                + ") {");
+        fd.getFuncBody().accept(this, step + 1);
+        out.println(skip(step) + "}");
+        out.println();
+    }
+
+    @Override
+    public void visit(UnaryExpr u, Integer step) throws AsterixException {
+        if (u.getSign() != null) {
+            out.print(skip(step) + u.getSign() + " ");
+            u.getExpr().accept(this, 0);
+        } else
+            u.getExpr().accept(this, step);
+    }
+
+    @Override
+    public void visit(FieldAccessor fa, Integer step) throws AsterixException {
+        out.println(skip(step) + "FieldAccessor [");
+        fa.getExpr().accept(this, step + 1);
+        out.println(skip(step + 1) + "Field=" + ((FieldAccessor) fa).getIdent().getValue());
+        out.println(skip(step) + "]");
+
+    }
+
+    @Override
+    public void visit(IndexAccessor fa, Integer step) throws AsterixException {
+        out.println(skip(step) + "IndexAccessor [");
+        fa.getExpr().accept(this, step + 1);
+        out.print(skip(step + 1) + "Index: ");
+        out.println((((IndexAccessor) fa).isAny() ? "ANY" : ((IndexAccessor) fa).getIndex()));
+
+        out.println(skip(step) + "]");
+
+    }
+
+    @Override
+    public void visit(TypeDecl t, Integer step) throws AsterixException {
+        out.println(skip(step) + "TypeDecl " + t.getIdent() + " [");
+        t.getTypeDef().accept(this, step + 1);
+        out.println(skip(step) + "]");
+    }
+
+    @Override
+    public void visit(TypeReferenceExpression t, Integer arg) throws AsterixException {
+        out.print(t.getIdent());
+    }
+
+    @Override
+    public void visit(RecordTypeDefinition r, Integer step) throws AsterixException {
+        if (r.getRecordKind() == RecordKind.CLOSED) {
+            out.print(skip(step) + "closed ");
+        } else {
+            out.print(skip(step) + "open ");
+        }
+        out.println("RecordType {");
+        Iterator<String> nameIter = r.getFieldNames().iterator();
+        Iterator<TypeExpression> typeIter = r.getFieldTypes().iterator();
+        Iterator<Boolean> isnullableIter = r.getNullableFields().iterator();
+        boolean first = true;
+        while (nameIter.hasNext()) {
+            if (first) {
+                first = false;
+            } else {
+                out.println(",");
+            }
+            String name = nameIter.next();
+            TypeExpression texp = typeIter.next();
+            Boolean isNullable = isnullableIter.next();
+            out.print(skip(step + 1) + name + " : ");
+            texp.accept(this, step + 2);
+            if (isNullable) {
+                out.print("?");
+            }
+        }
+        out.println();
+        out.println(skip(step) + "}");
+    }
+
+    @Override
+    public void visit(OrderedListTypeDefinition x, Integer step) throws AsterixException {
+        out.print("OrderedList [");
+        x.getItemTypeExpression().accept(this, step + 2);
+        out.println("]");
+    }
+
+    @Override
+    public void visit(UnorderedListTypeDefinition x, Integer step) throws AsterixException {
+        out.print("UnorderedList <");
+        x.getItemTypeExpression().accept(this, step + 2);
+        out.println(">");
+    }
+
+    @Override
+    public void visit(DatasetDecl dd, Integer step) throws AsterixException {
+        if (dd.getDatasetType() == DatasetType.INTERNAL) {
+            out.println(skip(step) + "DatasetDecl" + dd.getName() + "(" + dd.getItemTypeName() + ")"
+                    + " partitioned by " + ((InternalDetailsDecl) dd.getDatasetDetailsDecl()).getPartitioningExprs());
+        } else if (dd.getDatasetType() == DatasetType.EXTERNAL) {
+            out.println(skip(step) + "DatasetDecl" + dd.getName() + "(" + dd.getItemTypeName() + ")"
+                    + "is an external dataset");
+        } else if (dd.getDatasetType() == DatasetType.FEED) {
+            out.println(skip(step) + "DatasetDecl" + dd.getName() + "(" + dd.getItemTypeName() + ")"
+                    + "is an feed dataset");
+        }
+    }
+
+    @Override
+    public void visit(DataverseDecl dv, Integer step) throws AsterixException {
+        out.println(skip(step) + "DataverseUse " + dv.getDataverseName());
+    }
+
+    @Override
+    public void visit(NodegroupDecl ngd, Integer step) throws AsterixException {
+        out.println(skip(step) + "Nodegroup " + ngd.getNodeControllerNames());
+    }
+
+    @Override
+    public void visit(LoadFromFileStatement stmtLoad, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void visit(WriteFromQueryResultStatement stmtLoad, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void visit(DropStatement stmtDel, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void visit(WriteStatement ws, Integer step) throws AsterixException {
+        out.print(skip(step) + "WriteOutputTo " + ws.getNcName() + ":" + ws.getFileName());
+        if (ws.getWriterClassName() != null) {
+            out.print(" using " + ws.getWriterClassName());
+        }
+        out.println();
+    }
+
+    @Override
+    public void visit(SetStatement ss, Integer step) throws AsterixException {
+        out.println(skip(step) + "Set " + ss.getPropName() + "=" + ss.getPropValue());
+    }
+
+    @Override
+    public void visit(CreateIndexStatement cis, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void visit(ControlFeedStatement ss, Integer step) throws AsterixException {
+        out.println(skip(step) + ss.getOperationType() + skip(step) + ss.getDatasetName());
+    }
+
+    @Override
+    public void visit(UnionExpr u, Integer step) throws AsterixException {
+        out.println(skip(step) + "Union [");
+        for (Expression expr : u.getExprs()) {
+            expr.accept(this, step + 1);
+        }
+        out.println(skip(step) + "]");
+    }
+
+    @Override
+    public void visit(DistinctClause dc, Integer step) throws AsterixException {
+        out.print(skip(step) + "Distinct ");
+        for (Expression expr : dc.getDistinctByExpr())
+            expr.accept(this, step + 1);
+    }
+
+    @Override
+    public void visit(InsertStatement stmtDel, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void visit(DeleteStatement stmtDel, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void visit(UpdateStatement stmtDel, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void visit(UpdateClause updateClause, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void visit(CreateDataverseStatement stmtDel, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void visit(IndexDropStatement stmtDel, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void visit(NodeGroupDropStatement deleteStatement, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void visit(DataverseDropStatement deleteStatement, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void visit(TypeDropStatement deleteStatement, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void visit(CreateFunctionStatement cfs, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void visit(FunctionDropStatement fds, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void visit(BeginFeedStatement stmtDel, Integer arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/IAqlExpressionVisitor.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/IAqlExpressionVisitor.java
new file mode 100644
index 0000000..6c8b844
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/IAqlExpressionVisitor.java
@@ -0,0 +1,159 @@
+package edu.uci.ics.asterix.aql.expression.visitor;
+
+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.CreateDataverseStatement;
+import edu.uci.ics.asterix.aql.expression.CreateFunctionStatement;
+import edu.uci.ics.asterix.aql.expression.CreateIndexStatement;
+import edu.uci.ics.asterix.aql.expression.DatasetDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDropStatement;
+import edu.uci.ics.asterix.aql.expression.DeleteStatement;
+import edu.uci.ics.asterix.aql.expression.DieClause;
+import edu.uci.ics.asterix.aql.expression.DistinctClause;
+import edu.uci.ics.asterix.aql.expression.DropStatement;
+import edu.uci.ics.asterix.aql.expression.FLWOGRExpression;
+import edu.uci.ics.asterix.aql.expression.FieldAccessor;
+import edu.uci.ics.asterix.aql.expression.ForClause;
+import edu.uci.ics.asterix.aql.expression.FunctionDecl;
+import edu.uci.ics.asterix.aql.expression.FunctionDropStatement;
+import edu.uci.ics.asterix.aql.expression.GroupbyClause;
+import edu.uci.ics.asterix.aql.expression.IfExpr;
+import edu.uci.ics.asterix.aql.expression.IndexAccessor;
+import edu.uci.ics.asterix.aql.expression.IndexDropStatement;
+import edu.uci.ics.asterix.aql.expression.InsertStatement;
+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.LiteralExpr;
+import edu.uci.ics.asterix.aql.expression.LoadFromFileStatement;
+import edu.uci.ics.asterix.aql.expression.NodeGroupDropStatement;
+import edu.uci.ics.asterix.aql.expression.NodegroupDecl;
+import edu.uci.ics.asterix.aql.expression.OperatorExpr;
+import edu.uci.ics.asterix.aql.expression.OrderbyClause;
+import edu.uci.ics.asterix.aql.expression.OrderedListTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.QuantifiedExpression;
+import edu.uci.ics.asterix.aql.expression.Query;
+import edu.uci.ics.asterix.aql.expression.RecordConstructor;
+import edu.uci.ics.asterix.aql.expression.RecordTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.SetStatement;
+import edu.uci.ics.asterix.aql.expression.TypeDecl;
+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.UnionExpr;
+import edu.uci.ics.asterix.aql.expression.UnorderedListTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.UpdateClause;
+import edu.uci.ics.asterix.aql.expression.UpdateStatement;
+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.WriteStatement;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+
+public interface IAqlExpressionVisitor<R, T> {
+
+    R visitQuery(Query q, T arg) throws AsterixException;
+
+    R visitFunctionDecl(FunctionDecl fd, T arg) throws AsterixException;
+
+    R visitTypeDecl(TypeDecl td, T arg) throws AsterixException;
+
+    R visitNodegroupDecl(NodegroupDecl ngd, T arg) throws AsterixException;
+
+    R visitDatasetDecl(DatasetDecl dd, T arg) throws AsterixException;
+
+    R visitLoadFromFileStatement(LoadFromFileStatement stmtLoad, T arg) throws AsterixException;
+
+    R visitLoadFromQueryResultStatement(WriteFromQueryResultStatement stmtLoad, T arg) throws AsterixException;
+
+    R visitDropStatement(DropStatement del, T arg) throws AsterixException;
+
+    R visitInsertStatement(InsertStatement insert, T arg) throws AsterixException;
+
+    R visitDeleteStatement(DeleteStatement del, T arg) throws AsterixException;
+
+    R visitUpdateStatement(UpdateStatement update, T arg) throws AsterixException;
+
+    R visitUpdateClause(UpdateClause del, T arg) throws AsterixException;
+
+    R visitTypeReferenceExpression(TypeReferenceExpression tre, T arg) throws AsterixException;
+
+    R visitRecordTypeDefiniton(RecordTypeDefinition tre, T arg) throws AsterixException;
+
+    R visitOrderedListTypeDefiniton(OrderedListTypeDefinition olte, T arg) throws AsterixException;
+
+    R visitUnorderedListTypeDefiniton(UnorderedListTypeDefinition ulte, T arg) throws AsterixException;
+
+    R visitLiteralExpr(LiteralExpr l, T arg) throws AsterixException;
+
+    R visitVariableExpr(VariableExpr v, T arg) throws AsterixException;
+
+    R visitListConstructor(ListConstructor lc, T arg) throws AsterixException;
+
+    R visitRecordConstructor(RecordConstructor rc, T arg) throws AsterixException;
+
+    R visitOperatorExpr(OperatorExpr ifbo, T arg) throws AsterixException;
+
+    R visitFieldAccessor(FieldAccessor fa, T arg) throws AsterixException;
+
+    R visitIndexAccessor(IndexAccessor ia, T arg) throws AsterixException;
+
+    R visitIfExpr(IfExpr ifexpr, T arg) throws AsterixException;
+
+    R visitFlworExpression(FLWOGRExpression flwor, T arg) throws AsterixException;
+
+    R visitQuantifiedExpression(QuantifiedExpression qe, T arg) throws AsterixException;
+
+    R visitForClause(ForClause fc, T arg) throws AsterixException;
+
+    R visitLetClause(LetClause lc, T arg) throws AsterixException;
+
+    R visitWhereClause(WhereClause wc, T arg) throws AsterixException;
+
+    R visitOrderbyClause(OrderbyClause oc, T arg) throws AsterixException;
+
+    R visitGroupbyClause(GroupbyClause gc, T arg) throws AsterixException;
+
+    R visitLimitClause(LimitClause lc, T arg) throws AsterixException;
+
+    R visitDistinctClause(DistinctClause dc, T arg) throws AsterixException;
+
+    R visitUnaryExpr(UnaryExpr u, T arg) throws AsterixException;
+
+    R visitUnionExpr(UnionExpr u, T arg) throws AsterixException;
+
+    R visitCreateIndexStatement(CreateIndexStatement cis, T arg) throws AsterixException;
+
+    R visitCreateDataverseStatement(CreateDataverseStatement del, T arg) throws AsterixException;
+
+    R visitIndexDropStatement(IndexDropStatement del, T arg) throws AsterixException;
+
+    R visitNodeGroupDropStatement(NodeGroupDropStatement del, T arg) throws AsterixException;
+
+    R visitDataverseDropStatement(DataverseDropStatement del, T arg) throws AsterixException;
+
+    R visitTypeDropStatement(TypeDropStatement del, T arg) throws AsterixException;
+
+    R visitWriteStatement(WriteStatement ws, T arg) throws AsterixException;
+
+    R visitSetStatement(SetStatement ss, T arg) throws AsterixException;
+
+    R visitBeginFeedStatement(BeginFeedStatement bf, T arg) throws AsterixException;
+    
+    R visitControlFeedStatement(ControlFeedStatement del, T arg) throws AsterixException;
+
+    R visitCallExpr(CallExpr pf, T arg) throws AsterixException;
+
+    R visitDataverseDecl(DataverseDecl dv, T arg) throws AsterixException;
+
+    R visitWriteFromQueryResultStatement(WriteFromQueryResultStatement stmtLoad, T arg) throws AsterixException;
+
+    R visitDieClause(DieClause stmtLoad, T arg) throws AsterixException;
+
+    R visit(CreateFunctionStatement cfs, T arg) throws AsterixException;
+
+    R visitFunctionDropStatement(FunctionDropStatement del, T arg) throws AsterixException;
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/IAqlPlusExpressionVisitor.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/IAqlPlusExpressionVisitor.java
new file mode 100644
index 0000000..3e33473
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/IAqlPlusExpressionVisitor.java
@@ -0,0 +1,14 @@
+package edu.uci.ics.asterix.aql.expression.visitor;
+
+import edu.uci.ics.asterix.aql.expression.JoinClause;
+import edu.uci.ics.asterix.aql.expression.MetaVariableClause;
+import edu.uci.ics.asterix.aql.expression.MetaVariableExpr;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+
+public interface IAqlPlusExpressionVisitor<R, T> extends IAqlExpressionVisitor<R, T> {
+    R visitJoinClause(JoinClause c, T arg) throws AsterixException;
+
+    R visitMetaVariableClause(MetaVariableClause c, T arg) throws AsterixException;
+
+    R visitMetaVariableExpr(MetaVariableExpr v, T arg) throws AsterixException;
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/IAqlVisitorWithVoidReturn.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/IAqlVisitorWithVoidReturn.java
new file mode 100644
index 0000000..d4891ac
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/expression/visitor/IAqlVisitorWithVoidReturn.java
@@ -0,0 +1,156 @@
+package edu.uci.ics.asterix.aql.expression.visitor;
+
+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.CreateDataverseStatement;
+import edu.uci.ics.asterix.aql.expression.CreateFunctionStatement;
+import edu.uci.ics.asterix.aql.expression.CreateIndexStatement;
+import edu.uci.ics.asterix.aql.expression.DatasetDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDropStatement;
+import edu.uci.ics.asterix.aql.expression.DeleteStatement;
+import edu.uci.ics.asterix.aql.expression.DieClause;
+import edu.uci.ics.asterix.aql.expression.DistinctClause;
+import edu.uci.ics.asterix.aql.expression.DropStatement;
+import edu.uci.ics.asterix.aql.expression.FLWOGRExpression;
+import edu.uci.ics.asterix.aql.expression.FieldAccessor;
+import edu.uci.ics.asterix.aql.expression.ForClause;
+import edu.uci.ics.asterix.aql.expression.FunctionDecl;
+import edu.uci.ics.asterix.aql.expression.FunctionDropStatement;
+import edu.uci.ics.asterix.aql.expression.GroupbyClause;
+import edu.uci.ics.asterix.aql.expression.IfExpr;
+import edu.uci.ics.asterix.aql.expression.IndexAccessor;
+import edu.uci.ics.asterix.aql.expression.IndexDropStatement;
+import edu.uci.ics.asterix.aql.expression.InsertStatement;
+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.LiteralExpr;
+import edu.uci.ics.asterix.aql.expression.LoadFromFileStatement;
+import edu.uci.ics.asterix.aql.expression.NodeGroupDropStatement;
+import edu.uci.ics.asterix.aql.expression.NodegroupDecl;
+import edu.uci.ics.asterix.aql.expression.OperatorExpr;
+import edu.uci.ics.asterix.aql.expression.OrderbyClause;
+import edu.uci.ics.asterix.aql.expression.OrderedListTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.QuantifiedExpression;
+import edu.uci.ics.asterix.aql.expression.Query;
+import edu.uci.ics.asterix.aql.expression.RecordConstructor;
+import edu.uci.ics.asterix.aql.expression.RecordTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.SetStatement;
+import edu.uci.ics.asterix.aql.expression.TypeDecl;
+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.UnionExpr;
+import edu.uci.ics.asterix.aql.expression.UnorderedListTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.UpdateClause;
+import edu.uci.ics.asterix.aql.expression.UpdateStatement;
+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.WriteStatement;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+
+public interface IAqlVisitorWithVoidReturn<T> {
+
+    void visit(Query q, T arg) throws AsterixException;
+
+    void visit(FunctionDecl fd, T arg) throws AsterixException;
+
+    void visit(TypeDecl t, T arg) throws AsterixException;
+
+    void visit(NodegroupDecl ngd, T arg) throws AsterixException;
+
+    void visit(DropStatement stmtDel, T arg) throws AsterixException;
+
+    void visit(LoadFromFileStatement stmtLoad, T arg) throws AsterixException;
+
+    void visit(InsertStatement stmtInsert, T arg) throws AsterixException;
+
+    void visit(DeleteStatement stmtDelete, T arg) throws AsterixException;
+
+    void visit(UpdateStatement stmtUpdate, T arg) throws AsterixException;
+
+    void visit(UpdateClause updateClause, T arg) throws AsterixException;
+
+    void visit(WriteFromQueryResultStatement stmtLoad, T arg) throws AsterixException;
+
+    void visit(DatasetDecl dd, T arg) throws AsterixException;
+
+    void visit(LiteralExpr l, T arg) throws AsterixException;
+
+    void visit(VariableExpr v, T arg) throws AsterixException;
+
+    void visit(ListConstructor lc, T arg) throws AsterixException;
+
+    void visit(RecordConstructor rc, T arg) throws AsterixException;
+
+    void visit(CallExpr pf, T arg) throws AsterixException;
+
+    void visit(OperatorExpr ifbo, T arg) throws AsterixException;
+
+    void visit(FieldAccessor fa, T arg) throws AsterixException;
+
+    void visit(IndexAccessor fa, T arg) throws AsterixException;
+
+    void visit(IfExpr ifexpr, T arg) throws AsterixException;
+
+    void visit(FLWOGRExpression flwor, T arg) throws AsterixException;
+
+    void visit(QuantifiedExpression qe, T arg) throws AsterixException;
+
+    void visit(ForClause fc, T arg) throws AsterixException;
+
+    void visit(LetClause lc, T arg) throws AsterixException;
+
+    void visit(WhereClause wc, T arg) throws AsterixException;
+
+    void visit(OrderbyClause oc, T arg) throws AsterixException;
+
+    void visit(GroupbyClause gc, T arg) throws AsterixException;
+
+    void visit(LimitClause lc, T arg) throws AsterixException;
+
+    void visit(DistinctClause dc, T arg) throws AsterixException;
+
+    void visit(UnaryExpr u, T arg) throws AsterixException;
+
+    void visit(UnionExpr u, T arg) throws AsterixException;
+
+    void visit(TypeReferenceExpression t, T arg) throws AsterixException;
+
+    void visit(RecordTypeDefinition r, T arg) throws AsterixException;
+
+    void visit(OrderedListTypeDefinition x, T arg) throws AsterixException;
+
+    void visit(UnorderedListTypeDefinition x, T arg) throws AsterixException;
+
+    void visit(DataverseDecl dv, T arg) throws AsterixException;
+
+    void visit(SetStatement ss, T arg) throws AsterixException;
+
+    void visit(WriteStatement ws, T arg) throws AsterixException;
+
+    void visit(CreateIndexStatement cis, T arg) throws AsterixException;
+
+    void visit(CreateDataverseStatement cdvStmt, T arg) throws AsterixException;
+
+    void visit(IndexDropStatement stmtDel, T arg) throws AsterixException;
+
+    void visit(NodeGroupDropStatement stmtDel, T arg) throws AsterixException;
+
+    void visit(DataverseDropStatement stmtDel, T arg) throws AsterixException;
+
+    void visit(TypeDropStatement stmtDel, T arg) throws AsterixException;
+    
+    void visit(BeginFeedStatement stmtDel, T arg) throws AsterixException;
+
+    void visit(ControlFeedStatement stmtDel, T arg) throws AsterixException;
+
+    void visit(DieClause stmtDel, T arg) throws AsterixException;
+
+    void visit(CreateFunctionStatement cfs, T arg) throws AsterixException;
+
+    void visit(FunctionDropStatement fds, T arg) throws AsterixException;
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/DoubleLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/DoubleLiteral.java
new file mode 100644
index 0000000..d35f5f3
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/DoubleLiteral.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2009-2010 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.aql.literal;
+
+import edu.uci.ics.asterix.aql.base.ILiteral;
+
+public class DoubleLiteral implements ILiteral {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -5685491458356989250L;
+    private Double value;
+
+    public DoubleLiteral(Double value) {
+        super();
+        this.value = value;
+    }
+
+    public Double getValue() {
+        return value;
+    }
+
+    public void setValue(Double value) {
+        this.value = value;
+    }
+
+    @Override
+    public Type getLiteralType() {
+        return Type.DOUBLE;
+    }
+
+    @Override
+    public String getStringValue() {
+        return value.toString();
+    }
+
+    @Override
+    public String toString() {
+        return getStringValue();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof DoubleLiteral)) {
+            return false;
+        }
+        DoubleLiteral d = (DoubleLiteral) obj;
+        return d.getValue() == value;
+    }
+
+    @Override
+    public int hashCode() {
+        return value.hashCode();
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FalseLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FalseLiteral.java
new file mode 100644
index 0000000..17b4254
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FalseLiteral.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2009-2010 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.aql.literal;
+
+import edu.uci.ics.asterix.aql.base.ILiteral;
+
+public class FalseLiteral implements ILiteral {
+
+    private static final long serialVersionUID = -750814844423165149L;
+
+    private FalseLiteral() {
+    }
+
+    public final static FalseLiteral INSTANCE = new FalseLiteral();
+
+    @Override
+    public Type getLiteralType() {
+        return Type.FALSE;
+    }
+
+    @Override
+    public String getStringValue() {
+        return "false";
+    }
+
+    @Override
+    public String toString() {
+        return getStringValue();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj == INSTANCE;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) serialVersionUID;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FloatLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FloatLiteral.java
new file mode 100644
index 0000000..f77ed39
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/FloatLiteral.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2009-2010 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.aql.literal;
+
+import edu.uci.ics.asterix.aql.base.ILiteral;
+
+public class FloatLiteral implements ILiteral {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 3273563021227964396L;
+    private Float value;
+
+    public FloatLiteral(Float value) {
+        super();
+        this.value = value;
+    }
+
+    public Float getValue() {
+        return value;
+    }
+
+    public void setValue(Float value) {
+        this.value = value;
+    }
+
+    @Override
+    public Type getLiteralType() {
+        return Type.FLOAT;
+    }
+
+    @Override
+    public String getStringValue() {
+        return value.toString();
+    }
+
+    @Override
+    public String toString() {
+        return getStringValue();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof FloatLiteral)) {
+            return false;
+        }
+        FloatLiteral f = (FloatLiteral) obj;
+        return f.getValue() == value;
+    }
+
+    @Override
+    public int hashCode() {
+        return value.hashCode();
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/IntegerLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/IntegerLiteral.java
new file mode 100644
index 0000000..52cf7fa
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/IntegerLiteral.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2009-2010 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.aql.literal;
+
+import edu.uci.ics.asterix.aql.base.ILiteral;
+
+public class IntegerLiteral implements ILiteral {
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -8633520244871361967L;
+    private Integer value;
+
+    public IntegerLiteral(Integer value) {
+        super();
+        this.value = value;
+    }
+
+    public Integer getValue() {
+        return value;
+    }
+
+    public void setValue(Integer value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return getStringValue();
+    }
+
+    @Override
+    public Type getLiteralType() {
+        return Type.INTEGER;
+    }
+
+    @Override
+    public String getStringValue() {
+        return value.toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof IntegerLiteral)) {
+            return false;
+        }
+        IntegerLiteral i = (IntegerLiteral) obj;
+        return value.equals(i.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+        return value;
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/NullLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/NullLiteral.java
new file mode 100644
index 0000000..b421afa
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/NullLiteral.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2009-2010 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.aql.literal;
+
+import edu.uci.ics.asterix.aql.base.ILiteral;
+
+public class NullLiteral implements ILiteral {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -7782153599294838739L;
+
+    private NullLiteral() {
+    }
+
+    public final static NullLiteral INSTANCE = new NullLiteral();
+
+    @Override
+    public Type getLiteralType() {
+        return Type.NULL;
+    }
+
+    @Override
+    public String getStringValue() {
+        return "null";
+    }
+
+    @Override
+    public String toString() {
+        return getStringValue();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj == INSTANCE;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) serialVersionUID;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/StringLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/StringLiteral.java
new file mode 100644
index 0000000..ad5588f
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/StringLiteral.java
@@ -0,0 +1,52 @@
+package edu.uci.ics.asterix.aql.literal;
+
+import edu.uci.ics.asterix.aql.base.ILiteral;
+
+public class StringLiteral implements ILiteral {
+
+    private static final long serialVersionUID = -6342491706277606168L;
+    private String value;
+
+    public StringLiteral(String value) {
+        super();
+        this.value = value;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public Type getLiteralType() {
+        return Type.STRING;
+    }
+
+    @Override
+    public String getStringValue() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return getStringValue();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof StringLiteral)) {
+            return false;
+        }
+        StringLiteral s = (StringLiteral) obj;
+        return value.equals(s.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+        return value.hashCode();
+    }
+
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/TrueLiteral.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/TrueLiteral.java
new file mode 100644
index 0000000..dedd52b
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/literal/TrueLiteral.java
@@ -0,0 +1,37 @@
+package edu.uci.ics.asterix.aql.literal;
+
+import edu.uci.ics.asterix.aql.base.ILiteral;
+
+public class TrueLiteral implements ILiteral {
+    private static final long serialVersionUID = -8513245514578847512L;
+
+    private TrueLiteral() {
+    }
+
+    public final static TrueLiteral INSTANCE = new TrueLiteral();
+
+    @Override
+    public Type getLiteralType() {
+        return Type.TRUE;
+    }
+
+    @Override
+    public String getStringValue() {
+        return "true";
+    }
+
+    @Override
+    public String toString() {
+        return getStringValue();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj == INSTANCE;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) serialVersionUID;
+    }
+}
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
new file mode 100644
index 0000000..51537e3
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/parser/ScopeChecker.java
@@ -0,0 +1,140 @@
+package edu.uci.ics.asterix.aql.parser;
+
+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.hyracks.algebricks.core.algebra.base.Counter;
+
+public abstract class ScopeChecker {
+
+    protected Counter varCounter = new Counter(-1);
+
+    protected Stack<Scope> scopeStack = new Stack<Scope>();
+
+    protected Stack<Scope> forbiddenScopeStack = new Stack<Scope>();
+
+    // Forbidden scopes are used to disallow, in a limit clause, variables
+    // having the same name as a variable defined by the FLWOR in which that
+    // limit clause appears.
+
+    /**
+     * Create a new scope, using the top scope in scopeStack as parent scope
+     * 
+     * @param scopeStack
+     * @return new scope
+     */
+    public final Scope createNewScope() {
+        Scope scope = new Scope(this, scopeStack.peek());// top one as parent
+        scopeStack.push(scope);
+        return scope;
+    }
+
+    /**
+     * Extend the current scope
+     * 
+     * @param scopeStack
+     * @return
+     */
+    public final Scope extendCurrentScope() {
+        return extendCurrentScope(false);
+    }
+
+    public final Scope extendCurrentScope(boolean maskParentScope) {
+        Scope scope = extendCurrentScopeNoPush(maskParentScope);
+        scopeStack.pop();
+        scopeStack.push(scope);
+        return scope;
+    }
+
+    public final Scope extendCurrentScopeNoPush(boolean maskParentScope) {
+        Scope scope = scopeStack.peek();
+        scope = new Scope(this, scope, maskParentScope);
+        return scope;
+    }
+
+    public final void replaceCurrentScope(Scope scope) {
+        scopeStack.pop();
+        scopeStack.push(scope);
+    }
+
+    /**
+     * Remove current scope
+     * 
+     * @return
+     */
+    public final Scope removeCurrentScope() {
+        return scopeStack.pop();
+    }
+
+    /**
+     * get current scope
+     * 
+     * @return
+     */
+    public final Scope getCurrentScope() {
+        return scopeStack.peek();
+    }
+
+    /**
+     * find symbol in the scope
+     * 
+     * @return identifier
+     */
+    public final Identifier lookupSymbol(String name) {
+        if (name != null) {
+            return getCurrentScope().findSymbol(name);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * find FunctionSignature in the scope
+     * 
+     * @return functionDescriptor
+     */
+    public final FunIdentifier lookupFunctionSignature(String name, int arity) {
+        if (name != null) {
+            return getCurrentScope().findFunctionSignature(name, arity);
+        } else {
+            return null;
+        }
+    }
+
+    public final int getVarCounter() {
+        return varCounter.get();
+    }
+
+    public final void setVarCounter(Counter varCounter) {
+        this.varCounter = varCounter;
+    }
+
+    public final void incVarCounter() {
+        varCounter.inc();
+    }
+
+    public final void pushForbiddenScope(Scope s) {
+        forbiddenScopeStack.push(s);
+    }
+
+    public final void popForbiddenScope() {
+        forbiddenScopeStack.pop();
+    }
+
+    public final boolean isInForbiddenScopes(String ident) {
+        for (Scope s : forbiddenScopeStack) {
+            if (s.findLocalSymbol(ident) != null) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static final String removeQuotesAndEscapes(String s) {
+        char q = s.charAt(0); // simple or double quote
+        String stripped = s.substring(1, s.length() - 1);
+        return stripped.replaceAll("\\\\" + q, "\\" + q);
+    }
+}
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
new file mode 100644
index 0000000..5f03cca1
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/AqlRewriter.java
@@ -0,0 +1,599 @@
+package edu.uci.ics.asterix.aql.rewrites;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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.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.CreateDataverseStatement;
+import edu.uci.ics.asterix.aql.expression.CreateFunctionStatement;
+import edu.uci.ics.asterix.aql.expression.CreateIndexStatement;
+import edu.uci.ics.asterix.aql.expression.DatasetDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDropStatement;
+import edu.uci.ics.asterix.aql.expression.DeleteStatement;
+import edu.uci.ics.asterix.aql.expression.DieClause;
+import edu.uci.ics.asterix.aql.expression.DistinctClause;
+import edu.uci.ics.asterix.aql.expression.DropStatement;
+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.FunctionDecl;
+import edu.uci.ics.asterix.aql.expression.FunctionDropStatement;
+import edu.uci.ics.asterix.aql.expression.GbyVariableExpressionPair;
+import edu.uci.ics.asterix.aql.expression.GroupbyClause;
+import edu.uci.ics.asterix.aql.expression.IfExpr;
+import edu.uci.ics.asterix.aql.expression.IndexAccessor;
+import edu.uci.ics.asterix.aql.expression.IndexDropStatement;
+import edu.uci.ics.asterix.aql.expression.InsertStatement;
+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.LiteralExpr;
+import edu.uci.ics.asterix.aql.expression.LoadFromFileStatement;
+import edu.uci.ics.asterix.aql.expression.NodeGroupDropStatement;
+import edu.uci.ics.asterix.aql.expression.NodegroupDecl;
+import edu.uci.ics.asterix.aql.expression.OperatorExpr;
+import edu.uci.ics.asterix.aql.expression.OrderbyClause;
+import edu.uci.ics.asterix.aql.expression.OrderedListTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.QuantifiedExpression;
+import edu.uci.ics.asterix.aql.expression.QuantifiedPair;
+import edu.uci.ics.asterix.aql.expression.Query;
+import edu.uci.ics.asterix.aql.expression.RecordConstructor;
+import edu.uci.ics.asterix.aql.expression.RecordTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.SetStatement;
+import edu.uci.ics.asterix.aql.expression.TypeDecl;
+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.UnionExpr;
+import edu.uci.ics.asterix.aql.expression.UnorderedListTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.UpdateClause;
+import edu.uci.ics.asterix.aql.expression.UpdateStatement;
+import edu.uci.ics.asterix.aql.expression.VarIdentifier;
+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.WriteStatement;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
+import edu.uci.ics.asterix.aql.util.FunctionUtil;
+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.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+
+public final class AqlRewriter {
+
+    private Query topExpr;
+    private AqlRewritingContext context;
+    private MetadataTransactionContext mdTxnCtx;
+    private String dataverseName;
+
+    private enum DfsColor {
+        WHITE, GRAY, BLACK
+    }
+
+    public AqlRewriter(Query topExpr, int varCounter, MetadataTransactionContext txnContext, String dataverseName) {
+        this.topExpr = topExpr;
+        context = new AqlRewritingContext(varCounter);
+        mdTxnCtx = txnContext;
+        this.dataverseName = dataverseName;
+
+    }
+
+    public Query getExpr() {
+        return topExpr;
+    }
+
+    public int getVarCounter() {
+        return context.getVarCounter();
+    }
+
+    public void rewrite() throws AsterixException {
+        wrapInLets();
+        inlineDeclaredUdfs();
+    }
+
+    private void wrapInLets() {
+        // If the top expression of the main statement is not a FLWOR, it wraps
+        // it into a let clause.
+        if (topExpr == null) {
+            return;
+        }
+        Expression body = topExpr.getBody();
+        if (body.getKind() != Kind.FLWOGR_EXPRESSION) {
+            VarIdentifier var = context.newVariable();
+            VariableExpr v = new VariableExpr(var);
+            LetClause c1 = new LetClause(v, body);
+            ArrayList<Clause> clauseList = new ArrayList<Clause>(1);
+            clauseList.add(c1);
+            FLWOGRExpression newBody = new FLWOGRExpression(clauseList, new VariableExpr(var));
+            topExpr.setBody(newBody);
+        }
+    }
+
+    private void inlineDeclaredUdfs() throws AsterixException {
+        if (topExpr == null) {
+            return;
+        }
+        List<FunctionDecl> fdecls = buildFunctionDeclList(topExpr);
+        List<FunIdentifier> funIds = new ArrayList<FunIdentifier>();
+        for (FunctionDecl fdecl : fdecls) {
+            funIds.add(fdecl.getIdent());
+        }
+
+        List<FunctionDecl> otherFDecls = new ArrayList<FunctionDecl>();
+        buildOtherUdfs(topExpr.getBody(), otherFDecls, funIds);
+        fdecls.addAll(otherFDecls);
+        if (!fdecls.isEmpty()) {
+            checkRecursivity(fdecls);
+            InlineUdfsVisitor visitor = new InlineUdfsVisitor(context);
+            while (topExpr.accept(visitor, fdecls)) {
+                // loop until no more changes
+            }
+        }
+    }
+
+    private void buildOtherUdfs(Expression expression, List<FunctionDecl> functionDecls,
+            List<FunIdentifier> declaredFunctions) throws AsterixException {
+        if (expression == null) {
+            return;
+        }
+
+        List<FunIdentifier> functionCalls = getFunctionCalls(expression);
+        for (FunIdentifier funId : functionCalls) {
+            if (AsterixBuiltinFunctions.isBuiltinCompilerFunction(new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+                    funId.getValue(), false))) {
+                continue;
+            }
+
+            if (AsterixBuiltinFunctions.isBuiltinCompilerFunction(new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS,
+                    funId.getValue(), false))) {
+                continue;
+            }
+            
+            if (declaredFunctions != null && declaredFunctions.contains(funId)) {
+                continue;
+            }
+
+            FunctionDecl functionDecl = getFunctionDecl(funId);
+            if (functionDecls.contains(functionDecl)) {
+                throw new AsterixException(" Detected recursvity!");
+            }
+            functionDecls.add(functionDecl);
+            buildOtherUdfs(functionDecl.getFuncBody(), functionDecls, declaredFunctions);
+        }
+    }
+
+    private FunctionDecl getFunctionDecl(FunIdentifier funId) throws AsterixException {
+        Function function = MetadataManager.INSTANCE.getFunction(mdTxnCtx, dataverseName, funId.getValue(), funId
+                .getArity());
+        if (function == null) {
+            throw new AsterixException(" unknown function " + funId);
+        }
+        return FunctionUtil.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>>();
+        GatherFunctionCalls gfc = new GatherFunctionCalls();
+        expression.accept(gfc, null);
+        List<FunIdentifier> 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>>();
+        for (FunctionDecl fd : fdecls) {
+            GatherFunctionCalls gfc = new GatherFunctionCalls();
+            fd.getFuncBody().accept(gfc, null);
+            List<FunIdentifier> calls = gfc.getCalls();
+            arcs.put(fd.getIdent(), calls);
+            color.put(fd.getIdent(), DfsColor.WHITE);
+        }
+        for (FunIdentifier 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 {
+        color.put(a, DfsColor.GRAY);
+        List<FunIdentifier> next = arcs.get(a);
+        if (next != null) {
+            for (FunIdentifier f : next) {
+                DfsColor dc = color.get(f);
+                if (dc == DfsColor.GRAY) {
+                    throw new AsterixException("Recursive function calls, created by calling " + f + " starting from "
+                            + a);
+                }
+                if (dc == DfsColor.WHITE) {
+                    checkRecursivityDfs(f, arcs, color);
+                }
+            }
+        }
+        color.put(a, DfsColor.BLACK);
+    }
+
+    private List<FunctionDecl> buildFunctionDeclList(Query q) {
+        ArrayList<FunctionDecl> fdecls = new ArrayList<FunctionDecl>();
+        for (Statement s : q.getPrologDeclList()) {
+            if (s.getKind() == Statement.Kind.FUNCTION_DECL) {
+                fdecls.add((FunctionDecl) s);
+            }
+        }
+        return fdecls;
+    }
+
+    private static class GatherFunctionCalls implements IAqlExpressionVisitor<Void, Void> {
+
+        private final List<FunIdentifier> calls = new ArrayList<FunIdentifier>();
+
+        public GatherFunctionCalls() {
+        }
+
+        @Override
+        public Void visitCallExpr(CallExpr pf, Void arg) throws AsterixException {
+            calls.add(pf.getIdent());
+            for (Expression e : pf.getExprList()) {
+                e.accept(this, arg);
+            }
+            return null;
+        }
+
+        @Override
+        public Void visitCreateIndexStatement(CreateIndexStatement cis, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitDataverseDecl(DataverseDecl dv, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitDeleteStatement(DeleteStatement del, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitDistinctClause(DistinctClause dc, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitDropStatement(DropStatement del, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitDatasetDecl(DatasetDecl dd, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitFieldAccessor(FieldAccessor fa, Void arg) throws AsterixException {
+            fa.getExpr().accept(this, arg);
+            return null;
+        }
+
+        @Override
+        public Void visitFlworExpression(FLWOGRExpression flwor, Void arg) throws AsterixException {
+            for (Clause c : flwor.getClauseList()) {
+                c.accept(this, arg);
+            }
+            flwor.getReturnExpr().accept(this, arg);
+            return null;
+        }
+
+        @Override
+        public Void visitForClause(ForClause fc, Void arg) throws AsterixException {
+            fc.getInExpr().accept(this, arg);
+            if (fc.getPosVarExpr() != null) {
+                fc.getPosVarExpr().accept(this, arg);
+            }
+            return null;
+        }
+
+        @Override
+        public Void visitFunctionDecl(FunctionDecl fd, Void arg) throws AsterixException {
+            fd.getFuncBody().accept(this, arg);
+            return null;
+        }
+
+        @Override
+        public Void visitGroupbyClause(GroupbyClause gc, Void arg) throws AsterixException {
+            for (GbyVariableExpressionPair p : gc.getGbyPairList()) {
+                p.getExpr().accept(this, arg);
+            }
+            for (GbyVariableExpressionPair p : gc.getDecorPairList()) {
+                p.getExpr().accept(this, arg);
+            }
+            return null;
+        }
+
+        @Override
+        public Void visitIfExpr(IfExpr ifexpr, Void arg) throws AsterixException {
+            ifexpr.getCondExpr().accept(this, arg);
+            ifexpr.getThenExpr().accept(this, arg);
+            ifexpr.getElseExpr().accept(this, arg);
+            return null;
+        }
+
+        @Override
+        public Void visitIndexAccessor(IndexAccessor ia, Void arg) throws AsterixException {
+            ia.getExpr().accept(this, arg);
+            return null;
+        }
+
+        @Override
+        public Void visitInsertStatement(InsertStatement insert, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitLetClause(LetClause lc, Void arg) throws AsterixException {
+            lc.getBindingExpr().accept(this, arg);
+            return null;
+        }
+
+        @Override
+        public Void visitLimitClause(LimitClause lc, Void arg) throws AsterixException {
+            lc.getLimitExpr().accept(this, arg);
+            if (lc.getOffset() != null) {
+                lc.getOffset().accept(this, arg);
+            }
+            return null;
+        }
+
+        @Override
+        public Void visitDieClause(DieClause lc, Void arg) throws AsterixException {
+            lc.getDieExpr().accept(this, arg);
+            return null;
+        }
+
+        @Override
+        public Void visitListConstructor(ListConstructor lc, Void arg) throws AsterixException {
+            for (Expression e : lc.getExprList()) {
+                e.accept(this, arg);
+            }
+            return null;
+        }
+
+        @Override
+        public Void visitLiteralExpr(LiteralExpr l, Void arg) throws AsterixException {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public Void visitLoadFromFileStatement(LoadFromFileStatement stmtLoad, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitNodegroupDecl(NodegroupDecl ngd, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitOperatorExpr(OperatorExpr op, Void arg) throws AsterixException {
+            for (Expression e : op.getExprList()) {
+                e.accept(this, arg);
+            }
+            return null;
+        }
+
+        @Override
+        public Void visitOrderbyClause(OrderbyClause oc, Void arg) throws AsterixException {
+            for (Expression e : oc.getOrderbyList()) {
+                e.accept(this, arg);
+            }
+            return null;
+        }
+
+        @Override
+        public Void visitOrderedListTypeDefiniton(OrderedListTypeDefinition olte, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitQuantifiedExpression(QuantifiedExpression qe, Void arg) throws AsterixException {
+            for (QuantifiedPair qp : qe.getQuantifiedList()) {
+                qp.getExpr().accept(this, arg);
+            }
+            qe.getSatisfiesExpr().accept(this, arg);
+            return null;
+        }
+
+        @Override
+        public Void visitQuery(Query q, Void arg) throws AsterixException {
+            q.getBody().accept(this, arg);
+            return null;
+        }
+
+        @Override
+        public Void visitRecordConstructor(RecordConstructor rc, Void arg) throws AsterixException {
+            for (FieldBinding fb : rc.getFbList()) {
+                fb.getLeftExpr().accept(this, arg);
+                fb.getRightExpr().accept(this, arg);
+            }
+            return null;
+        }
+
+        @Override
+        public Void visitRecordTypeDefiniton(RecordTypeDefinition tre, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitSetStatement(SetStatement ss, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitTypeDecl(TypeDecl td, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitTypeReferenceExpression(TypeReferenceExpression tre, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitUnaryExpr(UnaryExpr u, Void arg) throws AsterixException {
+            u.getExpr().accept(this, arg);
+            return null;
+        }
+
+        @Override
+        public Void visitUnionExpr(UnionExpr u, Void arg) throws AsterixException {
+            for (Expression e : u.getExprs()) {
+                e.accept(this, arg);
+            }
+            return null;
+        }
+
+        @Override
+        public Void visitUnorderedListTypeDefiniton(UnorderedListTypeDefinition ulte, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitUpdateClause(UpdateClause del, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitUpdateStatement(UpdateStatement update, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitVariableExpr(VariableExpr v, Void arg) throws AsterixException {
+            // do nothing
+            return null;
+        }
+
+        @Override
+        public Void visitWhereClause(WhereClause wc, Void arg) throws AsterixException {
+            wc.getWhereExpr().accept(this, arg);
+            return null;
+        }
+
+        @Override
+        public Void visitWriteFromQueryResultStatement(WriteFromQueryResultStatement stmtLoad, Void arg)
+                throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitWriteStatement(WriteStatement ws, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        public List<FunIdentifier> getCalls() {
+            return calls;
+        }
+
+        @Override
+        public Void visitLoadFromQueryResultStatement(WriteFromQueryResultStatement stmtLoad, Void arg)
+                throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitCreateDataverseStatement(CreateDataverseStatement del, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitIndexDropStatement(IndexDropStatement del, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitNodeGroupDropStatement(NodeGroupDropStatement del, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitDataverseDropStatement(DataverseDropStatement del, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitTypeDropStatement(TypeDropStatement del, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitControlFeedStatement(ControlFeedStatement del, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visit(CreateFunctionStatement cfs, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitFunctionDropStatement(FunctionDropStatement del, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Void visitBeginFeedStatement(BeginFeedStatement bf, Void arg) throws AsterixException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/AqlRewritingContext.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/AqlRewritingContext.java
new file mode 100644
index 0000000..ed40e85
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/AqlRewritingContext.java
@@ -0,0 +1,44 @@
+package edu.uci.ics.asterix.aql.rewrites;
+
+import java.util.HashMap;
+
+import edu.uci.ics.asterix.aql.expression.VarIdentifier;
+
+public final class AqlRewritingContext {
+    private int varCounter;
+    private HashMap<Integer, VarIdentifier> oldVarIdToNewVarId = new HashMap<Integer, VarIdentifier>();
+
+    public AqlRewritingContext(int varCounter) {
+        this.varCounter = varCounter;
+    }
+
+    public int getVarCounter() {
+        return varCounter;
+    }
+
+    public VarIdentifier mapOldId(Integer oldId, String varValue) {
+        int n = newId();
+        VarIdentifier newVar = new VarIdentifier(varValue);
+        newVar.setId(n);
+        oldVarIdToNewVarId.put(oldId, newVar);
+        return newVar;
+    }
+
+    public VarIdentifier mapOldVarIdentifier(VarIdentifier vi) {
+        return mapOldId(vi.getId(), vi.getValue());
+    }
+
+    public VarIdentifier getRewrittenVar(Integer oldId) {
+        return oldVarIdToNewVarId.get(oldId);
+    }
+
+    public VarIdentifier newVariable() {
+        int id = newId();
+        return new VarIdentifier("@@" + id, id);
+    }
+
+    private int newId() {
+        varCounter++;
+        return varCounter;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/CloneAndSubstituteVariablesVisitor.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/CloneAndSubstituteVariablesVisitor.java
new file mode 100644
index 0000000..1db36a0
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/CloneAndSubstituteVariablesVisitor.java
@@ -0,0 +1,596 @@
+package edu.uci.ics.asterix.aql.rewrites;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import edu.uci.ics.asterix.aql.base.Clause;
+import edu.uci.ics.asterix.aql.base.Expression;
+import edu.uci.ics.asterix.aql.base.IAqlExpression;
+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.CreateDataverseStatement;
+import edu.uci.ics.asterix.aql.expression.CreateFunctionStatement;
+import edu.uci.ics.asterix.aql.expression.CreateIndexStatement;
+import edu.uci.ics.asterix.aql.expression.DatasetDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDropStatement;
+import edu.uci.ics.asterix.aql.expression.DeleteStatement;
+import edu.uci.ics.asterix.aql.expression.DieClause;
+import edu.uci.ics.asterix.aql.expression.DistinctClause;
+import edu.uci.ics.asterix.aql.expression.DropStatement;
+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.FunctionDecl;
+import edu.uci.ics.asterix.aql.expression.FunctionDropStatement;
+import edu.uci.ics.asterix.aql.expression.GbyVariableExpressionPair;
+import edu.uci.ics.asterix.aql.expression.GroupbyClause;
+import edu.uci.ics.asterix.aql.expression.IfExpr;
+import edu.uci.ics.asterix.aql.expression.IndexAccessor;
+import edu.uci.ics.asterix.aql.expression.IndexDropStatement;
+import edu.uci.ics.asterix.aql.expression.InsertStatement;
+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.LiteralExpr;
+import edu.uci.ics.asterix.aql.expression.LoadFromFileStatement;
+import edu.uci.ics.asterix.aql.expression.NodeGroupDropStatement;
+import edu.uci.ics.asterix.aql.expression.NodegroupDecl;
+import edu.uci.ics.asterix.aql.expression.OperatorExpr;
+import edu.uci.ics.asterix.aql.expression.OrderbyClause;
+import edu.uci.ics.asterix.aql.expression.OrderedListTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.QuantifiedExpression;
+import edu.uci.ics.asterix.aql.expression.QuantifiedPair;
+import edu.uci.ics.asterix.aql.expression.Query;
+import edu.uci.ics.asterix.aql.expression.RecordConstructor;
+import edu.uci.ics.asterix.aql.expression.RecordTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.SetStatement;
+import edu.uci.ics.asterix.aql.expression.TypeDecl;
+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.UnionExpr;
+import edu.uci.ics.asterix.aql.expression.UnorderedListTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.UpdateClause;
+import edu.uci.ics.asterix.aql.expression.UpdateStatement;
+import edu.uci.ics.asterix.aql.expression.VarIdentifier;
+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.WriteStatement;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.hyracks.algebricks.core.utils.Pair;
+
+public class CloneAndSubstituteVariablesVisitor implements
+        IAqlExpressionVisitor<Pair<IAqlExpression, List<VariableSubstitution>>, List<VariableSubstitution>> {
+
+    private AqlRewritingContext context;
+
+    public CloneAndSubstituteVariablesVisitor(AqlRewritingContext context) {
+        this.context = context;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitFieldAccessor(FieldAccessor fa,
+            List<VariableSubstitution> arg) throws AsterixException {
+        Pair<IAqlExpression, List<VariableSubstitution>> p = fa.getExpr().accept(this, arg);
+        FieldAccessor newF = new FieldAccessor((Expression) p.first, fa.getIdent());
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(newF, p.second);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitFlworExpression(FLWOGRExpression flwor,
+            List<VariableSubstitution> arg) throws AsterixException {
+        List<Clause> newClauses = new ArrayList<Clause>(flwor.getClauseList().size());
+        List<VariableSubstitution> ongoing = arg;
+        for (Clause c : flwor.getClauseList()) {
+            Pair<IAqlExpression, List<VariableSubstitution>> p1 = c.accept(this, ongoing);
+            ongoing = p1.second;
+            newClauses.add((Clause) p1.first);
+        }
+        Pair<IAqlExpression, List<VariableSubstitution>> p2 = flwor.getReturnExpr().accept(this, ongoing);
+        Expression newReturnExpr = (Expression) p2.first;
+        FLWOGRExpression newFlwor = new FLWOGRExpression(newClauses, newReturnExpr);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(newFlwor, p2.second);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitForClause(ForClause fc, List<VariableSubstitution> arg)
+            throws AsterixException {
+        Pair<IAqlExpression, List<VariableSubstitution>> p1 = fc.getInExpr().accept(this, arg);
+        VarIdentifier vi = fc.getVarExpr().getVar();
+        // we need new variables
+        VarIdentifier newVar = context.mapOldId(vi.getId(), vi.getValue());
+
+        VariableSubstitution vs = findVarSubst(arg, vi);
+        List<VariableSubstitution> newSubs;
+        if (vs == null) {
+            newSubs = arg;
+        } else {
+            // This for clause is overriding a binding, so we don't subst. that
+            // one anymore.
+            newSubs = eliminateSubstFromList(vi, arg);
+        }
+
+        VariableExpr newVe = new VariableExpr(newVar);
+        ForClause newFor = new ForClause(newVe, (Expression) p1.first);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(newFor, newSubs);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitLetClause(LetClause lc, List<VariableSubstitution> arg)
+            throws AsterixException {
+        Pair<IAqlExpression, List<VariableSubstitution>> p1 = lc.getBindingExpr().accept(this, arg);
+        VarIdentifier vi = lc.getVarExpr().getVar();
+        VarIdentifier newVar = context.mapOldId(vi.getId(), vi.getValue());
+
+        VariableSubstitution vs = findVarSubst(arg, vi);
+        List<VariableSubstitution> newSubs;
+        if (vs == null) {
+            newSubs = arg;
+        } else {
+            newSubs = eliminateSubstFromList(vi, arg);
+        }
+
+        VariableExpr newVe = new VariableExpr(newVar);
+        LetClause newLet = new LetClause(newVe, (Expression) p1.first);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(newLet, newSubs);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitGroupbyClause(GroupbyClause gc,
+            List<VariableSubstitution> arg) throws AsterixException {
+        List<VariableSubstitution> newSubs = arg;
+        List<GbyVariableExpressionPair> newGbyList = substInVarExprPair(gc.getGbyPairList(), arg, newSubs);
+        List<GbyVariableExpressionPair> newDecorList = substInVarExprPair(gc.getDecorPairList(), arg, newSubs);
+        List<VariableExpr> wList = new LinkedList<VariableExpr>();
+        for (VariableExpr w : gc.getWithVarList()) {
+            VarIdentifier newVar = context.getRewrittenVar(w.getVar().getId());
+            wList.add(new VariableExpr(newVar));
+        }
+        GroupbyClause newGroup = new GroupbyClause(newGbyList, newDecorList, wList, gc.hasHashGroupByHint());
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(newGroup, newSubs);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitQuantifiedExpression(QuantifiedExpression qe,
+            List<VariableSubstitution> arg) throws AsterixException {
+        List<QuantifiedPair> oldPairs = qe.getQuantifiedList();
+        List<QuantifiedPair> newPairs = new ArrayList<QuantifiedPair>(oldPairs.size());
+        List<VarIdentifier> newVis = new LinkedList<VarIdentifier>();
+        List<VariableSubstitution> newSubs = arg;
+        for (QuantifiedPair t : oldPairs) {
+            VarIdentifier newVar = context.mapOldVarIdentifier(t.getVarExpr().getVar());
+            newVis.add(newVar);
+            newSubs = eliminateSubstFromList(newVar, newSubs);
+            Pair<IAqlExpression, List<VariableSubstitution>> p1 = t.getExpr().accept(this, newSubs);
+            QuantifiedPair t2 = new QuantifiedPair(new VariableExpr(newVar), (Expression) p1.first);
+            newPairs.add(t2);
+        }
+        Pair<IAqlExpression, List<VariableSubstitution>> p2 = qe.getSatisfiesExpr().accept(this, newSubs);
+        QuantifiedExpression qe2 = new QuantifiedExpression(qe.getQuantifier(), newPairs, (Expression) p2.first);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(qe2, newSubs);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitVariableExpr(VariableExpr v,
+            List<VariableSubstitution> arg) throws AsterixException {
+        VariableSubstitution vs = findVarSubst(arg, v.getVar());
+        VarIdentifier var;
+        if (vs != null) {
+            // it is a variable subst from the list
+            var = vs.getNewVar();
+        } else {
+            // it is a var. from the context
+            var = context.getRewrittenVar(v.getVar().getId());
+            if(var == null){
+                var = v.getVar();
+            }
+        }
+        VariableExpr ve = new VariableExpr(var);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(ve, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitWhereClause(WhereClause wc,
+            List<VariableSubstitution> arg) throws AsterixException {
+        Pair<IAqlExpression, List<VariableSubstitution>> p1 = wc.getWhereExpr().accept(this, arg);
+        WhereClause newW = new WhereClause((Expression) p1.first);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(newW, p1.second);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitCallExpr(CallExpr pf, List<VariableSubstitution> arg)
+            throws AsterixException {
+        List<Expression> exprList = visitAndCloneExprList(pf.getExprList(), arg);
+        CallExpr f = new CallExpr(pf.getIdent(), exprList);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(f, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitFunctionDecl(FunctionDecl fd,
+            List<VariableSubstitution> arg) throws AsterixException {
+        List<VarIdentifier> newList = new ArrayList<VarIdentifier>(fd.getParamList().size());
+        for (VarIdentifier vi : fd.getParamList()) {
+            VariableSubstitution vs = findVarSubst(arg, vi);
+            if (vs == null) {
+                throw new AsterixException("Parameter " + vi + " does not appear in the substitution list.");
+            }
+            newList.add(vs.getNewVar());
+        }
+
+        Pair<IAqlExpression, List<VariableSubstitution>> p1 = fd.getFuncBody().accept(this, arg);
+        FunctionDecl newF = new FunctionDecl(fd.getIdent(), newList, (Expression) p1.first);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(newF, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitIfExpr(IfExpr ifexpr, List<VariableSubstitution> arg)
+            throws AsterixException {
+        Pair<IAqlExpression, List<VariableSubstitution>> p1 = ifexpr.getCondExpr().accept(this, arg);
+        Pair<IAqlExpression, List<VariableSubstitution>> p2 = ifexpr.getThenExpr().accept(this, arg);
+        Pair<IAqlExpression, List<VariableSubstitution>> p3 = ifexpr.getElseExpr().accept(this, arg);
+        IfExpr i = new IfExpr((Expression) p1.first, (Expression) p2.first, (Expression) p3.first);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(i, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitIndexAccessor(IndexAccessor ia,
+            List<VariableSubstitution> arg) throws AsterixException {
+        Pair<IAqlExpression, List<VariableSubstitution>> p1 = ia.getExpr().accept(this, arg);
+        IndexAccessor i = new IndexAccessor((Expression) p1.first, ia.getIndex());
+        i.setAny(ia.isAny());
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(i, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitLimitClause(LimitClause lc,
+            List<VariableSubstitution> arg) throws AsterixException {
+        Pair<IAqlExpression, List<VariableSubstitution>> p1 = lc.getLimitExpr().accept(this, arg);
+        Pair<IAqlExpression, List<VariableSubstitution>> p2 = lc.getOffset().accept(this, arg);
+        LimitClause c = new LimitClause((Expression) p1.first, (Expression) p2.first);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(c, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitDieClause(DieClause lc, List<VariableSubstitution> arg)
+            throws AsterixException {
+        Pair<IAqlExpression, List<VariableSubstitution>> p1 = lc.getDieExpr().accept(this, arg);
+        DieClause c = new DieClause((Expression) p1.first);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(c, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitListConstructor(ListConstructor lc,
+            List<VariableSubstitution> arg) throws AsterixException {
+        List<Expression> oldExprList = lc.getExprList();
+        List<Expression> exprs = visitAndCloneExprList(oldExprList, arg);
+        ListConstructor c = new ListConstructor(lc.getType(), exprs);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(c, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitLiteralExpr(LiteralExpr l,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // LiteralExpr e = new LiteralExpr(l.getValue());
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(l, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitOperatorExpr(OperatorExpr op,
+            List<VariableSubstitution> arg) throws AsterixException {
+        ArrayList<Expression> oldExprList = op.getExprList();
+        ArrayList<Expression> exprs = new ArrayList<Expression>(oldExprList.size());
+        for (Expression e : oldExprList) {
+            Pair<IAqlExpression, List<VariableSubstitution>> p1 = e.accept(this, arg);
+            exprs.add((Expression) p1.first);
+        }
+        OperatorExpr oe = new OperatorExpr(exprs, op.getExprBroadcastIdx(), op.getOpList());
+        oe.setCurrentop(op.isCurrentop());
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(oe, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitOrderbyClause(OrderbyClause oc,
+            List<VariableSubstitution> arg) throws AsterixException {
+        List<Expression> exprList = visitAndCloneExprList(oc.getOrderbyList(), arg);
+        OrderbyClause oc2 = new OrderbyClause(exprList, oc.getModifierList());
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(oc2, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitQuery(Query q, List<VariableSubstitution> arg)
+            throws AsterixException {
+        Query newQ = new Query();
+        Pair<IAqlExpression, List<VariableSubstitution>> p1 = q.getBody().accept(this, arg);
+        newQ.setBody((Expression) p1.first);
+        newQ.setPrologDeclList(q.getPrologDeclList());
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(newQ, p1.second);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitRecordConstructor(RecordConstructor rc,
+            List<VariableSubstitution> arg) throws AsterixException {
+        List<FieldBinding> oldFbs = rc.getFbList();
+        ArrayList<FieldBinding> newFbs = new ArrayList<FieldBinding>(oldFbs.size());
+        for (FieldBinding fb : oldFbs) {
+            Pair<IAqlExpression, List<VariableSubstitution>> p1 = fb.getLeftExpr().accept(this, arg);
+            Pair<IAqlExpression, List<VariableSubstitution>> p2 = fb.getRightExpr().accept(this, arg);
+            FieldBinding fb2 = new FieldBinding((Expression) p1.first, (Expression) p2.first);
+            newFbs.add(fb2);
+        }
+        RecordConstructor newRc = new RecordConstructor(newFbs);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(newRc, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitUnaryExpr(UnaryExpr u, List<VariableSubstitution> arg)
+            throws AsterixException {
+        Pair<IAqlExpression, List<VariableSubstitution>> p1 = u.getExpr().accept(this, arg);
+        UnaryExpr newU = new UnaryExpr(u.getSign(), (Expression) p1.first);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(newU, arg);
+    }
+
+    private List<Expression> visitAndCloneExprList(List<Expression> oldExprList, List<VariableSubstitution> arg)
+            throws AsterixException {
+        List<Expression> exprs = new ArrayList<Expression>(oldExprList.size());
+        for (Expression e : oldExprList) {
+            Pair<IAqlExpression, List<VariableSubstitution>> p1 = e.accept(this, arg);
+            exprs.add((Expression) p1.first);
+        }
+        return exprs;
+    }
+
+    private static VariableSubstitution findVarSubst(List<VariableSubstitution> varSubstList, VarIdentifier v) {
+        VariableSubstitution res = null;
+        for (VariableSubstitution s : varSubstList) {
+            if (s.getOldVar().getValue().equals(v.getValue())) {
+                res = s;
+                break;
+            }
+        }
+        return res;
+    }
+
+    private static List<VariableSubstitution> eliminateSubstFromList(VarIdentifier vi, List<VariableSubstitution> arg) {
+        List<VariableSubstitution> newArg = new LinkedList<VariableSubstitution>();
+        for (VariableSubstitution vs1 : arg) {
+            if (!vs1.getOldVar().getValue().equals(vi.getValue())) {
+                newArg.add(vs1);
+            }
+        }
+        return newArg;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitTypeDecl(TypeDecl td, List<VariableSubstitution> arg)
+            throws AsterixException {
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitRecordTypeDefiniton(RecordTypeDefinition tre,
+            List<VariableSubstitution> arg) throws AsterixException {
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitTypeReferenceExpression(TypeReferenceExpression tre,
+            List<VariableSubstitution> arg) throws AsterixException {
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitNodegroupDecl(NodegroupDecl ngd,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitLoadFromFileStatement(LoadFromFileStatement stmtLoad,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitDropStatement(DropStatement del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitControlFeedStatement(ControlFeedStatement del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    private List<GbyVariableExpressionPair> substInVarExprPair(List<GbyVariableExpressionPair> gbyVeList,
+            List<VariableSubstitution> arg, List<VariableSubstitution> newSubs) throws AsterixException {
+        List<GbyVariableExpressionPair> veList = new LinkedList<GbyVariableExpressionPair>();
+        for (GbyVariableExpressionPair vep : gbyVeList) {
+            VariableExpr oldGbyVar = vep.getVar();
+            VariableExpr newGbyVar = null;
+            if (oldGbyVar != null) {
+                VarIdentifier newVar = context.mapOldVarIdentifier(oldGbyVar.getVar());
+                newSubs = eliminateSubstFromList(newVar, newSubs);
+                newGbyVar = new VariableExpr(newVar);
+            }
+            Pair<IAqlExpression, List<VariableSubstitution>> p1 = vep.getExpr().accept(this, newSubs);
+            GbyVariableExpressionPair ve2 = new GbyVariableExpressionPair(newGbyVar, (Expression) p1.first);
+            veList.add(ve2);
+        }
+        return veList;
+
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitWriteFromQueryResultStatement(
+            WriteFromQueryResultStatement stmtLoad, List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitCreateIndexStatement(CreateIndexStatement cis,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitUnionExpr(UnionExpr u, List<VariableSubstitution> arg)
+            throws AsterixException {
+        List<Expression> exprList = visitAndCloneExprList(u.getExprs(), arg);
+        UnionExpr newU = new UnionExpr(exprList);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(newU, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitDistinctClause(DistinctClause dc,
+            List<VariableSubstitution> arg) throws AsterixException {
+        List<Expression> exprList = visitAndCloneExprList(dc.getDistinctByExpr(), arg);
+        DistinctClause dc2 = new DistinctClause(exprList);
+        return new Pair<IAqlExpression, List<VariableSubstitution>>(dc2, arg);
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitOrderedListTypeDefiniton(
+            OrderedListTypeDefinition olte, List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitUnorderedListTypeDefiniton(
+            UnorderedListTypeDefinition ulte, List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitInsertStatement(InsertStatement del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitDeleteStatement(DeleteStatement del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitUpdateStatement(UpdateStatement del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitUpdateClause(UpdateClause del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitDataverseDecl(DataverseDecl dv,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitSetStatement(SetStatement ss,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitWriteStatement(WriteStatement ws,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitDatasetDecl(DatasetDecl dd,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitLoadFromQueryResultStatement(
+            WriteFromQueryResultStatement stmtLoad, List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitCreateDataverseStatement(CreateDataverseStatement del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitIndexDropStatement(IndexDropStatement del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitNodeGroupDropStatement(NodeGroupDropStatement del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitDataverseDropStatement(DataverseDropStatement del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitTypeDropStatement(TypeDropStatement del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visit(CreateFunctionStatement cfs,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitFunctionDropStatement(FunctionDropStatement del,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<IAqlExpression, List<VariableSubstitution>> visitBeginFeedStatement(BeginFeedStatement bf,
+            List<VariableSubstitution> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
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
new file mode 100644
index 0000000..5c59c7c
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/InlineUdfsVisitor.java
@@ -0,0 +1,526 @@
+package edu.uci.ics.asterix.aql.rewrites;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+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.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.CreateDataverseStatement;
+import edu.uci.ics.asterix.aql.expression.CreateFunctionStatement;
+import edu.uci.ics.asterix.aql.expression.CreateIndexStatement;
+import edu.uci.ics.asterix.aql.expression.DatasetDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDecl;
+import edu.uci.ics.asterix.aql.expression.DataverseDropStatement;
+import edu.uci.ics.asterix.aql.expression.DeleteStatement;
+import edu.uci.ics.asterix.aql.expression.DieClause;
+import edu.uci.ics.asterix.aql.expression.DistinctClause;
+import edu.uci.ics.asterix.aql.expression.DropStatement;
+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.FunctionDecl;
+import edu.uci.ics.asterix.aql.expression.FunctionDropStatement;
+import edu.uci.ics.asterix.aql.expression.GbyVariableExpressionPair;
+import edu.uci.ics.asterix.aql.expression.GroupbyClause;
+import edu.uci.ics.asterix.aql.expression.IfExpr;
+import edu.uci.ics.asterix.aql.expression.IndexAccessor;
+import edu.uci.ics.asterix.aql.expression.IndexDropStatement;
+import edu.uci.ics.asterix.aql.expression.InsertStatement;
+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.LiteralExpr;
+import edu.uci.ics.asterix.aql.expression.LoadFromFileStatement;
+import edu.uci.ics.asterix.aql.expression.NodeGroupDropStatement;
+import edu.uci.ics.asterix.aql.expression.NodegroupDecl;
+import edu.uci.ics.asterix.aql.expression.OperatorExpr;
+import edu.uci.ics.asterix.aql.expression.OrderbyClause;
+import edu.uci.ics.asterix.aql.expression.OrderedListTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.QuantifiedExpression;
+import edu.uci.ics.asterix.aql.expression.QuantifiedPair;
+import edu.uci.ics.asterix.aql.expression.Query;
+import edu.uci.ics.asterix.aql.expression.RecordConstructor;
+import edu.uci.ics.asterix.aql.expression.RecordTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.SetStatement;
+import edu.uci.ics.asterix.aql.expression.TypeDecl;
+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.UnionExpr;
+import edu.uci.ics.asterix.aql.expression.UnorderedListTypeDefinition;
+import edu.uci.ics.asterix.aql.expression.UpdateClause;
+import edu.uci.ics.asterix.aql.expression.UpdateStatement;
+import edu.uci.ics.asterix.aql.expression.VarIdentifier;
+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.WriteStatement;
+import edu.uci.ics.asterix.aql.expression.visitor.IAqlExpressionVisitor;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.hyracks.algebricks.core.utils.Pair;
+
+public class InlineUdfsVisitor implements IAqlExpressionVisitor<Boolean, List<FunctionDecl>> {
+
+    private final AqlRewritingContext context;
+    private final CloneAndSubstituteVariablesVisitor cloneVisitor;
+
+    public InlineUdfsVisitor(AqlRewritingContext context) {
+        this.context = context;
+        this.cloneVisitor = new CloneAndSubstituteVariablesVisitor(context);
+    }
+
+    @Override
+    public Boolean visitQuery(Query q, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, Expression> p = inlineUdfsInExpr(q.getBody(), arg);
+        q.setBody(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitFunctionDecl(FunctionDecl fd, List<FunctionDecl> arg) throws AsterixException {
+        // Careful, we should only do this after analyzing the graph of function
+        // calls.
+        Pair<Boolean, Expression> p = inlineUdfsInExpr(fd.getFuncBody(), arg);
+        fd.setFuncBody(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitListConstructor(ListConstructor lc, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, ArrayList<Expression>> p = newExprList(lc.getExprList(), arg);
+        lc.setExprList(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitRecordConstructor(RecordConstructor rc, List<FunctionDecl> arg) throws AsterixException {
+        boolean changed = false;
+        for (FieldBinding b : rc.getFbList()) {
+            if (b.getLeftExpr().accept(this, arg)) {
+                changed = true;
+            }
+            if (b.getRightExpr().accept(this, arg)) {
+                changed = true;
+            }
+        }
+        return changed;
+    }
+
+    @Override
+    public Boolean visitCallExpr(CallExpr pf, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, ArrayList<Expression>> p = newExprList(pf.getExprList(), arg);
+        pf.setExprList(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitOperatorExpr(OperatorExpr ifbo, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, ArrayList<Expression>> p = newExprList(ifbo.getExprList(), arg);
+        ifbo.setExprList(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitFieldAccessor(FieldAccessor fa, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, Expression> p = inlineUdfsInExpr(fa.getExpr(), arg);
+        fa.setExpr(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitIndexAccessor(IndexAccessor fa, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, Expression> p = inlineUdfsInExpr(fa.getExpr(), arg);
+        fa.setExpr(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitIfExpr(IfExpr ifexpr, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, Expression> p1 = inlineUdfsInExpr(ifexpr.getCondExpr(), arg);
+        ifexpr.setCondExpr(p1.second);
+        Pair<Boolean, Expression> p2 = inlineUdfsInExpr(ifexpr.getThenExpr(), arg);
+        ifexpr.setThenExpr(p2.second);
+        Pair<Boolean, Expression> p3 = inlineUdfsInExpr(ifexpr.getElseExpr(), arg);
+        ifexpr.setElseExpr(p3.second);
+        return p1.first || p2.first || p3.first;
+    }
+
+    @Override
+    public Boolean visitFlworExpression(FLWOGRExpression flwor, List<FunctionDecl> arg) throws AsterixException {
+        boolean changed = false;
+        for (Clause c : flwor.getClauseList()) {
+            if (c.accept(this, arg)) {
+                changed = true;
+            }
+        }
+        Pair<Boolean, Expression> p = inlineUdfsInExpr(flwor.getReturnExpr(), arg);
+        flwor.setReturnExpr(p.second);
+        return changed || p.first;
+    }
+
+    @Override
+    public Boolean visitQuantifiedExpression(QuantifiedExpression qe, List<FunctionDecl> arg) throws AsterixException {
+        boolean changed = false;
+        for (QuantifiedPair t : qe.getQuantifiedList()) {
+            Pair<Boolean, Expression> p = inlineUdfsInExpr(t.getExpr(), arg);
+            t.setExpr(p.second);
+            if (p.first) {
+                changed = true;
+            }
+        }
+        Pair<Boolean, Expression> p2 = inlineUdfsInExpr(qe.getSatisfiesExpr(), arg);
+        qe.setSatisfiesExpr(p2.second);
+        return changed || p2.first;
+    }
+
+    @Override
+    public Boolean visitForClause(ForClause fc, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, Expression> p = inlineUdfsInExpr(fc.getInExpr(), arg);
+        fc.setInExpr(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitLetClause(LetClause lc, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, Expression> p = inlineUdfsInExpr(lc.getBindingExpr(), arg);
+        lc.setBindingExpr(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitWhereClause(WhereClause wc, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, Expression> p = inlineUdfsInExpr(wc.getWhereExpr(), arg);
+        wc.setWhereExpr(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitOrderbyClause(OrderbyClause oc, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, ArrayList<Expression>> p = newExprList(oc.getOrderbyList(), arg);
+        oc.setOrderbyList(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitGroupbyClause(GroupbyClause gc, List<FunctionDecl> arg) throws AsterixException {
+        boolean changed = false;
+        for (GbyVariableExpressionPair p : gc.getGbyPairList()) {
+            Pair<Boolean, Expression> be = inlineUdfsInExpr(p.getExpr(), arg);
+            p.setExpr(be.second);
+            if (be.first) {
+                changed = true;
+            }
+        }
+        for (GbyVariableExpressionPair p : gc.getDecorPairList()) {
+            Pair<Boolean, Expression> be = inlineUdfsInExpr(p.getExpr(), arg);
+            p.setExpr(be.second);
+            if (be.first) {
+                changed = true;
+            }
+        }
+        return changed;
+    }
+
+    @Override
+    public Boolean visitLimitClause(LimitClause lc, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, Expression> p1 = inlineUdfsInExpr(lc.getLimitExpr(), arg);
+        lc.setLimitExpr(p1.second);
+        boolean changed = p1.first;
+        if (lc.getOffset() != null) {
+            Pair<Boolean, Expression> p2 = inlineUdfsInExpr(lc.getOffset(), arg);
+            lc.setOffset(p2.second);
+            changed = changed || p2.first;
+        }
+        return changed;
+    }
+
+    @Override
+    public Boolean visitDieClause(DieClause lc, List<FunctionDecl> arg) throws AsterixException {
+        Pair<Boolean, Expression> p1 = inlineUdfsInExpr(lc.getDieExpr(), arg);
+        lc.setDieExpr(p1.second);
+        return p1.first;
+    }
+
+    @Override
+    public Boolean visitUnaryExpr(UnaryExpr u, List<FunctionDecl> arg) throws AsterixException {
+        return u.getExpr().accept(this, arg);
+    }
+
+    @Override
+    public Boolean visitUnionExpr(UnionExpr u, List<FunctionDecl> fds) throws AsterixException {
+        Pair<Boolean, ArrayList<Expression>> p = newExprList(u.getExprs(), fds);
+        u.setExprs(p.second);
+        return p.first;
+    }
+
+    @Override
+    public Boolean visitDistinctClause(DistinctClause dc, List<FunctionDecl> arg) throws AsterixException {
+        boolean changed = false;
+        for (Expression expr : dc.getDistinctByExpr()) {
+            changed = expr.accept(this, arg);
+        }
+        return changed;
+    }
+
+    @Override
+    public Boolean visitVariableExpr(VariableExpr v, List<FunctionDecl> arg) throws AsterixException {
+        return false;
+    }
+
+    @Override
+    public Boolean visitLiteralExpr(LiteralExpr l, List<FunctionDecl> arg) throws AsterixException {
+        return false;
+    }
+
+    private Pair<Boolean, Expression> inlineUdfsInExpr(Expression expr, List<FunctionDecl> arg) throws AsterixException {
+        if (expr.getKind() != Kind.CALL_EXPRESSION) {
+            boolean r = expr.accept(this, arg);
+            return new Pair<Boolean, Expression>(r, expr);
+        } else {
+            CallExpr f = (CallExpr) expr;
+            FunctionDecl implem = findFuncDeclaration(f.getIdent(), arg);
+            if (implem == null) {
+                boolean r = expr.accept(this, arg);
+                return new Pair<Boolean, Expression>(r, expr);
+            } else { // it's one of the functions we want to inline
+                List<Clause> clauses = new ArrayList<Clause>();
+                Iterator<VarIdentifier> paramIter = implem.getParamList().iterator();
+                // List<VariableExpr> effectiveArgs = new
+                // ArrayList<VariableExpr>(f.getExprList().size());
+                List<VariableSubstitution> subts = new ArrayList<VariableSubstitution>(f.getExprList().size());
+                for (Expression e : f.getExprList()) {
+                    VarIdentifier param = paramIter.next();
+                    // Obs: we could do smth about passing also literals, or let
+                    // variable inlining to take care of this.
+                    if (e.getKind() == Kind.VARIABLE_EXPRESSION) {
+                        subts.add(new VariableSubstitution(param, ((VariableExpr) e).getVar()));
+                    } else {
+                        VarIdentifier newV = context.newVariable();
+                        Pair<IAqlExpression, List<VariableSubstitution>> p1 = e.accept(cloneVisitor,
+                                new ArrayList<VariableSubstitution>());
+                        LetClause c = new LetClause(new VariableExpr(newV), (Expression) p1.first);
+                        clauses.add(c);
+                        subts.add(new VariableSubstitution(param, newV));
+                    }
+                }
+                Pair<IAqlExpression, List<VariableSubstitution>> p2 = implem.getFuncBody().accept(cloneVisitor, subts);
+                Expression resExpr;
+                if (clauses.isEmpty()) {
+                    resExpr = (Expression) p2.first;
+                } else {
+                    resExpr = new FLWOGRExpression(clauses, (Expression) p2.first);
+                }
+                return new Pair<Boolean, Expression>(true, resExpr);
+            }
+        }
+    }
+
+    private Pair<Boolean, ArrayList<Expression>> newExprList(List<Expression> exprList, List<FunctionDecl> fds)
+            throws AsterixException {
+        ArrayList<Expression> newList = new ArrayList<Expression>();
+        boolean changed = false;
+        for (Expression e : exprList) {
+            Pair<Boolean, Expression> p = inlineUdfsInExpr(e, fds);
+            newList.add(p.second);
+            if (p.first) {
+                changed = true;
+            }
+        }
+        return new Pair<Boolean, ArrayList<Expression>>(changed, newList);
+    }
+
+    private static FunctionDecl findFuncDeclaration(FunIdentifier fid, List<FunctionDecl> sequence) {
+        for (FunctionDecl f : sequence) {
+            if (f.getIdent().equals(fid)) {
+                return f;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Boolean visitCreateIndexStatement(CreateIndexStatement cis, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitDataverseDecl(DataverseDecl dv, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitDeleteStatement(DeleteStatement del, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitDropStatement(DropStatement del, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitDatasetDecl(DatasetDecl dd, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitInsertStatement(InsertStatement insert, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitLoadFromFileStatement(LoadFromFileStatement stmtLoad, List<FunctionDecl> arg)
+            throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitNodegroupDecl(NodegroupDecl ngd, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitOrderedListTypeDefiniton(OrderedListTypeDefinition olte, List<FunctionDecl> arg)
+            throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitRecordTypeDefiniton(RecordTypeDefinition tre, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitSetStatement(SetStatement ss, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitTypeDecl(TypeDecl td, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitTypeReferenceExpression(TypeReferenceExpression tre, List<FunctionDecl> arg)
+            throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitUnorderedListTypeDefiniton(UnorderedListTypeDefinition ulte, List<FunctionDecl> arg)
+            throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitUpdateClause(UpdateClause del, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitUpdateStatement(UpdateStatement update, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitWriteFromQueryResultStatement(WriteFromQueryResultStatement stmtLoad, List<FunctionDecl> arg)
+            throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitWriteStatement(WriteStatement ws, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitLoadFromQueryResultStatement(WriteFromQueryResultStatement stmtLoad, List<FunctionDecl> arg)
+            throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitCreateDataverseStatement(CreateDataverseStatement del, List<FunctionDecl> arg)
+            throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitIndexDropStatement(IndexDropStatement del, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitNodeGroupDropStatement(NodeGroupDropStatement del, List<FunctionDecl> arg)
+            throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitDataverseDropStatement(DataverseDropStatement del, List<FunctionDecl> arg)
+            throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitTypeDropStatement(TypeDropStatement del, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitControlFeedStatement(ControlFeedStatement del, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visit(CreateFunctionStatement cfs, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitFunctionDropStatement(FunctionDropStatement del, List<FunctionDecl> arg)
+            throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Boolean visitBeginFeedStatement(BeginFeedStatement bf, List<FunctionDecl> arg) throws AsterixException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
diff --git a/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/VariableSubstitution.java b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/VariableSubstitution.java
new file mode 100644
index 0000000..e787ac0
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/rewrites/VariableSubstitution.java
@@ -0,0 +1,25 @@
+package edu.uci.ics.asterix.aql.rewrites;
+
+import edu.uci.ics.asterix.aql.expression.VarIdentifier;
+
+public final class VariableSubstitution {
+    private final VarIdentifier oldVar;
+    private final VarIdentifier newVar;
+
+    // private final int newVarId;
+
+    public VariableSubstitution(VarIdentifier oldVar, VarIdentifier newVar) {
+        this.oldVar = oldVar;
+        this.newVar = newVar;
+        // this.newVarId = newVarId;
+    }
+
+    public VarIdentifier getOldVar() {
+        return oldVar;
+    }
+
+    public VarIdentifier getNewVar() {
+        return newVar;
+    }
+
+}
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
new file mode 100644
index 0000000..0214ada
--- /dev/null
+++ b/asterix-aql/src/main/java/edu/uci/ics/asterix/aql/util/FunctionUtil.java
@@ -0,0 +1,49 @@
+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/javacc/AQL.html b/asterix-aql/src/main/javacc/AQL.html
new file mode 100644
index 0000000..1674cb5
--- /dev/null
+++ b/asterix-aql/src/main/javacc/AQL.html
@@ -0,0 +1,605 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+<HEAD>
+<TITLE>BNF for AQL.jj</TITLE>
+</HEAD>
+<BODY>
+<H1 ALIGN=CENTER>BNF for AQL.jj</H1>
+<H2 ALIGN=CENTER>TOKENS</H2>
+<TABLE>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;CARET: "^"&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;DATASET: "dataset"&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;LEFTPAREN: "("&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;RIGHTPAREN: ")"&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;INTEGER_LITERAL: (&lt;DIGIT&gt;)+&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;NULL: "null"&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;TRUE: "true"&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;FALSE: "false"&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;#DIGIT: ["0"-"9"]&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;DOUBLE_LITERAL: &lt;INTEGER&gt; | &lt;INTEGER&gt; ("." &lt;INTEGER&gt;)? | "." &lt;INTEGER&gt;&gt;
+| &lt;FLOAT_LITERAL: &lt;INTEGER&gt; ("f" | "F") | &lt;INTEGER&gt; ("." &lt;INTEGER&gt; ("f" | "F"))? | "." &lt;INTEGER&gt; ("f" | "F")&gt;
+| &lt;INTEGER: (&lt;DIGIT&gt;)+&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;#LETTER: ["A"-"Z","a"-"z"]&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;SPECIALCHARS: ["$","_","-"]&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;STRING_LITERAL: "\"" (&lt;EscapeQuot&gt; | ~["\""])* "\"" | "\'" (&lt;EscapeApos&gt; | ~["\'"])* "\'"&gt;
+| &lt;#EscapeQuot: "\\\""&gt;
+| &lt;#EscapeApos: "\\\'"&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;IDENTIFIER: (&lt;LETTER&gt;)+ (&lt;LETTER&gt; | &lt;DIGIT&gt; | &lt;SPECIALCHARS&gt;)*&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; TOKEN : {
+&lt;VARIABLE: "$" &lt;IDENTIFIER&gt;&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; SKIP : {
+" "
+| "\t"
+| "\r"
+| "\n"
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; SKIP : {
+&lt;"//" (~["\n"])* "\n"&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; SKIP : {
+&lt;"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")?&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;DEFAULT&gt; SKIP : {
+"/*" : INSIDE_COMMENT
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;INSIDE_COMMENT&gt; SPECIAL : {
+&lt;"+" (" ")* (~["*"])*&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;INSIDE_COMMENT&gt; SKIP : {
+"/*" : {
+}
+
+   </PRE>
+  </TD>
+ </TR>
+ <!-- Token -->
+ <TR>
+  <TD>
+   <PRE>
+&lt;INSIDE_COMMENT&gt; SKIP : {
+"*/" : {
+| &lt;~[]&gt;
+}
+
+   </PRE>
+  </TD>
+ </TR>
+</TABLE>
+<H2 ALIGN=CENTER>NON-TERMINALS</H2>
+<TABLE>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod1">Statement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( ( ( "use" | "declare" "function" | "create" ( "type" | "nodegroup" | "external" &lt;DATASET&gt; | &lt;DATASET&gt; | "index" | "dataverse" ) | "load" | "enlist" | "drop" ( &lt;DATASET&gt; | "index" | "nodegroup" | "type" | "dataverse" ) | "write" | "set" | "insert" | "delete" | "update" )* ( <A HREF="#prod2">Query</A> )? ) &lt;EOF&gt; )</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod3">InsertStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"into" &lt;DATASET&gt; &lt;IDENTIFIER&gt; &lt;LEFTPAREN&gt; <A HREF="#prod2">Query</A> &lt;RIGHTPAREN&gt; ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod4">DeleteStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod5">Variable</A> "from" &lt;DATASET&gt; &lt;IDENTIFIER&gt; ( "where" <A HREF="#prod6">Expression</A> )? ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod7">UpdateStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod5">Variable</A> "in" <A HREF="#prod6">Expression</A> "where" <A HREF="#prod6">Expression</A> &lt;LEFTPAREN&gt; ( <A HREF="#prod8">UpdateClause</A> ( "," <A HREF="#prod8">UpdateClause</A> )* ) &lt;RIGHTPAREN&gt; ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod8">UpdateClause</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"set" <A HREF="#prod6">Expression</A> ":=" <A HREF="#prod6">Expression</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"insert" <A HREF="#prod3">InsertStatement</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"delete" <A HREF="#prod4">DeleteStatement</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"update" <A HREF="#prod7">UpdateStatement</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>|</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"if" &lt;LEFTPAREN&gt; <A HREF="#prod6">Expression</A> &lt;RIGHTPAREN&gt; "then" <A HREF="#prod8">UpdateClause</A> ( "else" <A HREF="#prod8">UpdateClause</A> )?</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod9">SetStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; &lt;STRING_LITERAL&gt; ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod10">WriteStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( ( "output" "to" &lt;IDENTIFIER&gt; ":" &lt;STRING_LITERAL&gt; ( "using" &lt;STRING_LITERAL&gt; )? ) | ( "into" &lt;DATASET&gt; &lt;IDENTIFIER&gt; &lt;LEFTPAREN&gt; <A HREF="#prod2">Query</A> &lt;RIGHTPAREN&gt; ) ) ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod11">CreateIndexStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; ( "if not exists" )? "on" &lt;IDENTIFIER&gt; &lt;LEFTPAREN&gt; ( &lt;IDENTIFIER&gt; ) ( "," &lt;IDENTIFIER&gt; )* &lt;RIGHTPAREN&gt; ( "type" ( "btree" | "keyword" | "qgram" | "rtree" ) ";" | ";" )</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod12">DataverseDeclaration</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"dataverse" &lt;IDENTIFIER&gt; ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod13">DropStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; ( "if exists" )? ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod14">IndexDropStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; "." &lt;IDENTIFIER&gt; ( "if exists" )? ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod15">NodeGroupDropStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; ( "if exists" )? ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod16">TypeDropStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; ( "if exists" )? ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod17">DataverseDropStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; ( "if exists" )? ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod18">CreateDataverseStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; ( "if not exists" )? ( "with format" &lt;STRING_LITERAL&gt; )? ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod19">LoadStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;DATASET&gt; &lt;IDENTIFIER&gt; "from" ( &lt;IDENTIFIER&gt; ":" &lt;STRING_LITERAL&gt; ) ( "," &lt;IDENTIFIER&gt; ":" &lt;STRING_LITERAL&gt; )* ( "delimited" "by" &lt;STRING_LITERAL&gt; )? ( "pre-sorted" )? ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod20">EnlistStatement</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;DATASET&gt; &lt;IDENTIFIER&gt; ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod21">DatasetDeclaration</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; ( "if not exists" )? ( &lt;LEFTPAREN&gt; &lt;IDENTIFIER&gt; &lt;RIGHTPAREN&gt; )?</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod22">InternalDatasetDeclaration</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"partitioned" "by" "key" &lt;IDENTIFIER&gt; ( "," &lt;IDENTIFIER&gt; )* "on" &lt;IDENTIFIER&gt; ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod23">ExternalDatasetDeclaration</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( "hdfs" ( &lt;STRING_LITERAL&gt; ) | "splits" ( &lt;IDENTIFIER&gt; ":" &lt;STRING_LITERAL&gt; ) ( "," &lt;IDENTIFIER&gt; ":" &lt;STRING_LITERAL&gt; )* ) "using" ( &lt;STRING_LITERAL&gt; &lt;LEFTPAREN&gt; ( ( &lt;LEFTPAREN&gt; ( &lt;STRING_LITERAL&gt; ":" &lt;STRING_LITERAL&gt; ) &lt;RIGHTPAREN&gt; ) ( "," &lt;LEFTPAREN&gt; ( &lt;STRING_LITERAL&gt; ":" &lt;STRING_LITERAL&gt; ) &lt;RIGHTPAREN&gt; )* )? &lt;RIGHTPAREN&gt; ) ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod24">NodegroupDeclaration</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; ( "if not exists" )? "on" &lt;IDENTIFIER&gt; ( "," &lt;IDENTIFIER&gt; )* ";"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod25">TypeDeclaration</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; ( "if not exists" )? "as" ( <A HREF="#prod26">TypeExpr</A> )</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod26">TypeExpr</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod27">RecordTypeDef</A> | <A HREF="#prod28">TypeReference</A> | <A HREF="#prod29">OrderedListTypeDef</A> | <A HREF="#prod30">UnorderedListTypeDef</A> )</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod27">RecordTypeDef</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( "closed" | "open" )? "{" ( <A HREF="#prod31">RecordField</A> ( "," <A HREF="#prod31">RecordField</A> )* )? "}"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod31">RecordField</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; ":" ( <A HREF="#prod26">TypeExpr</A> ) ( "?" )?</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod28">TypeReference</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt;</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod29">OrderedListTypeDef</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"[" ( <A HREF="#prod26">TypeExpr</A> ) "]"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod30">UnorderedListTypeDef</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"&lt;" ( <A HREF="#prod26">TypeExpr</A> ) "&gt;"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod32">FunctionDeclaration</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IDENTIFIER&gt; &lt;LEFTPAREN&gt; ( &lt;VARIABLE&gt; ( "," &lt;VARIABLE&gt; )* )? &lt;RIGHTPAREN&gt; "{" <A HREF="#prod6">Expression</A> "}"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod2">Query</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod6">Expression</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod6">Expression</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod33">OperatorExpr</A> | <A HREF="#prod34">IfThenElse</A> | <A HREF="#prod35">FLWOGR</A> | <A HREF="#prod36">QuantifiedExpression</A> )</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod33">OperatorExpr</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod37">AndExpr</A> ( "or" <A HREF="#prod37">AndExpr</A> )*</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod37">AndExpr</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod38">RelExpr</A> ( "and" <A HREF="#prod38">RelExpr</A> )*</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod38">RelExpr</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod39">AddExpr</A> ( ( "&lt;" | "&gt;" | "&lt;=" | "&gt;=" | "=" | "!=" | "~=" ) <A HREF="#prod39">AddExpr</A> )?</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod39">AddExpr</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod40">MultExpr</A> ( ( "+" | "-" ) <A HREF="#prod40">MultExpr</A> )*</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod40">MultExpr</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod41">UnionExpr</A> ( ( "*" | "/" | "%" | &lt;CARET&gt; | "idiv" ) <A HREF="#prod41">UnionExpr</A> )*</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod41">UnionExpr</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod42">UnaryExpr</A> ( "union" ( <A HREF="#prod42">UnaryExpr</A> ) )*</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod42">UnaryExpr</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( ( "+" | "-" ) )? <A HREF="#prod43">ValueExpr</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod43">ValueExpr</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod44">FieldOrIndexAccessor</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod44">FieldOrIndexAccessor</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod45">PrimaryExpr</A> ) ( ( <A HREF="#prod46">Field</A> ) | ( <A HREF="#prod47">Index</A> ) )*</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod46">Field</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"." &lt;IDENTIFIER&gt;</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod47">Index</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"[" ( <A HREF="#prod6">Expression</A> | "?" ) "]"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod45">PrimaryExpr</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod48">Literal</A> | <A HREF="#prod49">FunctionCallExpr</A> | <A HREF="#prod50">VariableRef</A> | <A HREF="#prod51">ListConstructor</A> | <A HREF="#prod52">RecordConstructor</A> | <A HREF="#prod53">ParenthesizedExpression</A> )</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod48">Literal</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;STRING_LITERAL&gt; | &lt;INTEGER_LITERAL&gt; | &lt;FLOAT_LITERAL&gt; | &lt;DOUBLE_LITERAL&gt; | &lt;NULL&gt; | &lt;TRUE&gt; | &lt;FALSE&gt; )</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod50">VariableRef</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;VARIABLE&gt;</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod5">Variable</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;VARIABLE&gt;</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod51">ListConstructor</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod54">OrderedListConstructor</A> | <A HREF="#prod55">UnorderedListConstructor</A> )</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod54">OrderedListConstructor</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"[" ( <A HREF="#prod6">Expression</A> ( "," <A HREF="#prod6">Expression</A> )* )? "]"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod55">UnorderedListConstructor</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"&lt;" ( <A HREF="#prod6">Expression</A> ( "," <A HREF="#prod6">Expression</A> )* )? "&gt;"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod52">RecordConstructor</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"{" ( <A HREF="#prod56">FieldBinding</A> ( "," <A HREF="#prod56">FieldBinding</A> )* )? "}"</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod56">FieldBinding</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><A HREF="#prod6">Expression</A> ":" <A HREF="#prod6">Expression</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod49">FunctionCallExpr</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( &lt;IDENTIFIER&gt; | &lt;DATASET&gt; ) &lt;LEFTPAREN&gt; ( <A HREF="#prod6">Expression</A> ( "," <A HREF="#prod6">Expression</A> )* )? &lt;RIGHTPAREN&gt;</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod53">ParenthesizedExpression</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;LEFTPAREN&gt; <A HREF="#prod6">Expression</A> &lt;RIGHTPAREN&gt;</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod34">IfThenElse</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"if" &lt;LEFTPAREN&gt; <A HREF="#prod6">Expression</A> &lt;RIGHTPAREN&gt; "then" <A HREF="#prod6">Expression</A> "else" <A HREF="#prod6">Expression</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod35">FLWOGR</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod57">ForClause</A> | <A HREF="#prod58">LetClause</A> ) ( <A HREF="#prod59">Clause</A> )* "return" <A HREF="#prod6">Expression</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod59">Clause</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod57">ForClause</A> | <A HREF="#prod58">LetClause</A> | <A HREF="#prod60">WhereClause</A> | <A HREF="#prod61">OrderbyClause</A> | <A HREF="#prod62">GroupClause</A> | <A HREF="#prod63">LimitClause</A> | <A HREF="#prod64">DistinctClause</A> )</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod57">ForClause</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"for" <A HREF="#prod5">Variable</A> ( "at" <A HREF="#prod5">Variable</A> )? "in" ( <A HREF="#prod6">Expression</A> )</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod58">LetClause</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"let" <A HREF="#prod5">Variable</A> ":=" <A HREF="#prod6">Expression</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod60">WhereClause</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"where" <A HREF="#prod6">Expression</A></TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod61">OrderbyClause</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( "order" "by" <A HREF="#prod6">Expression</A> ( ( "asc" ) | ( "desc" ) )? ( "," <A HREF="#prod6">Expression</A> ( ( "asc" ) | ( "desc" ) )? )* )</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod62">GroupClause</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"group" "by" ( <A HREF="#prod5">Variable</A> ":=" )? <A HREF="#prod6">Expression</A> ( "," ( <A HREF="#prod5">Variable</A> ":=" )? <A HREF="#prod6">Expression</A> )* ( "decor" <A HREF="#prod5">Variable</A> ":=" <A HREF="#prod6">Expression</A> ( "," "decor" <A HREF="#prod5">Variable</A> ":=" <A HREF="#prod6">Expression</A> )* )? "with" <A HREF="#prod50">VariableRef</A> ( "," <A HREF="#prod50">VariableRef</A> )*</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod63">LimitClause</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"limit" <A HREF="#prod6">Expression</A> ( "offset" <A HREF="#prod6">Expression</A> )?</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod64">DistinctClause</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>"distinct" "by" <A HREF="#prod6">Expression</A> ( "," <A HREF="#prod6">Expression</A> )*</TD>
+</TR>
+<TR>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod36">QuantifiedExpression</A></TD>
+<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( ( "some" ) | ( "every" ) ) <A HREF="#prod5">Variable</A> "in" <A HREF="#prod6">Expression</A> ( "," <A HREF="#prod5">Variable</A> "in" <A HREF="#prod6">Expression</A> )* "satisfies" <A HREF="#prod6">Expression</A></TD>
+</TR>
+</TABLE>
+</BODY>
+</HTML>
diff --git a/asterix-aql/src/main/javacc/AQL.jj b/asterix-aql/src/main/javacc/AQL.jj
new file mode 100644
index 0000000..544e855
--- /dev/null
+++ b/asterix-aql/src/main/javacc/AQL.jj
@@ -0,0 +1,2250 @@
+options {
+
+	  
+       STATIC = false;
+	
+}
+
+
+PARSER_BEGIN(AQLParser)
+
+package edu.uci.ics.asterix.aql.parser;
+
+import java.io.*;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Stack;
+
+import java.util.Map;
+import java.util.HashMap;
+import edu.uci.ics.asterix.aql.literal.FloatLiteral;
+import edu.uci.ics.asterix.aql.literal.DoubleLiteral;
+import edu.uci.ics.asterix.aql.literal.FalseLiteral;
+import edu.uci.ics.asterix.aql.base.ILiteral;
+import edu.uci.ics.asterix.aql.literal.IntegerLiteral;
+import edu.uci.ics.asterix.aql.literal.NullLiteral;
+import edu.uci.ics.asterix.aql.literal.StringLiteral;
+import edu.uci.ics.asterix.aql.literal.TrueLiteral;
+
+import edu.uci.ics.asterix.aql.base.*;
+import edu.uci.ics.asterix.aql.expression.*;
+import edu.uci.ics.asterix.common.config.DatasetConfig.DatasetType;
+import edu.uci.ics.asterix.common.config.DatasetConfig.IndexType;
+import edu.uci.ics.asterix.aql.expression.visitor.AQLPrintVisitor;
+import edu.uci.ics.asterix.aql.expression.UnaryExpr.Sign;
+import edu.uci.ics.asterix.aql.base.Statement.Kind;
+import edu.uci.ics.asterix.aql.context.Scope;
+import edu.uci.ics.asterix.aql.context.RootScopeFactory;
+import edu.uci.ics.asterix.common.annotations.*;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+
+
+public class AQLParser extends ScopeChecker {
+
+/*
+    private void printHints(Token t) {
+       //System.err.println("token="+t.image+"\t special="+t.specialToken); 
+       if (t.specialToken == null) return;
+       Token tmp_t = t.specialToken;
+       while (tmp_t.specialToken != null) tmp_t = tmp_t.specialToken;    
+       while (tmp_t != null) {
+         System.out.println(tmp_t.image);
+         tmp_t = tmp_t.next;
+       }
+    }
+*/
+  
+    // optimizer hints
+    private static final String HASH_GROUP_BY_HINT = "hash";
+    private static final String BROADCAST_JOIN_HINT = "bcast";
+    private static final String INMEMORY_HINT = "inmem";
+    private static final String VAL_FILE_HINT = "val-files";
+    private static final String VAL_FILE_SAME_INDEX_HINT = "val-file-same-idx";
+    private static final String INTERVAL_HINT = "interval";
+    private static final String COMPOSE_VAL_FILES_HINT = "compose-val-files";
+    private static final String INSERT_RAND_INT_HINT = "insert-rand-int";
+    private static final String LIST_VAL_FILE_HINT = "list-val-file";
+    private static final String LIST_HINT = "list";
+    private static final String DATETIME_BETWEEN_YEARS_HINT = "datetime-between-years";
+    private static final String DATE_BETWEEN_YEARS_HINT = "date-between-years";
+    private static final String DATETIME_ADD_RAND_HOURS_HINT = "datetime-add-rand-hours";
+    private static final String AUTO_HINT = "auto";   
+        
+    private static final String GEN_FIELDS_HINT = "gen-fields";   
+    
+    // data generator hints
+    private static final String DGEN_HINT = "dgen";
+   
+    private static String getHint(Token t) {
+       if (t.specialToken == null) {
+         return null;
+       }       
+       String s = t.specialToken.image;
+       int n = s.length();
+       if (n < 2) {
+         return null;
+       }  
+       return s.substring(1).trim();
+    }
+
+	public static void main(String args[]) throws ParseException, TokenMgrError, IOException, FileNotFoundException, AsterixException {
+			File file = new File(args[0]);
+			Reader fis = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
+		    AQLParser parser = new AQLParser(fis);
+		    Statement st = parser.Statement();
+		    st.accept(new AQLPrintVisitor(), 0);
+	}
+
+
+}
+
+PARSER_END(AQLParser)
+
+
+Statement Statement() throws ParseException:
+{
+  Query query = null;
+  scopeStack.push(RootScopeFactory.createRootScope(this));
+  List<Statement> decls = new ArrayList<Statement>();
+}
+{
+    (
+      (
+        ( 
+          "use"
+            {
+              decls.add(DataverseDeclaration());
+            }           
+          | "declare" "function" { 
+                              decls.add(FunctionDeclaration()); 
+             }
+	  	   |  "create" (
+	  	   	  {
+                String hint = getHint(token);
+                boolean dgen = false;
+         	   	if (hint != null && hint.startsWith(DGEN_HINT)) {
+         	   	  dgen = true;
+         	   	}                  
+              } 
+              "type"     
+              	{ 
+                              decls.add(TypeDeclaration(dgen, hint)); 
+                 }
+              | "nodegroup" 
+              	{
+                              decls.add(NodegroupDeclaration());
+                }   
+              | "external" <DATASET>
+            	{   
+              		decls.add(DatasetDeclaration(DatasetType.EXTERNAL));
+            	}
+              | "feed" <DATASET>
+                {
+                   decls.add(DatasetDeclaration(DatasetType.FEED)); 	
+            	}
+              | <DATASET>
+          		{
+            		decls.add(DatasetDeclaration(DatasetType.INTERNAL));
+          		}
+              | "index" 
+              	{
+              				decls.add(CreateIndexStatement());
+                 }
+	          | "dataverse"
+          		{
+            		decls.add(CreateDataverseStatement());
+          		}
+          	  | "function"
+          	    {
+          	        decls.add(FunctionCreation());
+          	    }	
+            )        
+         	 | "load" {
+                       decls.add(LoadStatement());
+                   }  
+          	                    
+          	| "drop"
+			(
+          	<DATASET>
+          	{
+            		decls.add(DropStatement());
+          	}
+        	| "index"
+          	{
+            		decls.add(IndexDropStatement());
+          	}
+        	| "nodegroup"
+          	{
+            		decls.add(NodeGroupDropStatement());
+          	}
+        	| "type"
+          	{
+            		decls.add(TypeDropStatement());
+          	}
+        	| "dataverse"
+          	{
+            		decls.add(DataverseDropStatement());
+          	}
+        	)
+          | "write" {
+                       decls.add(WriteStatement());
+                    }              
+          | "set" {
+                       decls.add(SetStatement());
+                    }                                                      
+	  	  | "insert" {
+		       decls.add(InsertStatement());
+			}
+          | "delete" {
+			decls.add(DeleteStatement());
+		    }
+          | "update" {
+	  		decls.add(UpdateStatement());		
+	  	    } 
+	  	  | "begin" "feed"  <IDENTIFIER> {
+	  	    Identifier datasetName = new Identifier(token.image); 
+	  	    decls.add(new BeginFeedStatement(datasetName, getVarCounter()));
+	  	   } ";"
+	  	  | "suspend" "feed"  <IDENTIFIER> {
+	  	    datasetName = new Identifier(token.image); 
+	  	    decls.add(new ControlFeedStatement(ControlFeedStatement.OperationType.SUSPEND, datasetName));
+	  	   } ";"
+	  	   | "resume" "feed"  <IDENTIFIER> {
+	  	    datasetName = new Identifier(token.image); 
+	  	    decls.add(new ControlFeedStatement(ControlFeedStatement.OperationType.RESUME, datasetName));
+	  	   } ";"
+	  	   | "end" "feed"  <IDENTIFIER> {
+	  	    datasetName = new Identifier(token.image); 
+	  	    decls.add(new ControlFeedStatement(ControlFeedStatement.OperationType.END, datasetName));
+	  	   } ";" 
+	  	   | "alter" "feed" <IDENTIFIER> {
+             datasetName = new Identifier(token.image);
+             decls.add(AlterFeedDeclaration(datasetName));
+           }             
+                                                     
+        )*
+        (query = Query())?
+      )
+
+      <EOF>
+    )
+    {
+      if (query == null) {
+        query = new Query(true);
+      }
+      query.setPrologDeclList(decls);
+    
+      return query;
+    }
+}
+
+InsertStatement InsertStatement() throws ParseException:
+{
+	Identifier datasetName;
+	Query query;
+}
+{
+   "into" <DATASET> <IDENTIFIER> { datasetName = new Identifier(token.image); }
+     		<LEFTPAREN> query = Query() <RIGHTPAREN> ";"
+   {return new InsertStatement(datasetName, query,  getVarCounter());}
+}
+
+DeleteStatement DeleteStatement() throws ParseException:
+{
+	VariableExpr var = null;
+    Identifier datasetName = null;
+	Expression condition = null;
+	Clause dieClause = null;
+}
+{
+   var = Variable() { getCurrentScope().addNewVarSymbolToScope(var.getVar());  }
+	    "from" <DATASET> <IDENTIFIER> { datasetName = new Identifier(token.image); }
+	    ("where" condition = Expression())?  (dieClause = DieClause())? ";"
+   {return new DeleteStatement(var, datasetName, condition,  dieClause, getVarCounter()); }
+}
+
+UpdateStatement UpdateStatement() throws ParseException:
+{
+	VariableExpr vars;
+    Expression target;
+	Expression condition;
+	UpdateClause uc;
+ 	List<UpdateClause> ucs = new ArrayList<UpdateClause>();
+}
+{
+   vars = Variable()  "in" target = Expression()
+	"where" condition = Expression() 
+	<LEFTPAREN> (uc=UpdateClause() {ucs.add(uc); }  ("," uc=UpdateClause() {ucs.add(uc); } )*) <RIGHTPAREN> ";"
+   {return new UpdateStatement(vars, target, condition, ucs);}
+}
+
+
+
+UpdateClause UpdateClause() throws ParseException:
+{
+	Expression target = null;
+	Expression value = null ;	
+	InsertStatement is = null;
+	DeleteStatement ds = null;
+	UpdateStatement us = null;
+	Expression condition = null;
+	UpdateClause ifbranch = null;
+	UpdateClause elsebranch = null;
+}
+{
+   "set" target = Expression() ":=" value = Expression() 
+   | "insert" is = InsertStatement()
+   | "delete" ds = DeleteStatement()
+   | "update" us = UpdateStatement()
+   | "if" <LEFTPAREN> condition = Expression() <RIGHTPAREN> "then" ifbranch = UpdateClause() [LOOKAHEAD(1) "else" elsebranch = UpdateClause()] 
+   {return new UpdateClause(target, value, is, ds, us, condition, ifbranch, elsebranch);}
+}
+
+
+Statement SetStatement() throws ParseException:
+{
+  String pn = null;
+  Statement stmt = null;
+}
+{
+  <IDENTIFIER>  { pn = token.image; }  
+  <STRING_LITERAL>
+    { String pv = removeQuotesAndEscapes(token.image); }
+    ";"
+  {
+    return new SetStatement(pn, pv);
+  }
+}
+
+Statement WriteStatement() throws ParseException:
+{
+  Identifier nodeName = null;
+  String fileName = null;
+  Identifier datasetName = null;
+  Statement stmt = null;
+  Query query;
+  String writerClass = null;
+}
+{
+  (( "output" "to" 
+    <IDENTIFIER> { nodeName = new Identifier(token.image); } 
+    ":" <STRING_LITERAL> { fileName = removeQuotesAndEscapes(token.image); }
+    ( "using" <STRING_LITERAL> { writerClass = removeQuotesAndEscapes(token.image); } )?
+         {                  
+             stmt = new WriteStatement(nodeName, fileName, writerClass);         
+         } )
+    |
+   ( "into" 
+     <DATASET> <IDENTIFIER> { datasetName = new Identifier(token.image); }
+     <LEFTPAREN> query = Query() <RIGHTPAREN>
+     {
+        stmt = new WriteFromQueryResultStatement(datasetName, query, getVarCounter());
+     } ))  
+        
+    ";"
+    {
+      return stmt;
+    }
+}
+
+CreateIndexStatement CreateIndexStatement() throws ParseException:
+{
+  CreateIndexStatement cis = new CreateIndexStatement();
+}
+{
+  <IDENTIFIER> { cis.setIndexName(new Identifier(token.image)); }
+  (
+    "if not exists"
+    {
+      cis.setIfNotExists(true);
+    }
+  )?
+  "on"  
+  <IDENTIFIER> { cis.setDatasetName(new Identifier(token.image)); }
+  <LEFTPAREN>
+  	( <IDENTIFIER> { cis.addFieldExpr(token.image); } )
+  	("," <IDENTIFIER> { cis.addFieldExpr(token.image); })*
+  <RIGHTPAREN>
+    ("type"
+  		("btree" { cis.setIndexType(IndexType.BTREE); }
+  		| "keyword" { cis.setIndexType(IndexType.KEYWORD); }
+  		| "qgram" { cis.setIndexType(IndexType.QGRAM); } 
+  		| "rtree" { cis.setIndexType(IndexType.RTREE); }   		  		  
+		)  
+  	";"  	
+  	| ";"
+    )
+   {
+     return cis;
+   }
+}
+
+DataverseDecl DataverseDeclaration() throws ParseException:
+{
+  Identifier dvName = null;  
+}
+{
+  "dataverse" <IDENTIFIER> { dvName = new Identifier(token.image); }
+  ";"
+  {
+    return new DataverseDecl(dvName);
+  }
+}
+
+DropStatement DropStatement() throws ParseException :
+{
+  Identifier datasetName = null;
+  boolean ifExists = false;
+}
+{
+  < IDENTIFIER >
+  {
+    datasetName = new Identifier(token.image);
+  }
+  (
+    "if exists"
+    {
+      ifExists = true;
+    }
+  )? ";"
+  {
+    return new DropStatement(datasetName, ifExists);
+  }
+}
+
+IndexDropStatement IndexDropStatement() throws ParseException :
+{
+  Identifier datasetName = null;
+  Identifier indexName = null;
+  boolean ifExists = false;
+}
+{
+  < IDENTIFIER >
+  {
+    datasetName = new Identifier(token.image);
+  }
+  "." < IDENTIFIER >
+  {
+    indexName = new Identifier(token.image);
+  }
+  (
+    "if exists"
+    {
+      ifExists = true;
+    }
+  )? ";"
+  {
+    return new IndexDropStatement(datasetName, indexName, ifExists);
+  }
+}
+
+NodeGroupDropStatement NodeGroupDropStatement() throws ParseException :
+{
+  Identifier groupName = null;
+  boolean ifExists = false;
+}
+{
+  < IDENTIFIER >
+  {
+    groupName = new Identifier(token.image);
+  }
+  (
+    "if exists"
+    {
+      ifExists = true;
+    }
+  )? ";"
+  {
+    return new NodeGroupDropStatement(groupName, ifExists);
+  }
+}
+
+TypeDropStatement TypeDropStatement() throws ParseException :
+{
+  Identifier typeName = null;
+  boolean ifExists = false;
+}
+{
+  < IDENTIFIER >
+  {
+    typeName = new Identifier(token.image);
+  }
+  (
+    "if exists"
+    {
+      ifExists = true;
+    }
+  )? ";"
+  {
+    return new TypeDropStatement(typeName, ifExists);
+  }
+}
+
+DataverseDropStatement DataverseDropStatement() throws ParseException :
+{
+  Identifier dataverseName = null;
+  boolean ifExists = false;
+}
+{
+  < IDENTIFIER >
+  {
+    dataverseName = new Identifier(token.image);
+  }
+  (
+    "if exists"
+    {
+      ifExists = true;
+    }
+  )? ";"
+  {
+    return new DataverseDropStatement(dataverseName, ifExists);
+  }
+}
+
+CreateDataverseStatement CreateDataverseStatement() throws ParseException :
+{
+  Identifier dvName = null;
+  boolean ifNotExists = false;
+  String format = null;
+}
+{
+  < IDENTIFIER >
+  {
+    dvName = new Identifier(token.image);
+  }
+  (
+    "if not exists"
+    {
+      ifNotExists = true;
+    }
+  )?
+  (
+    "with format" < STRING_LITERAL >
+    {
+      format = removeQuotesAndEscapes(token.image);
+    }
+  )?
+  ";"
+  {
+    return new CreateDataverseStatement(dvName, format, ifNotExists);
+  }
+}
+
+LoadFromFileStatement LoadStatement() throws ParseException:
+{
+  Identifier datasetName = null;
+  boolean alreadySorted = false;
+  String adapterClassname;
+  Map<String,String> properties;
+}
+{
+   <DATASET> <IDENTIFIER> { datasetName = new Identifier(token.image); }
+ 
+   "using"
+
+    <STRING_LITERAL>
+    {
+      adapterClassname = removeQuotesAndEscapes(token.image);
+    }
+
+    {
+      properties = getConfiguration();
+    }
+  
+    ("pre-sorted" 
+      {  alreadySorted = true; }
+    )?
+        
+  ";"
+  {
+     return new LoadFromFileStatement(datasetName, adapterClassname, properties, alreadySorted);
+  }   
+}
+
+
+
+DatasetDecl DatasetDeclaration(DatasetType datasetType) throws ParseException :
+{
+  DatasetDecl dd = null;
+  Identifier datasetName = null;
+  Identifier itemTypeName = null;
+  boolean ifNotExists = false;
+  IDatasetDetailsDecl idd = null;
+}
+{
+  < IDENTIFIER >
+  {
+    datasetName = new Identifier(token.image);
+  }
+  (
+    "if not exists"
+    {
+      ifNotExists = true;
+    }
+  )?
+  (
+  	< LEFTPAREN > < IDENTIFIER >
+  	{
+    	itemTypeName = new Identifier(token.image);
+  	}
+  	< RIGHTPAREN >
+  )?
+  {
+  	  if(datasetType == DatasetType.INTERNAL) {
+      	idd = InternalDatasetDeclaration();
+      	dd = new DatasetDecl(datasetName, itemTypeName, idd, ifNotExists);
+      }
+      else if(datasetType == DatasetType.EXTERNAL) {
+      	idd = ExternalDatasetDeclaration();
+      	dd = new DatasetDecl(datasetName, itemTypeName, idd,ifNotExists);
+      }
+      else if(datasetType == DatasetType.FEED) {
+      	idd = FeedDatasetDeclaration();
+      	dd = new DatasetDecl(datasetName, itemTypeName, idd,ifNotExists);
+      }
+      dd.setDatasetType(datasetType);
+  }
+  {
+    return dd;
+  }
+}
+
+InternalDetailsDecl InternalDatasetDeclaration() throws ParseException :
+{
+    InternalDetailsDecl idd = null;
+}
+{
+  {
+    idd = new InternalDetailsDecl();
+  }
+  "partitioned" "by" "key"
+  < IDENTIFIER >
+  {
+    	 idd.addPartitioningExpr(token.image);
+  }
+  (
+    "," < IDENTIFIER >
+    {
+      	idd.addPartitioningExpr(token.image);
+    }
+  )*
+  (
+  "on" < IDENTIFIER >
+    {
+    	idd.setNodegroupName(new Identifier(token.image));
+    }
+  )?
+  ";"
+  {
+    return idd;
+  }
+}
+
+ExternalDetailsDecl ExternalDatasetDeclaration() throws ParseException :
+{
+  ExternalDetailsDecl edd = null;
+  String adapterClassname = null;
+  Map < String, String > properties;
+}
+{
+  {
+    edd = new ExternalDetailsDecl();
+  }
+ 
+    "using"
+    
+     <STRING_LITERAL>
+    {
+      adapterClassname = removeQuotesAndEscapes(token.image);
+    }
+
+    {
+      properties = getConfiguration();
+    }
+
+    {
+    	  edd = new ExternalDetailsDecl();
+		  edd.setAdapter(adapterClassname);
+   		  edd.setProperties(properties);
+    } 
+  ";"
+ 
+  {
+    return edd;
+  }
+}
+
+FeedDetailsDecl FeedDatasetDeclaration() throws ParseException :
+{
+    FeedDetailsDecl fdd = null;
+    String adapterClassname = null;
+    Map < String, String > properties;
+}
+{
+  {
+    fdd = new FeedDetailsDecl();
+  }
+  
+   "using"
+   
+    <STRING_LITERAL>
+    {
+      adapterClassname = removeQuotesAndEscapes(token.image);
+    }
+
+    {
+      properties = getConfiguration();
+    }
+  
+  ("apply" "function" 
+  < IDENTIFIER >
+  {
+      fdd.setFunctionIdentifier(token.image);
+  }
+  )?
+  
+  "partitioned" "by" "key"
+  < IDENTIFIER >
+  {
+    	 fdd.addPartitioningExpr(token.image);
+  }
+  (
+    "," < IDENTIFIER >
+    {
+      	fdd.addPartitioningExpr(token.image);
+    }
+  )*
+  (
+  "on" < IDENTIFIER >
+  {
+    	fdd.setNodegroupName(new Identifier(token.image));
+  }
+  )?
+  ";"
+  {
+    fdd.setAdapterClassname(adapterClassname);
+    fdd.setProperties(properties);
+    return fdd;
+  }
+}
+
+ControlFeedStatement AlterFeedDeclaration(Identifier datasetName) throws ParseException :
+{
+    String name = null;
+    String value = null;
+    Map < String, String > configuration = new HashMap < String, String > ();
+}
+{
+   "set"
+   { 
+   configuration = getConfiguration();
+   }
+  ";"
+  {
+    return new ControlFeedStatement(ControlFeedStatement.OperationType.ALTER, datasetName, configuration);
+  }
+}
+
+Map<String,String> getConfiguration()  throws ParseException :
+{
+	Map<String,String> configuration = new HashMap<String,String>();
+	String key;
+	String value;
+}
+{
+
+<LEFTPAREN>
+    (
+      (
+        <LEFTPAREN>
+        (
+          <STRING_LITERAL>
+          {
+            key = removeQuotesAndEscapes(token.image);
+          }
+          "=" <STRING_LITERAL>
+          {
+            value = removeQuotesAndEscapes(token.image);
+          }
+        )
+        <RIGHTPAREN>
+        {
+          configuration.put(key, value);
+        }
+      )
+      (
+        "," <LEFTPAREN>
+        (
+          <STRING_LITERAL>
+          {
+            key = removeQuotesAndEscapes(token.image);
+          }
+          "=" <STRING_LITERAL>
+          {
+            value = removeQuotesAndEscapes(token.image);
+          }
+        )
+        <RIGHTPAREN>
+        {
+          configuration.put(key, value);
+        }
+      )*
+    )?
+    <RIGHTPAREN>
+     {
+     	return configuration;
+     }
+}
+
+
+NodegroupDecl NodegroupDeclaration() throws ParseException :
+{
+  Identifier name = null;
+  List < Identifier > ncNames = new ArrayList < Identifier > ();
+  boolean ifNotExists = false;
+}
+{
+  < IDENTIFIER >
+  {
+    name = new Identifier(token.image);
+  }
+  (
+    "if not exists"
+    { 
+      ifNotExists = true;
+    }
+  )?
+  "on" < IDENTIFIER >
+  {
+    ncNames.add(new Identifier(token.image));
+  }
+  (
+    "," < IDENTIFIER >
+    {
+      ncNames.add(new Identifier(token.image));
+    }
+  )*
+  ";"
+  {
+    return new NodegroupDecl(name, ncNames, ifNotExists);
+  }
+}
+
+
+TypeDecl TypeDeclaration(boolean dgen, String hint) throws ParseException:
+{
+  Identifier ident;
+  TypeExpression typeExpr;
+  boolean ifNotExists = false;
+}
+{
+  <IDENTIFIER>
+  {
+    ident = new Identifier(token.image.toString());
+  }
+  (
+    "if not exists"
+    {
+      ifNotExists = true;
+    }
+  )?
+  "as"
+  ( typeExpr = TypeExpr() )
+  {
+    long numValues = -1;
+    String filename = null;
+    if (dgen) {       
+      String splits[] = hint.split(" +");
+      if (splits.length != 3) {
+        throw new ParseException("Expecting /*+ dgen <filename> <numberOfItems> */");
+      } 
+      filename = splits[1];
+      numValues = Long.parseLong(splits[2]);
+    }  
+    TypeDataGen tddg = new TypeDataGen(dgen, filename, numValues);
+    return new TypeDecl(ident, typeExpr, tddg, ifNotExists);
+  }
+}
+
+TypeExpression TypeExpr() throws ParseException:
+{
+  TypeExpression typeExpr = null;
+}
+{
+  (
+      typeExpr = RecordTypeDef()
+    | typeExpr = TypeReference()
+    | typeExpr = OrderedListTypeDef()
+    | typeExpr = UnorderedListTypeDef()  
+  )  
+  {
+    return typeExpr;
+  }
+}
+
+RecordTypeDefinition RecordTypeDef() throws ParseException:
+{
+  RecordTypeDefinition recType = new RecordTypeDefinition();
+  RecordTypeDefinition.RecordKind recordKind = null; 
+}
+{
+  ( "closed" { recordKind = RecordTypeDefinition.RecordKind.CLOSED; } 
+    | "open" { recordKind = RecordTypeDefinition.RecordKind.OPEN; } )?
+   "{"
+    {
+      String hint = getHint(token);
+      if (hint != null) { 
+        String splits[] = hint.split(" +");
+        if (splits[0].equals(GEN_FIELDS_HINT)) {
+          if (splits.length != 5) {
+            throw new ParseException("Expecting: /*+ gen-fields <type> <min> <max> <prefix>*/");
+          }
+          if (!splits[1].equals("int")) {
+            throw new ParseException("The only supported type for gen-fields is int.");
+          } 
+          UndeclaredFieldsDataGen ufdg = new UndeclaredFieldsDataGen(UndeclaredFieldsDataGen.Type.INT, 
+             Integer.parseInt(splits[2]), Integer.parseInt(splits[3]), splits[4]);
+          recType.setUndeclaredFieldsDataGen(ufdg);   
+        }
+      }  
+      
+    }
+		( 
+		  RecordField(recType)
+		  ( ","  RecordField(recType) )*
+		)?
+   "}"
+   {
+      if (recordKind == null) {
+        recordKind = RecordTypeDefinition.RecordKind.OPEN;
+      }
+      recType.setRecordKind(recordKind);
+      return recType;
+   } 
+}
+
+void RecordField(RecordTypeDefinition recType) throws ParseException:
+{
+        String fieldName;
+        TypeExpression type = null; 
+        boolean nullable = false;
+}
+{
+      <IDENTIFIER>
+      	{
+	     Token t = getToken(0);
+	     fieldName = t.toString();	     	     
+         String hint = getHint(t);
+         IRecordFieldDataGen rfdg = null;
+         if (hint != null) { 
+           String splits[] = hint.split(" +");
+           if (splits[0].equals(VAL_FILE_HINT)) { 
+             File[] valFiles = new File[splits.length - 1];
+             for (int k=1; k<splits.length; k++) {
+               valFiles[k-1] = new File(splits[k]);
+             } 
+             rfdg = new FieldValFileDataGen(valFiles);
+           } else if (splits[0].equals(VAL_FILE_SAME_INDEX_HINT)) {
+             rfdg = new FieldValFileSameIndexDataGen(new File(splits[1]), splits[2]);
+           } else if (splits[0].equals(LIST_VAL_FILE_HINT)) {
+             rfdg = new ListValFileDataGen(new File(splits[1]), Integer.parseInt(splits[2]), Integer.parseInt(splits[3]));
+           } else if (splits[0].equals(LIST_HINT)) {
+             rfdg = new ListDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
+           } else if (splits[0].equals(INTERVAL_HINT)) {
+             FieldIntervalDataGen.ValueType vt;
+             if (splits[1].equals("int")) {
+               vt = FieldIntervalDataGen.ValueType.INT;
+             } else if (splits[1].equals("long")) {
+               vt = FieldIntervalDataGen.ValueType.LONG;
+             } else if (splits[1].equals("float")) {
+               vt = FieldIntervalDataGen.ValueType.FLOAT;
+             } else if (splits[1].equals("double")) {
+               vt = FieldIntervalDataGen.ValueType.DOUBLE;
+             } else {
+               throw new ParseException("Unknown type for interval data gen: " + splits[1]);
+             }
+             rfdg = new FieldIntervalDataGen(vt, splits[2], splits[3]); 
+           } else if (splits[0].equals(INSERT_RAND_INT_HINT)) {
+             rfdg = new InsertRandIntDataGen(splits[1], splits[2]);
+           } else if (splits[0].equals(DATE_BETWEEN_YEARS_HINT)) {
+             rfdg = new DateBetweenYearsDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
+           } else if (splits[0].equals(DATETIME_BETWEEN_YEARS_HINT)) {
+             rfdg = new DatetimeBetweenYearsDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]));
+           } else if (splits[0].equals(DATETIME_ADD_RAND_HOURS_HINT)) {
+             rfdg = new DatetimeAddRandHoursDataGen(Integer.parseInt(splits[1]), Integer.parseInt(splits[2]), splits[3]);
+           } else if (splits[0].equals(AUTO_HINT)) {
+              rfdg = new AutoDataGen(splits[1]);
+           }
+         }
+	    }
+	  ":"
+	  ( type =  TypeExpr() )
+	  ("?" { nullable = true; } )?
+	  {
+	     recType.addField(fieldName, type, nullable, rfdg);
+	  }   
+}
+
+TypeReferenceExpression TypeReference() throws ParseException:
+{}
+{
+  <IDENTIFIER>
+  	{
+	  Token t = getToken(0);
+	  Identifier id = new Identifier(t.toString());
+	  return new TypeReferenceExpression(id);
+	}      
+}
+
+OrderedListTypeDefinition OrderedListTypeDef() throws ParseException:
+{  
+  TypeExpression type = null;
+}
+{
+  "["
+    ( type =  TypeExpr() )
+  "]"
+  {
+    return new OrderedListTypeDefinition(type);
+  }
+}
+
+
+UnorderedListTypeDefinition UnorderedListTypeDef() throws ParseException:
+{  
+  TypeExpression type = null;
+}
+{
+  "{{"
+    ( type =  TypeExpr() )
+  "}}"
+  {
+    return new UnorderedListTypeDefinition(type);
+  }
+}
+
+
+FunctionDecl FunctionDeclaration() throws ParseException:
+{
+  FunctionDecl func = new FunctionDecl();
+  FunIdentifier ident = new FunIdentifier();
+  int arity = 0;
+  List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
+  Expression funcBody;
+  VarIdentifier var = null;
+  createNewScope();
+}
+{
+
+    <IDENTIFIER>
+	{
+	  Token t = getToken(0);
+	  ident.setValue(t.toString());
+	}
+    <LEFTPAREN> (<VARIABLE>
+    {
+      var = new VarIdentifier();
+      var.setValue(getToken(0).toString());
+      paramList.add(var);
+      getCurrentScope().addNewVarSymbolToScope(var);
+      arity++;
+    }
+    ("," <VARIABLE>
+    {
+      var = new VarIdentifier();
+      var.setValue(getToken(0).toString());
+      paramList.add(var);
+      getCurrentScope().addNewVarSymbolToScope(var);
+      arity++;
+    })*)? <RIGHTPAREN> "{" funcBody = Expression() "}"
+
+    {
+      ident.setArity(arity);
+      getCurrentScope().addFunctionDescriptor(ident, false);
+      func.setIdent(ident);
+      func.setFuncBody(funcBody);
+      func.setParamList(paramList);
+      return func;
+    }
+}
+
+CreateFunctionStatement FunctionCreation() throws ParseException:
+{
+  CreateFunctionStatement cfs = null;
+  FunIdentifier ident = new FunIdentifier();
+  int arity = 0;
+  boolean ifNotExists = false;
+  List<VarIdentifier> paramList = new ArrayList<VarIdentifier>();
+  String funcBody;
+  VarIdentifier var = null;
+  createNewScope();
+}
+{
+
+    <IDENTIFIER>
+	{
+	  Token t = getToken(0);
+	  ident.setValue(t.toString());
+	}
+	
+	(
+      "if not exists"
+       {
+         ifNotExists = true;
+       }
+    )?
+	
+    <LEFTPAREN> (<VARIABLE>
+    {
+      var = new VarIdentifier();
+      var.setValue(getToken(0).toString());
+      paramList.add(var);
+      getCurrentScope().addNewVarSymbolToScope(var);
+      arity++;
+    }
+    ("," <VARIABLE>
+    {
+      var = new VarIdentifier();
+      var.setValue(getToken(0).toString());
+      paramList.add(var);
+      getCurrentScope().addNewVarSymbolToScope(var);
+      arity++;
+    })*)? <RIGHTPAREN>  "{" <STRING_LITERAL>
+          {
+            funcBody = removeQuotesAndEscapes(token.image);
+          }
+          "}"
+    {
+      ident.setArity(arity);
+      getCurrentScope().addFunctionDescriptor(ident, false);
+      cfs = new CreateFunctionStatement(ident, paramList, funcBody, ifNotExists);
+      return cfs;
+    }
+}
+
+
+
+Query Query()throws ParseException:
+{
+  Query query = new Query();
+  Expression expr;
+}
+{
+    expr = Expression()
+
+    {
+      query.setBody(expr);
+      return query;
+    }
+}
+
+
+
+Expression Expression():
+{
+  Expression expr = null;
+  Expression exprP = null;
+}
+{
+(
+  
+//OperatorExpr | IfThenElse | FLWOGRExpression | QuantifiedExpression
+    expr = OperatorExpr()
+    | expr = IfThenElse()
+    | expr = FLWOGR()
+    | expr = QuantifiedExpression()
+
+
+)
+	{
+	  return (exprP==null) ? expr : exprP;
+	}
+}
+
+
+
+Expression OperatorExpr()throws ParseException:
+{
+  OperatorExpr op = null;
+  Expression operand = null;
+}
+{
+	operand = AndExpr()
+	(
+	
+	  "or"
+  	{
+  	  if (op == null) {
+  	    op = new OperatorExpr();
+  	    op.addOperand(operand);
+	    op.setCurrentop(true);  	      	     
+  	  }  
+  	  Token t = getToken(0);
+      op.addOperator(t.toString());
+	}
+
+	operand = AndExpr()
+	{
+	  op.addOperand(operand);
+	}
+
+	)*
+	
+	{
+	  return op==null? operand: op;
+	}
+}
+
+Expression AndExpr()throws ParseException:
+{
+  OperatorExpr op = null;
+  Expression operand = null;
+}
+{
+	operand = RelExpr()
+	(
+	
+	  "and"
+  	{
+  	  if (op == null) {
+  	    op = new OperatorExpr();
+  	    op.addOperand(operand);
+	    op.setCurrentop(true);  	      	     
+  	  }  
+  	  Token t = getToken(0);
+      op.addOperator(t.toString());
+	}
+
+	operand = RelExpr()
+	{
+	  op.addOperand(operand);
+	}
+
+	)*
+	
+	{
+	  return op==null? operand: op;
+	}
+}
+
+
+
+Expression RelExpr()throws ParseException:
+{
+  OperatorExpr op = null;
+  Expression operand = null;
+  boolean broadcast = false;
+}
+{
+    operand = AddExpr()
+    {
+      if (operand instanceof VariableExpr) {
+        String hint = getHint(token);
+        if (hint != null && hint.equals(BROADCAST_JOIN_HINT)) {
+          broadcast = true;       
+        }
+      }
+    } 
+
+    (
+      LOOKAHEAD(2)( "<" | ">" | "<=" | ">=" | "=" | "!=" |"~=")
+  	  {
+  	    if (op == null) {
+  	      op = new OperatorExpr();
+  	      op.addOperand(operand, broadcast);
+          op.setCurrentop(true);
+          broadcast = false;
+  	    }   
+  	    Token t = getToken(0);
+        op.addOperator(t.toString());
+	  }
+	  
+ 	  operand = AddExpr()
+	  {
+         broadcast = false;
+	     if (operand instanceof VariableExpr) {
+           String hint = getHint(token);
+           if (hint != null && hint.equals(BROADCAST_JOIN_HINT)) {
+             broadcast = true;
+           }
+         } 
+         op.addOperand(operand, broadcast);
+      } 
+    )?
+ 	
+ 	{
+ 	  return op==null? operand: op;
+ 	}
+}
+
+Expression AddExpr()throws ParseException:
+{
+  OperatorExpr op = null;
+  Expression operand = null;  
+}
+{
+	operand = MultExpr()
+
+	( ("+" | "-")
+  	{
+  	  if (op == null) {
+  	    op = new OperatorExpr();
+        op.addOperand(operand);  	    
+        op.setCurrentop(true);        
+  	  } 
+  	  Token t = getToken(0);
+	  ((OperatorExpr)op).addOperator(t.toString());
+	}
+
+	operand = MultExpr()
+	{
+	  op.addOperand(operand);
+	}
+	)*
+	
+	{
+ 	  return op==null? operand: op;
+ 	}
+}
+
+Expression MultExpr()throws ParseException:
+{
+  OperatorExpr op = null;
+  Expression operand = null;
+}
+{
+	operand = UnionExpr()
+
+	(( "*" | "/" | "%" | <CARET> | "idiv")
+  	{
+  	  if (op == null) {
+  	    op = new OperatorExpr();
+        op.addOperand(operand);
+        op.setCurrentop(true);          	    
+  	  } 
+  	  Token t = getToken(0);
+	  op.addOperator(t.toString());
+	}
+	operand = UnionExpr()
+	{
+	   op.addOperand(operand);
+	}
+	)*
+	
+ 	{
+ 	  return op==null?operand:op;
+ 	}	
+}
+
+Expression UnionExpr() throws ParseException:
+{
+    UnionExpr union = null;
+    Expression operand1 = null;
+    Expression operand2 = null;
+}
+{
+   operand1 = UnaryExpr() 
+   ("union" 
+       (operand2 = UnaryExpr()) {
+          if (union == null) {
+             union = new UnionExpr();
+             union.addExpr(operand1); 
+          }
+          union.addExpr(operand2);   
+       } )*
+   {
+     return (union == null)? operand1: union;
+   }
+}
+
+Expression UnaryExpr() throws ParseException:
+{
+	Expression uexpr = null;
+	Expression expr = null;
+}
+{
+	(( "+"|"-") 
+	{
+	  	uexpr = new UnaryExpr(); 
+		Token t = getToken(0);
+		if("+".equals(t.toString()))
+			((UnaryExpr)uexpr).setSign(Sign.POSITIVE);
+		else if("-".equals(t.toString()))
+			((UnaryExpr)uexpr).setSign(Sign.NEGATIVE);
+		else 
+			throw new ParseException();
+	}
+	)?
+	
+	expr = ValueExpr()
+	{
+		if(uexpr!=null){
+			((UnaryExpr)uexpr).setExpr(expr);
+			return uexpr;
+		}
+		else{
+			return expr;
+		}
+	}
+}
+
+Expression ValueExpr() throws ParseException:
+{
+  Expression expr;
+}
+{
+  expr = FieldOrIndexAccessor()
+  {
+    return expr;
+  }
+}
+
+
+Expression FieldOrIndexAccessor()throws ParseException:
+{
+  Expression expr = null;
+  Identifier ident = null;
+  AbstractAccessor fa = null;
+  int index;
+
+}
+{
+	( expr = PrimaryExpr()
+
+	)
+
+
+	(
+	(
+	  	ident = Field()
+	{
+		  if(fa == null)
+		  	fa = new FieldAccessor(expr, ident);
+		  else
+		  	fa = new FieldAccessor(fa, ident);
+	}
+	)
+	| (
+		index = Index()
+		{
+		  if(fa == null)
+		  	fa = new IndexAccessor(expr, index);
+		  else
+		  	fa = new IndexAccessor(fa, index);
+		}
+	) 
+	)*
+
+	
+  	{
+ 	  return fa==null?expr:fa;
+ 	}
+}
+
+Identifier Field() throws ParseException:
+{
+  Identifier ident = null;
+
+}
+{
+  "." < IDENTIFIER >
+  	{
+    
+  	ident = new Identifier();
+	ident.setValue(getToken(0).toString());
+
+	  return ident;
+	}
+}
+
+int Index() throws ParseException:
+{
+	Expression expr = null;
+	int idx = -2;
+}
+{
+  "[" ( expr = Expression()
+	{
+		if(expr.getKind() == Expression.Kind.LITERAL_EXPRESSION)
+		{
+			ILiteral lit = ((LiteralExpr)expr).getValue();
+			if(lit.getLiteralType() == ILiteral.Type.INTEGER) {
+				idx = Integer.valueOf(lit.getStringValue());
+			}	
+			else {
+				throw new ParseException("Index should be an INTEGER");				
+            }
+		}
+
+	}
+
+  	| "?"
+	{
+		idx = IndexAccessor.ANY;
+	  // ANY
+	}
+ 	 
+  	)
+
+   "]"
+	{
+	  return idx;
+	}
+}
+
+
+Expression PrimaryExpr()throws ParseException:
+{
+  Expression expr = null;
+}
+{
+  //ILiteral | VariableRef | ListConstructor | RecordConstructor | FunctionCallExpr | ParenthesizedExpression
+	(
+	  expr =Literal() 
+	   | expr = FunctionCallExpr()
+	   | expr =VariableRef() 
+	   
+    {
+      if(((VariableExpr)expr).getIsNewVar() == true)
+      	throw new ParseException("can't find variable " + ((VariableExpr)expr).getVar());
+    }
+    	   | expr = ListConstructor()
+	   | expr = RecordConstructor()
+	   | expr = ParenthesizedExpression()
+	)
+ 	{
+ 	  return expr;
+ 	}
+}
+
+Expression Literal() throws ParseException:
+{
+
+  LiteralExpr lit = new LiteralExpr();
+  Token t;
+}
+{
+(
+      <STRING_LITERAL>
+	{
+	  t= getToken(0);
+	  lit.setValue( new StringLiteral(removeQuotesAndEscapes(t.image)));
+	}
+    
+ 	 | <INTEGER_LITERAL>
+    {
+      t= getToken(0);
+	  lit.setValue(new IntegerLiteral(new Integer(t.image)));
+	}
+     | < FLOAT_LITERAL >
+    {
+      t= getToken(0);
+      lit.setValue(new FloatLiteral(new Float(t.image)));
+    }     
+	 | < DOUBLE_LITERAL >
+    {
+      t= getToken(0);
+	  lit.setValue(new DoubleLiteral(new Double(t.image)));
+	}	  
+ 	 | <NULL>
+	{
+	  t= getToken(0);
+	  lit.setValue(NullLiteral.INSTANCE);
+	}
+   	 | <TRUE>
+	{
+	  t= getToken(0);
+	  lit.setValue(TrueLiteral.INSTANCE);
+	}   	 
+   	 | <FALSE>
+	{
+	  t= getToken(0);
+	  lit.setValue(FalseLiteral.INSTANCE);
+	}
+)
+    {
+      return lit;
+    }
+}
+
+
+VariableExpr VariableRef() throws ParseException:
+{
+	VariableExpr varExp = new VariableExpr();
+	VarIdentifier var = new VarIdentifier();
+	Token t;
+}
+{
+      <VARIABLE>
+    {
+     t = getToken(0);//get current token
+     String varName = t.toString(); 
+     Identifier ident = lookupSymbol(varName);
+     if (isInForbiddenScopes(varName)) {
+       throw new ParseException("Inside limit clauses, it is disallowed to reference a variable having the same name as any variable bound in the same scope as the limit clause.");
+     }
+     if(ident != null) { // exist such ident
+       varExp.setIsNewVar(false);
+       varExp.setVar((VarIdentifier)ident);       
+     } else {
+       varExp.setVar(var);     
+     }
+     var.setValue(t.toString());        
+     return varExp;
+    }
+}
+
+
+VariableExpr Variable() throws ParseException:
+{
+	VariableExpr varExp = new VariableExpr();
+	VarIdentifier var = new VarIdentifier();
+	Token t;
+}
+{
+      <VARIABLE>
+    {
+     t = getToken(0);//get current token
+     Identifier ident = lookupSymbol(t.toString());
+     if(ident != null) { // exist such ident
+       varExp.setIsNewVar(false);
+     }  
+     varExp.setVar(var);     
+     var.setValue(t.toString());        
+     return varExp;
+    }
+}
+
+Expression ListConstructor() throws ParseException:
+{
+	Expression expr = null;
+}
+{
+    (
+    	expr = OrderedListConstructor() | expr = UnorderedListConstructor()
+    )
+    
+    {
+      return expr;
+    }
+}
+
+
+ListConstructor OrderedListConstructor() throws ParseException:
+{
+  	ListConstructor expr = new ListConstructor();
+  	Expression tmp = null;
+  	List<Expression> exprList = new ArrayList<Expression>();
+  	expr.setType(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR);
+}
+{
+
+    "[" 
+	    ( tmp = Expression()
+			{
+			  exprList.add(tmp);
+			}
+		
+		    ("," tmp = Expression() { exprList.add(tmp);  })*
+	    )? 
+    
+    "]"
+
+    {
+      expr.setExprList(exprList);
+      return expr;
+    }    
+}
+
+ListConstructor UnorderedListConstructor() throws ParseException:
+{
+  	ListConstructor expr = new ListConstructor();
+  	Expression tmp = null;
+  	List<Expression> exprList = new ArrayList<Expression>();
+  	expr.setType(ListConstructor.Type.UNORDERED_LIST_CONSTRUCTOR);
+}
+{
+
+    "{{" ( tmp = Expression()
+	{
+	  exprList.add(tmp);
+	}
+    ("," tmp = Expression() { exprList.add(tmp);  })*)? "}}"
+    {
+      expr.setExprList(exprList);
+      return expr;
+    }    
+}
+
+RecordConstructor RecordConstructor() throws ParseException:
+{
+  	RecordConstructor expr = new RecordConstructor();
+  	FieldBinding tmp = null;
+  	List<FieldBinding> fbList = new ArrayList<FieldBinding>();
+}
+{
+    "{" (tmp = FieldBinding()
+    {
+      fbList.add(tmp);
+    }
+    ("," tmp = FieldBinding() { fbList.add(tmp);  })*)? "}"
+    {
+      expr.setFbList(fbList);
+      return expr;
+    }       
+}
+
+FieldBinding FieldBinding() throws ParseException:
+{
+	FieldBinding fb = new FieldBinding();
+	Expression left, right;
+}
+{
+    left = Expression() ":" right = Expression()
+    {
+      fb.setLeftExpr(left);
+      fb.setRightExpr(right);
+      return fb;
+    }
+}
+
+Expression FunctionCallExpr() throws ParseException:
+{
+  CallExpr pf = new CallExpr();
+  List<Expression > argList = new ArrayList<Expression >();
+  Expression tmp;
+  int arity = 0;
+  Token funcName;
+}
+{
+    ( <IDENTIFIER> | <DATASET> )
+    {
+		funcName = getToken(0);
+    }
+     <LEFTPAREN> (tmp = Expression()
+     {
+       argList.add(tmp);
+       arity ++;
+     } ("," tmp = Expression() { argList.add(tmp); arity++; })*)? <RIGHTPAREN>
+
+     {
+       FunIdentifier fd = lookupFunctionSignature(funcName.toString(), arity);
+	     if(fd == null)
+	     {
+	        fd = new FunIdentifier(funcName.toString(), arity);
+//	     	notFoundFunctionList.add(fd);
+	     }
+//	     	throw new ParseException("can't find function "+ funcName.toString() + "@" + arity);
+       pf.setIdent(fd);
+       pf.setExprList(argList);
+       return pf;
+     }
+}
+
+
+Expression ParenthesizedExpression() throws ParseException:
+{
+  Expression expr;
+}
+{
+    <LEFTPAREN> expr = Expression() <RIGHTPAREN>
+    {
+      return expr;
+    }
+}
+
+Expression IfThenElse() throws ParseException:
+{
+  Expression condExpr;
+  Expression thenExpr;
+  Expression elseExpr;
+  IfExpr ifExpr = new IfExpr();
+}
+{
+    "if" <LEFTPAREN> condExpr = Expression() <RIGHTPAREN> "then" thenExpr = Expression() "else" elseExpr = Expression()
+
+    {
+      ifExpr.setCondExpr(condExpr);
+      ifExpr.setThenExpr(thenExpr);
+      ifExpr.setElseExpr(elseExpr);
+      return ifExpr;
+    }
+}
+
+Expression  FLWOGR() throws ParseException:
+{
+	FLWOGRExpression flworg = new FLWOGRExpression();
+	List<Clause> clauseList = new ArrayList<Clause>();
+	Expression returnExpr;
+	Clause tmp;
+	createNewScope();
+}
+{
+     (tmp = ForClause()  {clauseList.add(tmp);} | tmp = LetClause() {clauseList.add(tmp);})
+      (tmp = Clause() {clauseList.add(tmp);})* "return" returnExpr = Expression()
+
+     {
+       flworg.setClauseList(clauseList);
+       flworg.setReturnExpr(returnExpr);
+       removeCurrentScope();
+       return flworg;
+     }
+}
+
+Clause Clause()throws ParseException :
+{
+  Clause clause;
+}
+{
+    (
+         clause = ForClause() 
+       | clause = LetClause() 
+       | clause = WhereClause() 
+       | clause = OrderbyClause() 
+       | clause = GroupClause() 
+       | clause = LimitClause()
+       | clause = DistinctClause()
+       | clause = DieClause()
+    )
+    {
+      return clause;
+    }
+}
+
+Clause ForClause()throws ParseException :
+{
+	ForClause fc = new ForClause();
+	VariableExpr varExp;
+	VariableExpr varPos = null;
+	Expression inExp;
+	extendCurrentScope();
+}
+{
+    "for" varExp = Variable()
+    {
+     	getCurrentScope().addNewVarSymbolToScope(varExp.getVar());
+	}
+	("at" varPos = Variable()
+	  {
+	     getCurrentScope().addNewVarSymbolToScope(varPos.getVar());
+	  } 
+	 )? 
+      "in" ( inExp = Expression() )
+    {
+      fc.setVarExpr(varExp);
+      fc.setInExpr(inExp);
+      if (varPos != null) {
+        fc.setPosExpr(varPos);
+      }
+      return fc;
+    }
+}
+
+Clause LetClause() throws ParseException:
+{
+	LetClause lc = new LetClause();
+	VariableExpr varExp;
+	Expression beExp;
+	extendCurrentScope();
+}
+{
+    "let" varExp = Variable()
+    {
+      getCurrentScope().addNewVarSymbolToScope(varExp.getVar());
+	}
+     ":=" beExp = Expression()
+    {
+      lc.setVarExpr(varExp);
+      lc.setBeExpr(beExp);
+      return lc;
+    }
+}
+
+Clause WhereClause()throws ParseException :
+{
+  WhereClause wc = new WhereClause();
+  Expression whereExpr;
+}
+{
+    "where" whereExpr = Expression()
+    {
+      wc.setWhereExpr(whereExpr);
+      return wc;
+    }
+}
+
+Clause OrderbyClause()throws ParseException :
+{
+  OrderbyClause oc = new OrderbyClause();
+  Expression orderbyExpr;
+  List<Expression> orderbyList = new ArrayList<Expression>();
+  List<OrderbyClause.OrderModifier> modifierList = new ArrayList<OrderbyClause.OrderModifier >();
+  int numOfOrderby = 0;
+}
+{
+  (
+    "order" 
+      {
+         String hint = getHint(token);
+         if (hint != null && hint.startsWith(INMEMORY_HINT)) {
+           String splits[] = hint.split(" +"); 
+           int numFrames = Integer.parseInt(splits[1]);
+           int numTuples = Integer.parseInt(splits[2]);
+           oc.setNumFrames(numFrames);
+           oc.setNumTuples(numTuples);   
+         } 
+      }     
+    "by" orderbyExpr = Expression()
+    {
+      orderbyList.add(orderbyExpr);
+      OrderbyClause.OrderModifier modif = OrderbyClause.OrderModifier.ASC;       
+    }
+    ( ("asc" { modif = OrderbyClause.OrderModifier.ASC; })
+    | ("desc" { modif = OrderbyClause.OrderModifier.DESC; }))?
+    {
+      modifierList.add(modif);
+    }
+    
+    ("," orderbyExpr = Expression()
+    {
+      orderbyList.add(orderbyExpr);
+      modif = OrderbyClause.OrderModifier.ASC;
+    }
+    ( ("asc" { modif = OrderbyClause.OrderModifier.ASC; })
+    | ("desc" { modif = OrderbyClause.OrderModifier.DESC; }))?
+    {
+      modifierList.add(modif);
+    }    
+    )*
+)
+    {
+      oc.setModifierList(modifierList);
+      oc.setOrderbyList(orderbyList);
+      return oc;
+    }
+}
+Clause GroupClause()throws ParseException :
+{
+  	GroupbyClause gbc = new GroupbyClause();
+  	// GbyVariableExpressionPair pair = new GbyVariableExpressionPair();
+ 	List<GbyVariableExpressionPair> vePairList = new ArrayList<GbyVariableExpressionPair>();
+    List<GbyVariableExpressionPair> decorPairList = new ArrayList<GbyVariableExpressionPair>();
+	List<VariableExpr> withVarList= new ArrayList<VariableExpr>();
+	VariableExpr var = null;
+	VariableExpr withVar = null;
+	Expression expr = null;
+	VariableExpr decorVar = null;
+	Expression decorExpr = null;
+}
+{
+  	{
+  	  Scope newScope = extendCurrentScopeNoPush(true); 
+  	  // extendCurrentScope(true);
+  	}
+    "group"
+      {
+         String hint = getHint(token);
+         if (hint != null && hint.equals(HASH_GROUP_BY_HINT)) {
+           gbc.setHashGroupByHint(true);   
+         } 
+      } 
+    "by" (LOOKAHEAD(2)  var = Variable()
+    {
+      newScope.addNewVarSymbolToScope(var.getVar());
+    } ":=")?
+    expr = Expression() 
+       {
+         GbyVariableExpressionPair pair1 = new GbyVariableExpressionPair(var, expr);    
+         vePairList.add(pair1);
+       }
+    ("," ( LOOKAHEAD(2) var = Variable()
+    {
+      newScope.addNewVarSymbolToScope(var.getVar());
+    } ":=")?
+    	expr = Expression()  
+    	 {
+           GbyVariableExpressionPair pair2 = new GbyVariableExpressionPair(var, expr);    
+           vePairList.add(pair2);
+         }
+    	)*
+    ("decor" decorVar = Variable() ":=" decorExpr = Expression()
+       {    
+         newScope.addNewVarSymbolToScope(decorVar.getVar()); 
+         GbyVariableExpressionPair pair3 = new GbyVariableExpressionPair(decorVar, decorExpr);
+         decorPairList.add(pair3);
+       }
+      ("," "decor" decorVar = Variable() ":=" decorExpr = Expression()
+           { 
+             newScope.addNewVarSymbolToScope(decorVar.getVar()); 
+             GbyVariableExpressionPair pair4 = new GbyVariableExpressionPair(decorVar, decorExpr);
+             decorPairList.add(pair4);              
+           }
+       )*            
+    )?	
+    "with" withVar = VariableRef()
+    {
+      if(withVar.getIsNewVar()==true)
+      	throw new ParseException("can't find variable " + withVar.getVar());
+      withVarList.add(withVar);
+      newScope.addNewVarSymbolToScope(withVar.getVar());
+    }
+    ("," withVar = VariableRef()
+    {
+      if(withVar.getIsNewVar()==true)
+      	throw new ParseException("can't find variable " + withVar.getVar());
+      withVarList.add(withVar);
+      newScope.addNewVarSymbolToScope(withVar.getVar());
+    })*
+    {
+      gbc.setGbyPairList(vePairList);
+      gbc.setDecorPairList(decorPairList);
+      gbc.setWithVarList(withVarList);
+      replaceCurrentScope(newScope);
+      return gbc;
+    }
+}
+
+
+LimitClause LimitClause() throws ParseException:
+{
+	LimitClause lc = new LimitClause();
+	Expression expr;
+	pushForbiddenScope(getCurrentScope());
+}
+{
+    "limit" expr = Expression()    { lc.setLimitExpr(expr);    }
+    ("offset" expr = Expression() { lc.setOffset(expr);    })?
+
+  {
+    popForbiddenScope();   
+    return lc;
+  }
+}
+
+DistinctClause DistinctClause() throws ParseException:
+{
+  List<Expression> exprs = new ArrayList<Expression>();
+  Expression expr;
+}
+{
+  "distinct" "by" expr = Expression() 
+  {
+    exprs.add(expr);
+  }
+  ("," expr = Expression() 
+  	{
+  		exprs.add(expr); 
+  	} 
+  )*
+  {
+  	return new DistinctClause(exprs);
+  }
+}
+
+DieClause DieClause() throws ParseException:
+{
+	DieClause lc = new DieClause();
+	Expression expr;
+	pushForbiddenScope(getCurrentScope());
+}
+{
+  "die" "after" expr = Expression()    { lc.setDieExpr(expr);    }
+  {
+    popForbiddenScope();   
+    return lc;
+  }
+}
+
+
+QuantifiedExpression QuantifiedExpression()throws ParseException:
+{
+  QuantifiedExpression qc = new QuantifiedExpression();
+  List<QuantifiedPair> quantifiedList = new ArrayList<QuantifiedPair>();
+  Expression satisfiesExpr;
+  VariableExpr var;
+  Expression inExpr;
+  QuantifiedPair pair;
+}
+{
+  {
+    createNewScope();
+  }
+	
+   (      ("some"  {  qc.setQuantifier(QuantifiedExpression.Quantifier.SOME);	})
+		| ("every" {  qc.setQuantifier(QuantifiedExpression.Quantifier.EVERY);	}))
+	var = Variable() "in" inExpr = Expression() 
+	{
+	  pair = new QuantifiedPair(var, inExpr);
+      getCurrentScope().addNewVarSymbolToScope(var.getVar());
+      quantifiedList.add(pair);
+	}
+	(
+	"," var = Variable() "in" inExpr = Expression() 
+	{ 
+      pair = new QuantifiedPair(var, inExpr);
+      getCurrentScope().addNewVarSymbolToScope(var.getVar());
+      quantifiedList.add(pair);	
+	}
+	)*
+	 "satisfies" satisfiesExpr = Expression()
+	 {
+	   qc.setSatisfiesExpr(satisfiesExpr);
+	   qc.setQuantifiedList(quantifiedList);
+	   removeCurrentScope();
+	   return qc;
+	 }
+}
+
+TOKEN_MGR_DECLS:
+{
+        public int commentDepth = 0;
+}
+
+<DEFAULT>
+TOKEN :
+{
+   <CARET : "^"  >
+}
+
+<DEFAULT>
+TOKEN :
+{
+   <DATASET : "dataset"  >
+}
+
+<DEFAULT>
+TOKEN :
+{
+   <LEFTPAREN : "("  >
+}
+
+<DEFAULT>
+TOKEN :
+{
+   <RIGHTPAREN : ")"  >
+}
+
+
+<DEFAULT>
+TOKEN :
+{
+	<INTEGER_LITERAL : (<DIGIT>)+ >
+}
+
+
+<DEFAULT>
+TOKEN :
+{
+	<NULL : "null">
+}
+
+<DEFAULT>
+TOKEN :
+{
+	<TRUE : "true">
+}
+
+<DEFAULT>
+TOKEN :
+{
+	<FALSE : "false">
+}
+
+<DEFAULT>
+TOKEN :
+{
+	<#DIGIT : ["0" - "9"]>
+}
+
+
+TOKEN:
+{
+  < DOUBLE_LITERAL: <INTEGER>
+        | <INTEGER> ( "." <INTEGER> )?
+        | "." <INTEGER>
+  >
+  |
+  < FLOAT_LITERAL: <INTEGER> ( "f" | "F" )
+        | <INTEGER> ( "." <INTEGER> ( "f" | "F" ) )?
+        | "." <INTEGER> ( "f" | "F" )
+  >
+  |
+  <INTEGER : (<DIGIT>)+ >
+}
+
+<DEFAULT>
+TOKEN :
+{
+	<#LETTER : ["A" - "Z", "a" - "z"]>
+}
+
+<DEFAULT>
+TOKEN :
+{
+	<SPECIALCHARS : ["$", "_", "-"]  >
+}
+
+<DEFAULT>
+TOKEN :
+{
+	<STRING_LITERAL : ("\"" (<EscapeQuot> | ~["\""])* "\"") | ("\'"(<EscapeApos> | ~["\'"])* "\'")>
+	|
+	< #EscapeQuot: "\\\"" >
+	|
+    < #EscapeApos: "\\\'" >
+}
+
+<DEFAULT>
+TOKEN :
+{
+	<IDENTIFIER : (<LETTER>)+ (<LETTER> | <DIGIT> | <SPECIALCHARS>)*>
+}
+
+<DEFAULT>
+TOKEN :
+{
+	<VARIABLE : "$" <IDENTIFIER> >
+}
+
+SKIP:
+{
+    " "
+|   "\t"
+|   "\r"
+|   "\n"
+}
+
+SKIP:
+{
+	<"//" (~["\n"])* "\n">
+}
+
+SKIP:
+{
+	<"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?> 
+}
+
+
+SKIP:
+{
+        <"/*"> {commentDepth=1;}: INSIDE_COMMENT
+}
+
+<INSIDE_COMMENT>
+SPECIAL_TOKEN:
+{
+       <"+"(" ")*(~["*"])*>
+}
+
+<INSIDE_COMMENT>
+SKIP:
+{
+        <"/*"> {commentDepth++;}
+}
+
+<INSIDE_COMMENT>
+SKIP:
+{
+        <"*/"> {commentDepth--; if (commentDepth == 0) SwitchTo(DEFAULT);}
+|       <~[]>
+}