merge asterix_stabilization r281:334

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_opentype@335 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
index fc0a2e8..b79be86 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceStaticTypeCastRule.java
@@ -10,13 +10,16 @@
 import edu.uci.ics.asterix.om.base.ANull;
 import edu.uci.ics.asterix.om.base.AString;
 import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
 import edu.uci.ics.asterix.om.typecomputer.base.TypeComputerUtilities;
 import edu.uci.ics.asterix.om.types.ARecordType;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.AbstractCollectionType;
 import edu.uci.ics.asterix.om.types.BuiltinType;
 import edu.uci.ics.asterix.om.types.IAType;
 import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.accessors.base.DefaultOpenFieldType;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
@@ -84,13 +87,13 @@
 
         AbstractLogicalOperator currentOperator = oldAssignOperator;
         List<LogicalVariable> producedVariables = new ArrayList<LogicalVariable>();
-        boolean changed = false;
 
         /**
          * find the assign operator for the "input record" to the insert_delete
          * operator
          */
         do {
+            context.addToDontApplySet(this, currentOperator);
             if (currentOperator.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
                 producedVariables.clear();
                 VariableUtilities.getProducedVariables(currentOperator, producedVariables);
@@ -105,21 +108,10 @@
                     ILogicalExpression expr = expressionPointers.get(position).getValue();
                     if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
                         ScalarFunctionCallExpression funcExpr = (ScalarFunctionCallExpression) expr;
-                        changed = TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredRecordType,
-                                inputRecordType);
-                        changed &= !requiredRecordType.equals(inputRecordType);
-                        if (changed) {
-                            staticTypeCast(funcExpr, requiredRecordType, inputRecordType);
-                            List<Mutable<ILogicalExpression>> args = funcExpr.getArguments();
-                            int openPartStart = requiredRecordType.getFieldTypes().length * 2;
-                            for (int j = openPartStart; j < args.size(); j++) {
-                                ILogicalExpression arg = args.get(j).getValue();
-                                if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
-                                    AbstractFunctionCallExpression argFunc = (AbstractFunctionCallExpression) arg;
-                                    TypeComputerUtilities.setOpenType(argFunc, true);
-                                }
-                            }
-                        }
+                        if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
+                            return false;
+                        IVariableTypeEnvironment assignEnv = oldAssignOperator.computeOutputTypeEnvironment(context);
+                        rewriteFuncExpr(funcExpr, requiredRecordType, inputRecordType, assignEnv);
                     }
                     context.computeAndSetTypeEnvironmentForOperator(originalAssign);
                 }
@@ -129,10 +121,58 @@
             else
                 break;
         } while (currentOperator != null);
-        return changed;
+        return true;
     }
 
-    private void staticTypeCast(ScalarFunctionCallExpression func, ARecordType reqType, ARecordType inputType) {
+    private void rewriteFuncExpr(ScalarFunctionCallExpression funcExpr, IAType reqType, IAType inputType,
+            IVariableTypeEnvironment env) throws AlgebricksException {
+        if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR) {
+            rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType, env);
+        }
+        if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR) {
+            rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType, env);
+        } else if (reqType.getTypeTag().equals(ATypeTag.RECORD)) {
+            rewriteRecordFuncExpr(funcExpr, (ARecordType) reqType, (ARecordType) inputType, env);
+        }
+    }
+
+    private void rewriteRecordFuncExpr(ScalarFunctionCallExpression funcExpr, ARecordType requiredRecordType,
+            ARecordType inputRecordType, IVariableTypeEnvironment env) throws AlgebricksException {
+        if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
+            return;
+        TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredRecordType, inputRecordType);
+        staticRecordTypeCast(funcExpr, requiredRecordType, inputRecordType, env);
+    }
+
+    private void rewriteListFuncExpr(ScalarFunctionCallExpression funcExpr, AbstractCollectionType requiredListType,
+            AbstractCollectionType inputListType, IVariableTypeEnvironment env) throws AlgebricksException {
+        if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
+            return;
+
+        TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredListType, inputListType);
+        List<Mutable<ILogicalExpression>> args = funcExpr.getArguments();
+
+        IAType itemType = requiredListType.getItemType();
+        if (itemType == null || itemType.getTypeTag().equals(ATypeTag.ANY))
+            return;
+        IAType inputItemType = inputListType.getItemType();
+        for (int j = 0; j < args.size(); j++) {
+            ILogicalExpression arg = args.get(j).getValue();
+            if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+                ScalarFunctionCallExpression argFunc = (ScalarFunctionCallExpression) arg;
+                IAType currentItemType = (IAType) env.getType(argFunc);
+                if (inputItemType == null || inputItemType == BuiltinType.ANY) {
+                    currentItemType = (IAType) env.getType(argFunc);
+                    rewriteFuncExpr(argFunc, itemType, currentItemType, env);
+                } else {
+                    rewriteFuncExpr(argFunc, itemType, inputItemType, env);
+                }
+            }
+        }
+    }
+
+    private void staticRecordTypeCast(ScalarFunctionCallExpression func, ARecordType reqType, ARecordType inputType,
+            IVariableTypeEnvironment env) throws AlgebricksException {
         IAType[] reqFieldTypes = reqType.getFieldTypes();
         String[] reqFieldNames = reqType.getFieldNames();
         IAType[] inputFieldTypes = inputType.getFieldTypes();
@@ -154,6 +194,11 @@
         for (int i = 0; i < inputFieldNames.length; i++) {
             String fieldName = inputFieldNames[i];
             IAType fieldType = inputFieldTypes[i];
+
+            if (2 * i + 1 > func.getArguments().size())
+                break;
+
+            ILogicalExpression arg = func.getArguments().get(2 * i + 1).getValue();
             matched = false;
             for (int j = 0; j < reqFieldNames.length; j++) {
                 String reqFieldName = reqFieldNames[j];
@@ -163,6 +208,11 @@
                         fieldPermutation[j] = i;
                         openFields[i] = false;
                         matched = true;
+
+                        if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+                            ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
+                            rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
+                        }
                         break;
                     }
 
@@ -171,13 +221,30 @@
                             && NonTaggedFormatUtil.isOptionalField((AUnionType) reqFieldType)) {
                         IAType itemType = ((AUnionType) reqFieldType).getUnionList().get(
                                 NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
+                        reqFieldType = itemType;
                         if (fieldType.equals(BuiltinType.ANULL) || fieldType.equals(itemType)) {
                             fieldPermutation[j] = i;
                             openFields[i] = false;
                             matched = true;
+
+                            // rewrite record expr
+                            if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+                                ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
+                                rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
+                            }
                             break;
                         }
                     }
+
+                    // match the record field: need cast
+                    if (arg.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+                        ScalarFunctionCallExpression scalarFunc = (ScalarFunctionCallExpression) arg;
+                        rewriteFuncExpr(scalarFunc, reqFieldType, fieldType, env);
+                        fieldPermutation[j] = i;
+                        openFields[i] = false;
+                        matched = true;
+                        break;
+                    }
                 }
             }
             if (matched)
@@ -196,7 +263,7 @@
                 String fieldName = inputFieldNames[j];
                 IAType fieldType = inputFieldTypes[j];
                 if (fieldName.equals(reqFieldName)) {
-                    if (fieldType.equals(reqFieldType)) {
+                    if (!openFields[j]) {
                         matched = true;
                         break;
                     }
@@ -250,7 +317,26 @@
         for (int i = 0; i < openFields.length; i++) {
             if (openFields[i]) {
                 arguments.add(argumentsClone.get(2 * i));
-                arguments.add(argumentsClone.get(2 * i + 1));
+                Mutable<ILogicalExpression> fExprRef = argumentsClone.get(2 * i + 1);
+                ILogicalExpression argExpr = fExprRef.getValue();
+
+                if (argExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+                    IAType reqFieldType = inputFieldTypes[i];
+                    if (inputFieldTypes[i].getTypeTag() == ATypeTag.RECORD) {
+                        reqFieldType = DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
+                    }
+                    if (inputFieldTypes[i].getTypeTag() == ATypeTag.ORDEREDLIST) {
+                        reqFieldType = DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
+                    }
+                    if (inputFieldTypes[i].getTypeTag() == ATypeTag.UNORDEREDLIST) {
+                        reqFieldType = DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
+                    }
+                    if (TypeComputerUtilities.getRequiredType((AbstractFunctionCallExpression) argExpr) == null) {
+                        ScalarFunctionCallExpression argFunc = (ScalarFunctionCallExpression) argExpr;
+                        rewriteFuncExpr(argFunc, reqFieldType, inputFieldTypes[i], env);
+                    }
+                }
+                arguments.add(fExprRef);
             }
         }
     }
diff --git a/asterix-app/src/test/resources/logging.properties b/asterix-app/src/test/resources/logging.properties
index deb88307..4cf5545 100644
--- a/asterix-app/src/test/resources/logging.properties
+++ b/asterix-app/src/test/resources/logging.properties
@@ -61,5 +61,5 @@
 # messages:
 
 #edu.uci.ics.asterix.level = FINE
-#edu.uci.ics.algebricks.level = FINE
-#edu.uci.ics.hyracks.level = INFO
+edu.uci.ics.algebricks.level = FINE
+edu.uci.ics.hyracks.level = INFO
diff --git a/asterix-app/src/test/resources/runtimets/ignore.txt b/asterix-app/src/test/resources/runtimets/ignore.txt
index 2b456ca..962d26b 100644
--- a/asterix-app/src/test/resources/runtimets/ignore.txt
+++ b/asterix-app/src/test/resources/runtimets/ignore.txt
@@ -14,5 +14,12 @@
 fuzzyjoin/events-users-aqlplus_1.aql
 fuzzyjoin
 failure/q1_pricing_summary_report_failure.aql
-open-closed
 dml/load-from-hdfs.aql
+open-closed/open-closed-15
+open-closed/open-closed-16
+open-closed/open-closed-17
+open-closed/open-closed-18
+open-closed/open-closed-19
+open-closed/open-closed-20
+open-closed/open-closed-21
+open-closed/open-closed-22
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o-recursive.aql b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o-recursive.aql
new file mode 100644
index 0000000..6c8264f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o-recursive.aql
@@ -0,0 +1,62 @@
+/* 
+ * Test case Name  : opentype-o2c-recursive.aql
+ * Description     : verify the static casting of nest record constants 
+ * Expected Result : Success
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+
+create type AddressType as open{
+  street: string,
+  city: string
+}
+create type Dept as open{
+	name: string,
+	id: int32
+}
+
+create type testtype as closed {
+  name: string,
+  id: string,
+  address: AddressType?,
+  department: {{Dept}}?
+}
+
+create type testtype2 as open {
+  name: string,
+  id: string
+}
+
+create dataset testds(testtype) partitioned by key id;
+
+create dataset testds2(testtype2) partitioned by key id;
+
+insert into dataset testds (
+{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH",  "city": "Irvine", "zip": 92697}, "department": {{ {"name":"CS", "id":299, "review":5}, {"name":"EE", "id":399} }} }
+);
+
+insert into dataset testds (
+{ "id": "002", "name": "Person Two" }
+);
+
+insert into dataset testds (
+{ "id": "003", "name": "Person Three", "address": {"street": "2019 DBH",  "city": "Irvine"} }
+);
+
+insert into dataset testds (
+{ "id": "004", "name": "Person Four", "address": {"street": "1019 DBH",  "city": "irvine", "property": {"zip": 92697, "review": "positive" }  } }
+);
+
+insert into dataset testds2 (
+ for $d in dataset("testds") 
+	return $d
+);
+
+write output to nc1:"rttest/dml_opentype-c2o-recursive.adm";
+
+for $d in dataset("testds2") 
+order by $d.id
+return $d
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o.aql b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o.aql
index e29ccdc..a63e2df 100644
--- a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-c2o.aql
@@ -12,7 +12,7 @@
 create type testtype as closed {
   id: string,
   name: string,
-  hobby: string?
+  hobby: {{string}}?
 }
 
 /*
@@ -28,19 +28,19 @@
 create dataset testds2(testtype2) partitioned by key id;
  
 insert into dataset testds (
-{ "hobby": "music", "id": "001", "name": "Person Three"}
+{ "hobby": {{"music", "coding"}}, "id": "001", "name": "Person Three"}
 );
 
 insert into dataset testds (
-{ "name": "Person One", "id": "002", "hobby": "sports"}
+{ "name": "Person One", "id": "002", "hobby": {{"sports"}} }
 );
 
 insert into dataset testds (
-{ "id": "003", "hobby": "movie", "name": "Person Two"}
+{ "id": "003", "hobby": {{"movie", "sports"}}, "name": "Person Two"}
 );
 
 insert into dataset testds (
-{ "id": "004", "name": "Person Four", "hobby": "swimming"}
+{ "id": "004", "name": "Person Four", "hobby": {{"swimming"}} }
 );
  
 insert into dataset testds (
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c-recursive.aql b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c-recursive.aql
new file mode 100644
index 0000000..2070e20
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c-recursive.aql
@@ -0,0 +1,63 @@
+/* 
+ * Test case Name  : opentype-o2c-recursive.aql
+ * Description     : verify the static casting of nest record constants 
+ * Expected Result : Success
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+
+create type AddressType as open{
+  street: string,
+  city: string
+}
+
+create type Dept as closed{
+	name: string,
+	id: int32
+}
+
+create type testtype as open {
+  name: string,
+  id: string
+}
+
+create type testtype2 as closed {
+  name: string,
+  id: string,
+  address: AddressType?,
+  department: {{Dept}}?
+}
+
+create dataset testds(testtype) partitioned by key id;
+
+create dataset testds2(testtype2) partitioned by key id;
+
+insert into dataset testds (
+{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH",  "city": "Irvine", "zip": 92697}, "department": {{ {"name":"CS", "id":299}, {"name":"EE", "id":399} }} }
+);
+
+insert into dataset testds (
+{ "id": "002", "name": "Person Two" }
+);
+
+insert into dataset testds (
+{ "id": "003", "name": "Person Three", "address": {"street": "2019 DBH",  "city": "Irvine"} }
+);
+
+insert into dataset testds (
+{ "id": "004", "name": "Person Four", "address": {"street": "1019 DBH",  "city": "irvine", "property": {"zip": 92697, "review": "positive" }  } }
+);
+
+insert into dataset testds2 (
+ for $d in dataset("testds") 
+	return $d
+);
+
+write output to nc1:"rttest/dml_opentype-o2c-recursive.adm";
+
+for $d in dataset("testds2") 
+order by $d.id
+return $d
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c.aql b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c.aql
index a6ed9cc..015aa7b 100644
--- a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-o2c.aql
@@ -16,7 +16,7 @@
 }
 
 create type testtype2 as closed {
-  hobby: string?,
+  hobby: {{string}}?,
   id: string,
   name: string
 }
@@ -26,19 +26,19 @@
 create dataset testds2(testtype2) partitioned by key id; 
  
 insert into dataset testds (
-{ "id": "001",  "hobby": "music", "name": "Person Three"}
+{ "id": "001",  "hobby": {{"music"}}, "name": "Person Three"}
 );
 
 insert into dataset testds (
-{ "id": "002", "name": "Person Three", "hobby": "football"}
+{ "id": "002", "name": "Person Three", "hobby": {{"football"}}}
 );
 
 insert into dataset testds (
-{ "id": "003", "name": "Person Three", "hobby": "movie"}
+{ "id": "003", "name": "Person Three", "hobby": {{"movie", "coding", "debugging"}}}
 );
 
 insert into dataset testds (
-{ "name": "Person Three", "hobby": "swimming", "id": "004"}
+{ "name": "Person Three", "hobby": {{"swimming", "music"}}, "id": "004"}
 );
 
 insert into dataset testds (
diff --git a/asterix-app/src/test/resources/runtimets/queries/nestrecords/nestrecord.aql b/asterix-app/src/test/resources/runtimets/queries/nestrecords/nestrecord.aql
new file mode 100644
index 0000000..c0b5e06
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/nestrecords/nestrecord.aql
@@ -0,0 +1,45 @@
+/* 
+ * Test case Name  : nestrecord.aql
+ * Description     : verify the static casting of nest record constants 
+ * Expected Result : Success
+ */
+
+drop dataverse testdv2 if exists;
+create dataverse testdv2;
+use dataverse testdv2;
+
+
+create type AddressType as open{
+  street: string,
+  city: string
+}
+
+create type testtype as open {
+  name: string,
+  id: string,
+  address: AddressType?
+}
+
+create dataset testds(testtype) partitioned by key id;
+
+insert into dataset testds (
+{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH",  "city": "Irvine", "zip": 92697} }
+);
+
+insert into dataset testds (
+{ "id": "002", "name": "Person Two" }
+);
+
+insert into dataset testds (
+{ "id": "003", "name": "Person Three", "address": {"street": "2019 DBH",  "city": "Irvine"} }
+);
+
+insert into dataset testds (
+{ "id": "004", "name": "Person Four", "home": {"street": "2019 DBH",  "city": {"name": "Irvine", "zip": 92697} } }
+);
+
+write output to nc1:"rttest/nestrecords_nestrecord.adm";
+
+for $d in dataset("testds") 
+order by $d.id
+return $d
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list-ordered01.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list-ordered01.aql
new file mode 100644
index 0000000..27935e0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list-ordered01.aql
@@ -0,0 +1,39 @@
+/*
+ * Test case Name : heterog-list01.aql
+ * Description    : To test insertion of an array of objects into internal dataset. 
+ *                : Heterogenous list construction.
+ * Success        : Yes
+ * Date           : 14th April 2012
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type BatterType as {
+id:int32,
+descrpt:string
+}
+
+create type TestType as closed {
+id:int32,
+description:string,
+name:string,
+batters:[[BatterType]]
+}
+
+create dataset T1(TestType) partitioned by key id;
+
+insert into dataset T1({
+"id":1234,
+"description":"donut",
+"name":"Cake",
+"batters":[[ {"id":345,"descrpt":"Regular"},{"id":445,"descrpt":"Chocolate"} ]] }
+);
+
+write output to nc1:"rttest/open-closed_heterog-list-ordered01.adm";
+
+for $d in dataset("T1") 
+order by $d.id
+return $d
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list01.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list01.aql
index d1edc3d..7ba1641 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list01.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/heterog-list01.aql
@@ -19,7 +19,7 @@
 id:int32,
 description:string,
 name:string,
-batters:[BatterType]
+batters:{{BatterType}}
 }
 
 create dataset T1(TestType) partitioned by key id;
@@ -28,11 +28,12 @@
 "id":1234,
 "description":"donut",
 "name":"Cake",
-"batters":[{"id":345,"descprt":"Regular"},{"id":445,"descprt":"Chocolate"}] }
+"batters":{{ {"id":345,"descrpt":"Regular"},{"id":445,"descrpt":"Chocolate"} }} }
 );
 
-write output to nc1:"rttest/open-closed_heteror-list01.adm";
+write output to nc1:"rttest/open-closed_heterog-list01.adm";
 
 for $d in dataset("T1") 
+order by $d.id
 return $d
 
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-01.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-01.aql
index 6373569..0d26b5d 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-01.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-01.aql
@@ -23,4 +23,6 @@
 );
 
 write output to nc1:"rttest/open-closed_open-closed-01.adm";
-for $l in dataset("testds") return $l
+for $l in dataset("testds") 
+order by $l.id
+return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-02.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-02.aql
deleted file mode 100644
index e15577b..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-02.aql
+++ /dev/null
@@ -1,25 +0,0 @@
-/* 
- * Test case Name  : open-closed-02.aql
- * Description     : This test is intended to test insertion of additional data into a dataset of closed type 
- * Expected Result : This test should fail because closed type internal datasets can not ingest additional data.
- * 
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-// name field here is optional.
-create type testType as closed {
-id : int32,
-name : string?
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id": 123});
-
-write output to nc1:"rttest/open-closed_open-closed-02.adm";
-for $l in dataset("testds") return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-03.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-03.aql
deleted file mode 100644
index f028c89..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-03.aql
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 
- * Test case Name  : open-closed-03.aql
- * Description     : This test is intended to test insertion of additional data into a closed type 
- * Expected Result : Failure - This should NOT be allowed!
- * Issue number    : Issue 66
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as closed {
-id : int32,
-name : string
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id": 123, "name": "John Doe", "hobbies": {{ "scuba", "music" }} }
-);
-
-for $l in dataset("testds") return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-04.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-04.aql
deleted file mode 100644
index 82912bd..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-04.aql
+++ /dev/null
@@ -1,31 +0,0 @@
-/* 
- * Test case Name  : open-closed-04.aql
- * Description     : This test is intended to test type in the Metdata for the dataset. 
- *                 : Verify if the type is open. 
- * Expected Result : Success - This should be allowed!
- * Issue number    : Issue 73
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type TestType as open {
-id : int32,
-name : string
-}
-
-create dataset testds(TestType) partitioned by key id;
-
-/*
- * Connect to the Metadata dataverse and run the following commands.
- */
-
-use dataverse Metadata;
-
-for $l in dataset('Datatype')
-let $x := $l.Derived
-where $l.DatatypeName="TestType"
-return $x.Record
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-05.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-05.aql
deleted file mode 100644
index 2bd18fe..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-05.aql
+++ /dev/null
@@ -1,30 +0,0 @@
-/* 
- * Test case Name  : open-closed-05.aql
- * Description     : Create internal dataset and verify if the type is marked as closed in metadata.
- * Expected Result : Success
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as closed {
-id : int32,
-name : string
-}
-
-create dataset testds(testType) partitioned by key id;
-
-/*
- * Connect to the Metadata dataverse and run the following commands.
- * Verify if the type is closed by querying Metadata.
- */
-
-use dataverse Metadata;
-
-for $l in dataset('Datatype')
-let $x := $l.Derived
-where $l.DatatypeName="TestType"
-return $x.Record
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-06.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-06.aql
deleted file mode 100644
index f6605a6..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-06.aql
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Test case Name : open-closed-06.aql
- * Description    : To test non nullable field types in closed type datasets.
- * Success        : Yes this test should Fail!
- * Date           : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as closed {
-id : int32,
-name : string
-}
-
-create dataset testds(testType) partitioned by key id;
-
-// Missing name field this insert stmt should fail.
-
-insert into dataset testds({"id": 123});
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-07.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-07.aql
deleted file mode 100644
index 155f8bb..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-07.aql
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Test case Name : open-closed-07.aql
- * Description    : To test non nullable field types in datasets of type open.
- * Success        : Yes this test should Fail!
- * Date           : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as open {
-id : int32,
-name : string
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id": 123});
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-08.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-08.aql
deleted file mode 100644
index 24423e8..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-08.aql
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Test case Name : open-closed-08.aql
- * Description    : To test nullable and non nullable field types in datasets of type closed.
- * Success        : Yes this test should succeed!
- * Date           : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as closed {
-id : int32,
-name : string?
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id": 123});
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-09.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-09.aql
deleted file mode 100644
index 63288d7..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-09.aql
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Test case Name : open-closed-09.aql
- * Description    : To test nullable and non nullable field types in datasets of type open.
- *                : Missing value for nullable field and missing value for non-nullable field in insert statement.
- * Success        : This test should Fail!
- * Date           : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as open {
-id : int32,
-name : string?
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({ });
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-10.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-10.aql
deleted file mode 100644
index cad1f12..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-10.aql
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Test case Name : open-closed-10.aql
- * Description    : To test nullable and non nullable field types in datasets of type open.
- *                : Missing value for nullable field in insert statement.
- * Success        : This test should succeed!
- * Date           : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as open {
-id : int32,
-name : string?
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id :" 32 });
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-11.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-11.aql
deleted file mode 100644
index 50d52d2..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-11.aql
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Test case Name : open-closed-11.aql
- * Description    : To test nullable and non nullable field types in datasets of type open.
- *                : No missing value for nullable field in insert statement.
- * Success        : This test should succeed!
- * Date           : 03/26/2012
- */
-
-drop dataverse test if exists;
-
-create dataverse test;
-
-use dataverse test;
-
-create type testType as open {
-id : int32,
-name : string?
-}
-
-create dataset testds(testType) partitioned by key id;
-
-insert into dataset testds({"id :" 32,"name :" "UCI"});
-
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-12.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-12.aql
index 2459fcc..ae21794 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-12.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-12.aql
@@ -43,6 +43,8 @@
 return $d
 );
 
+write output to nc1:"rttest/open-closed_open-closed-12.adm";
 for $d in dataset("testds01")
+order by $d.id
 return $d
 
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-13.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-13.aql
deleted file mode 100644
index 379e282..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-13.aql
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Testcase Name : open-closed-13.aql
- * Description   : Attempt to insert additional data into a dataset which is defined as closed type.
- * Success       : This test should fail! No additional data allowed in datasets of closed type.
- * Date          : March 27 2012
- */
-
-
-create dataverse testdv2;
-use dataverse testdv2;
-
-create type testtype as closed {
-  id: string,
-  name: string
-}
-
-create dataset testds(testtype) partitioned by key id;
-
-insert into dataset testds (
-{ "id": "001", "name": "Person Three", "hobbies": {{"scuba", "music"}}}
-);
-
-for $d in dataset("testds")
-return $d
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-14.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-14.aql
index 03e6e33..6c517ca 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-14.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-14.aql
@@ -48,6 +48,8 @@
 return $d
 );
 
+write output to nc1:"rttest/open-closed_open-closed-14.adm";
 for $d in dataset("testds01")
+order by $d.id
 return $d
 
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-15.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-15.aql
index 80cfa30..2ac2567 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-15.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-15.aql
@@ -46,6 +46,7 @@
 }
 );
 
+write output to nc1:"rttest/open-closed_open-closed-15.adm";
 for $l in dataset('tdtst')
 return $l
 
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-16.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-16.aql
index c463cb0..5e1a591 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-16.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-16.aql
@@ -46,6 +46,7 @@
 }
 );
 
+write output to nc1:"rttest/open-closed_open-closed-16.adm";
 for $l in dataset('tdtst')
 return $l
 
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-17.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-17.aql
index f1fe349..a590cf1 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-17.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-17.aql
@@ -43,5 +43,6 @@
 }
 );
 
+write output to nc1:"rttest/open-closed_open-closed-17.adm";
 for $l in dataset('tdtst')
 return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-18.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-18.aql
deleted file mode 100644
index 0da1474..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-18.aql
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Test case name : open-closed-18.aql
- * Description    : Test insertion of additional data into an open type internal dataset.
- * Success        : Yes
- * Date           : 29 April 2012
- */
-
-drop dataverse test if exists;
-create dataverse test;
-use dataverse test;
-
-create type TestType as open {
-id:int32
-}
-
-create dataset testds(TestType) partitioned by key id;
-
-insert into dataset testds( for $i in range(1,10) return { "id":$i,"name":"John Doe" });
-
-for $l in dataset('testds')
-return $l
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-19.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-19.aql
index 3ff2d71..b406663 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-19.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-19.aql
@@ -47,5 +47,6 @@
 
 insert into dataset dtst01({for $l in dataset('employee') return $l});
 
+write output to nc1:"rttest/open-closed_open-closed-19.adm";
 for $l in dataset('dtst01')
 retunr $l 
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-20.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-20.aql
index d7ad173..29b4366 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-20.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-20.aql
@@ -41,5 +41,6 @@
 
 insert into dataset dtst01(for $l in dataset('employee') return $l);
 
+write output to nc1:"rttest/open-closed_open-closed-20.adm";
 for $l in dataset('dtst01')
 return $l 
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-21.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-21.aql
index 71ce585..c52344e 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-21.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-21.aql
@@ -38,5 +38,6 @@
 
 insert into dataset dtst01(for $l in dataset('employee') return $l);
 
+write output to nc1:"rttest/open-closed_open-closed-21.adm";
 for $l in dataset('dtst01')
 return $l 
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-22.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-22.aql
index 6e05f61..cd9ac44 100644
--- a/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-22.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/open-closed-22.aql
@@ -39,5 +39,6 @@
 // missing dept field
 insert into dataset employee({"id":205,"name":"Mike Tyson","age":44,"sex":"M","dob":date("1970-12-22")});
 
+write output to nc1:"rttest/open-closed_open-closed-22.adm";
 for $l in dataset('employee')
 return $l 
diff --git a/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o-recursive.adm b/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o-recursive.adm
new file mode 100644
index 0000000..60a389c
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o-recursive.adm
@@ -0,0 +1,4 @@
+{ "name": "Person One", "id": "001", "address": { "street": "3019 DBH", "city": "Irvine", "zip": 92697 }, "department": {{ { "name": "CS", "id": 299, "review": 5 }, { "name": "EE", "id": 399 } }} }
+{ "name": "Person Two", "id": "002", "address": null, "department": null }
+{ "name": "Person Three", "id": "003", "address": { "street": "2019 DBH", "city": "Irvine" }, "department": null }
+{ "name": "Person Four", "id": "004", "address": { "street": "1019 DBH", "city": "irvine", "property": { "zip": 92697, "review": "positive" } }, "department": null }
diff --git a/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o.adm b/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o.adm
index 5e7a349..6086a08 100644
--- a/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o.adm
+++ b/asterix-app/src/test/resources/runtimets/results/dml/opentype-c2o.adm
@@ -1,5 +1,5 @@
-{ "id": "001", "name": "Person Three", "hobby": "music" }
-{ "id": "002", "name": "Person One", "hobby": "sports" }
-{ "id": "003", "name": "Person Two", "hobby": "movie" }
-{ "id": "004", "name": "Person Four", "hobby": "swimming" }
+{ "id": "001", "name": "Person Three", "hobby": {{ "music", "coding" }} }
+{ "id": "002", "name": "Person One", "hobby": {{ "sports" }} }
+{ "id": "003", "name": "Person Two", "hobby": {{ "movie", "sports" }} }
+{ "id": "004", "name": "Person Four", "hobby": {{ "swimming" }} }
 { "id": "005", "name": "Person Five", "hobby": null }
diff --git a/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c-recursive.adm b/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c-recursive.adm
new file mode 100644
index 0000000..c67c3cb
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c-recursive.adm
@@ -0,0 +1,4 @@
+{ "name": "Person One", "id": "001", "address": { "street": "3019 DBH", "city": "Irvine", "zip": 92697 }, "department": {{ { "name": "CS", "id": 299 }, { "name": "EE", "id": 399 } }} }
+{ "name": "Person Two", "id": "002", "address": null, "department": null }
+{ "name": "Person Three", "id": "003", "address": { "street": "2019 DBH", "city": "Irvine" }, "department": null }
+{ "name": "Person Four", "id": "004", "address": { "street": "1019 DBH", "city": "irvine", "property": { "zip": 92697, "review": "positive" } }, "department": null }
diff --git a/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c.adm b/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c.adm
index d9c778b..92809fd 100644
--- a/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c.adm
+++ b/asterix-app/src/test/resources/runtimets/results/dml/opentype-o2c.adm
@@ -1,5 +1,5 @@
-{ "hobby": "music", "id": "001", "name": "Person Three" }
-{ "hobby": "football", "id": "002", "name": "Person Three" }
-{ "hobby": "movie", "id": "003", "name": "Person Three" }
-{ "hobby": "swimming", "id": "004", "name": "Person Three" }
+{ "hobby": {{ "music" }}, "id": "001", "name": "Person Three" }
+{ "hobby": {{ "football" }}, "id": "002", "name": "Person Three" }
+{ "hobby": {{ "movie", "coding", "debugging" }}, "id": "003", "name": "Person Three" }
+{ "hobby": {{ "swimming", "music" }}, "id": "004", "name": "Person Three" }
 { "hobby": null, "id": "005", "name": "Person Five" }
diff --git a/asterix-app/src/test/resources/runtimets/results/nestrecords/nestrecord.adm b/asterix-app/src/test/resources/runtimets/results/nestrecords/nestrecord.adm
new file mode 100644
index 0000000..2b255b0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/nestrecords/nestrecord.adm
@@ -0,0 +1,4 @@
+{ "name": "Person One", "id": "001", "address": { "street": "3019 DBH", "city": "Irvine", "zip": 92697 } }
+{ "name": "Person Two", "id": "002", "address": null }
+{ "name": "Person Three", "id": "003", "address": { "street": "2019 DBH", "city": "Irvine" } }
+{ "name": "Person Four", "id": "004", "address": null, "home": { "street": "2019 DBH", "city": { "name": "Irvine", "zip": 92697 } } }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list-ordered01.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list-ordered01.adm
new file mode 100644
index 0000000..f6d3242
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list-ordered01.adm
@@ -0,0 +1 @@
+{ "id": 1234, "description": "donut", "name": "Cake", "batters": [ [ { "id": 0, "descrpt": "" }, { "id": 0, "descrpt": "" } ] ] }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list01.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list01.adm
new file mode 100644
index 0000000..30c55c2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/heterog-list01.adm
@@ -0,0 +1 @@
+{ "id": 1234, "description": "donut", "name": "Cake", "batters": {{ { "id": 345, "descrpt": "Regular" }, { "id": 445, "descrpt": "Chocolate" } }} }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-01.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-01.adm
new file mode 100644
index 0000000..c5aac6d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-01.adm
@@ -0,0 +1 @@
+{ "id": 123, "name": "John Doe", "hobbies": {{ "scuba", "music" }} }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-12.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-12.adm
new file mode 100644
index 0000000..7570226
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-12.adm
@@ -0,0 +1,3 @@
+{ "id": "001", "name": "Person One", "hobbies": {{ "scuba", "music" }} }
+{ "id": "002", "name": "Person Two", "hobbies": {{ "fishing", "dance" }} }
+{ "id": "003", "name": "Person Three", "hobbies": {{ "hiking", "surfing" }} }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-14.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-14.adm
new file mode 100644
index 0000000..70b6b95
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/open-closed-14.adm
@@ -0,0 +1,5 @@
+{ "id": "001", "name": null }
+{ "id": "002", "name": "John Doe" }
+{ "id": "003", "name": null }
+{ "id": "004", "name": null }
+{ "id": "005", "name": null }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
index 5494669..7e3dbdb 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
@@ -33,9 +33,9 @@
     private ARecordType recordType;
     private int numberOfSchemaFields = 0;
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings("rawtypes")
     private ISerializerDeserializer serializers[];
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings("rawtypes")
     private ISerializerDeserializer deserializers[];
 
     private ARecordSerializerDeserializer() {
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/base/TypeComputerUtilities.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/base/TypeComputerUtilities.java
index e8786ec..c9ce037 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/base/TypeComputerUtilities.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/base/TypeComputerUtilities.java
@@ -1,28 +1,12 @@
 package edu.uci.ics.asterix.om.typecomputer.base;
 
-import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.IAType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
 
 public class TypeComputerUtilities {
 
-    public static void setOpenType(AbstractFunctionCallExpression expr, boolean openType) {
-        Boolean openField = true;
-        Object[] opaqueParameters = new Object[1];
-        opaqueParameters[0] = openField;
-        expr.setOpaqueParameters(opaqueParameters);
-    }
-
-    public static boolean isOpenType(AbstractFunctionCallExpression expr) {
-        boolean openType = false;
-        Object[] opaqueParameters = expr.getOpaqueParameters();
-        if (opaqueParameters != null) {
-            openType = (Boolean) opaqueParameters[0];
-        }
-        return openType;
-    }
-
-    public static boolean setRequiredAndInputTypes(AbstractFunctionCallExpression expr, ARecordType requiredRecordType,
-            ARecordType inputRecordType) {
+    public static boolean setRequiredAndInputTypes(AbstractFunctionCallExpression expr, IAType requiredRecordType,
+            IAType inputRecordType) {
         boolean changed = false;
         Object opaqueParameter = expr.getOpaqueParameters();
         if (opaqueParameter == null) {
@@ -35,22 +19,21 @@
         return changed;
     }
 
-    public static ARecordType getRequiredType(AbstractFunctionCallExpression expr) {
+    public static IAType getRequiredType(AbstractFunctionCallExpression expr) {
         Object[] type = expr.getOpaqueParameters();
         if (type != null) {
-            ARecordType recordType = (ARecordType) type[0];
+            IAType recordType = (IAType) type[0];
             return recordType;
         } else
             return null;
     }
 
-    public static ARecordType getInputType(AbstractFunctionCallExpression expr) {
+    public static IAType getInputType(AbstractFunctionCallExpression expr) {
         Object[] type = expr.getOpaqueParameters();
         if (type != null) {
-            ARecordType recordType = (ARecordType) type[1];
+            IAType recordType = (IAType) type[1];
             return recordType;
         } else
             return null;
     }
-
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java
index 6a17a46..c482dfa 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/ClosedRecordConstructorResultType.java
@@ -31,10 +31,10 @@
         /**
          * if type has been top-down propagated, use the enforced type
          */
-        ARecordType type = TypeComputerUtilities.getRequiredType(f);
+        ARecordType type = (ARecordType) TypeComputerUtilities.getRequiredType(f);
         if (type != null)
             return type;
-
+        
         int n = f.getArguments().size() / 2;
         String[] fieldNames = new String[n];
         IAType[] fieldTypes = new IAType[n];
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java
index 8b27a82..790ca3f 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OpenRecordConstructorResultType.java
@@ -33,7 +33,7 @@
         /**
          * if type has been top-down propagated, use the enforced type
          */
-        ARecordType type = TypeComputerUtilities.getRequiredType(f);
+        ARecordType type = (ARecordType) TypeComputerUtilities.getRequiredType(f);
         if (type != null)
             return type;
 
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OrderedListConstructorResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OrderedListConstructorResultType.java
index 47f239b..84ac969 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OrderedListConstructorResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/OrderedListConstructorResultType.java
@@ -24,26 +24,28 @@
     public AOrderedListType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
             IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
         AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression;
-        boolean openType = TypeComputerUtilities.isOpenType(f);
-        int n = f.getArguments().size();
-        if (n == 0 || openType) {
-            return new AOrderedListType(BuiltinType.ANY, null);
-        } else {
-            ArrayList<IAType> types = new ArrayList<IAType>();
-            for (int k = 0; k < f.getArguments().size(); k++) {
-                IAType type = (IAType) env.getType(f.getArguments().get(k).getValue());
-                if (type.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) type))
-                    type = ((AUnionType) type).getUnionList()
-                            .get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
-                if (types.indexOf(type) < 0) {
-                    types.add(type);
-                }
-            }
-            if (types.size() == 1) {
-                return new AOrderedListType(types.get(0), null);
-            } else {
-                throw new AlgebricksException("You can not construct a heterogenous list.");
+
+        /**
+         * if type has been top-down propagated, use the enforced type
+         */
+        AOrderedListType reqType = (AOrderedListType) TypeComputerUtilities.getRequiredType(f);
+        if (reqType != null)
+            return reqType;
+
+        ArrayList<IAType> types = new ArrayList<IAType>();
+        for (int k = 0; k < f.getArguments().size(); k++) {
+            IAType type = (IAType) env.getType(f.getArguments().get(k).getValue());
+            if (type.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) type))
+                type = ((AUnionType) type).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
+            if (types.indexOf(type) < 0) {
+                types.add(type);
             }
         }
+        if (types.size() == 1) {
+            return new AOrderedListType(types.get(0), null);
+        } else {
+            return new AOrderedListType(BuiltinType.ANY, null);
+        }
+
     }
 }
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnorderedListConstructorResultType.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnorderedListConstructorResultType.java
index 0e03e6d..a4fd12a 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnorderedListConstructorResultType.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/UnorderedListConstructorResultType.java
@@ -24,26 +24,28 @@
     public AUnorderedListType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
             IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
         AbstractFunctionCallExpression f = (AbstractFunctionCallExpression) expression;
-        boolean openType = TypeComputerUtilities.isOpenType(f);
-        int n = f.getArguments().size();
-        if (n == 0 || openType) {
-            return new AUnorderedListType(BuiltinType.ANY, null);
-        } else {
-            ArrayList<IAType> types = new ArrayList<IAType>();
-            for (int k = 0; k < f.getArguments().size(); k++) {
-                IAType type = (IAType) env.getType(f.getArguments().get(k).getValue());
-                if (type.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) type))
-                    type = ((AUnionType) type).getUnionList()
-                            .get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
-                if (types.indexOf(type) < 0) {
-                    types.add(type);
-                }
-            }
-            if (types.size() == 1) {
-                return new AUnorderedListType(types.get(0), null);
-            } else {
-                throw new AlgebricksException("You can not construct a heterogenous list.");
+
+        /**
+         * if type has been top-down propagated, use the enforced type
+         */
+        AUnorderedListType reqType = (AUnorderedListType) TypeComputerUtilities.getRequiredType(f);
+        if (reqType != null)
+            return reqType;
+
+        ArrayList<IAType> types = new ArrayList<IAType>();
+        for (int k = 0; k < f.getArguments().size(); k++) {
+            IAType type = (IAType) env.getType(f.getArguments().get(k).getValue());
+            if (type.getTypeTag() == ATypeTag.UNION && NonTaggedFormatUtil.isOptionalField((AUnionType) type))
+                type = ((AUnionType) type).getUnionList().get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
+            if (types.indexOf(type) < 0) {
+                types.add(type);
             }
         }
+        if (types.size() == 1) {
+            return new AUnorderedListType(types.get(0), null);
+        } else {
+            return new AUnorderedListType(BuiltinType.ANY, null);
+        }
+
     }
 }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java
new file mode 100644
index 0000000..83c3791
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java
@@ -0,0 +1,62 @@
+/*
+ * 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.runtime.accessors;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
+
+public class AFlatValueAccessor extends AbstractBinaryAccessor {
+
+    public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
+        public AFlatValueAccessor createElement(IAType type) {
+            return new AFlatValueAccessor();
+        }
+    };
+
+    private AFlatValueAccessor() {
+
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof IValueReference))
+            return false;
+        IValueReference ivf = (IValueReference) o;
+        byte[] odata = ivf.getBytes();
+        int ostart = ivf.getStartIndex();
+        int olen = ivf.getLength();
+
+        byte[] data = getBytes();
+        int start = getStartIndex();
+        int len = getLength();
+        if ( len!= olen)
+            return false;
+        for (int i = 0; i < len; i++) {
+            if (data[start + i] != odata[ostart + i])
+                return false;
+        }
+        return true;
+    }
+
+    @Override
+    public <R, T> R accept(IBinaryAccessorVisitor<R, T> vistor, T tag) throws AsterixException {
+        return vistor.visit(this, tag);
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java
new file mode 100644
index 0000000..e4cf40d
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java
@@ -0,0 +1,156 @@
+/*
+ * 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.runtime.accessors;
+
+import java.io.DataOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AbstractCollectionType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
+import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
+
+public class AListAccessor extends AbstractBinaryAccessor {
+
+    public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
+        public IBinaryAccessor createElement(IAType type) {
+            return new AListAccessor((AbstractCollectionType) type);
+        }
+    };
+
+    private IAType itemType;
+    private ATypeTag itemTag;
+    private boolean typedItemList = false;
+
+    private List<IBinaryAccessor> items = new ArrayList<IBinaryAccessor>();
+    private List<IBinaryAccessor> itemTags = new ArrayList<IBinaryAccessor>();
+    private AccessorAllocator allocator = new AccessorAllocator();
+
+    private byte[] dataBuffer = new byte[32768];
+    private ResettableByteArrayOutputStream dataBos = new ResettableByteArrayOutputStream();
+    private DataOutputStream dataDos = new DataOutputStream(dataBos);
+
+    private AListAccessor(AbstractCollectionType inputType) {
+        if (inputType != null && inputType.getItemType() != null) {
+            itemType = inputType.getItemType();
+            if (itemType.getTypeTag() == ATypeTag.ANY) {
+                typedItemList = false;
+            } else {
+                typedItemList = true;
+                itemTag = inputType.getItemType().getTypeTag();
+            }
+        } else {
+            this.typedItemList = false;
+        }
+    }
+
+    private void reset() {
+        allocator.reset();
+        items.clear();
+        itemTags.clear();
+        dataBos.setByteArray(dataBuffer, 0);
+    }
+
+    @Override
+    public void reset(byte[] b, int s, int len) {
+        reset();
+
+        int numberOfitems = AInt32SerializerDeserializer.getInt(b, s + 6);
+        int itemOffset;
+        if (typedItemList) {
+            switch (itemTag) {
+                case STRING:
+                case RECORD:
+                case ORDEREDLIST:
+                case UNORDEREDLIST:
+                case ANY:
+                    itemOffset = s + 10 + (numberOfitems * 4);
+                    break;
+                default:
+                    itemOffset = s + 10;
+            }
+        } else
+            itemOffset = s + 10 + (numberOfitems * 4);
+        int itemLength = 0;
+        try {
+            if (typedItemList) {
+                for (int i = 0; i < numberOfitems; i++) {
+                    itemLength = NonTaggedFormatUtil.getFieldValueLength(b, itemOffset, itemTag, false);
+                    IBinaryAccessor tag = allocator.allocateFieldType();
+                    IBinaryAccessor item = allocator.allocateFieldValue(itemType);
+
+                    // set item type tag
+                    int start = dataBos.size();
+                    dataDos.writeByte(itemTag.serialize());
+                    int end = dataBos.size();
+                    tag.reset(dataBuffer, start, end - start);
+                    itemTags.add(tag);
+                    
+                    // set item value
+                    start = dataBos.size();
+                    dataDos.writeByte(itemTag.serialize());
+                    dataDos.write(b, itemOffset, itemLength);
+                    end = dataBos.size();
+                    item.reset(dataBuffer, start, end - start);
+                    itemOffset += itemLength;
+                    items.add(item);
+                }
+            } else {
+                for (int i = 0; i < numberOfitems; i++) {
+                    itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[itemOffset]);
+                    itemLength = NonTaggedFormatUtil.getFieldValueLength(b, itemOffset, itemTag, true) + 1;
+                    IBinaryAccessor tag = allocator.allocateFieldType();
+                    IBinaryAccessor item = allocator.allocateFieldValue(itemType);
+
+                    // set item type tag
+                    int start = dataBos.size();
+                    dataDos.writeByte(itemTag.serialize());
+                    int end = dataBos.size();
+                    tag.reset(dataBuffer, start, end - start);
+                    itemTags.add(tag);
+
+                    // open part field already include the type tag
+                    item.reset(b, itemOffset, itemLength);
+                    itemOffset += itemLength;
+                    items.add(item);
+                }
+            }
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    public <R, T> R accept(IBinaryAccessorVisitor<R, T> vistor, T tag) throws AsterixException {
+        return vistor.visit(this, tag);
+    }
+
+    public List<IBinaryAccessor> getItems() {
+        return items;
+    }
+
+    public List<IBinaryAccessor> getItemTags() {
+        return itemTags;
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
similarity index 69%
rename from asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordAccessor.java
rename to asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
index d45b4ac..776cdc0 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordAccessor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
@@ -13,13 +13,14 @@
  * limitations under the License.
  */
 
-package edu.uci.ics.asterix.runtime.util;
+package edu.uci.ics.asterix.runtime.accessors;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.dataflow.data.nontagged.AqlNullWriterFactory;
 import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
 import edu.uci.ics.asterix.om.types.ARecordType;
@@ -28,14 +29,27 @@
 import edu.uci.ics.asterix.om.types.EnumDeserializer;
 import edu.uci.ics.asterix.om.types.IAType;
 import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
+import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
 import edu.uci.ics.hyracks.api.dataflow.value.INullWriter;
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
 
-public class ARecordAccessor implements IValueReference {
+public class ARecordAccessor extends AbstractBinaryAccessor {
 
-    private List<SimpleValueReference> fieldNames = new ArrayList<SimpleValueReference>();
-    private List<SimpleValueReference> fieldTypeTags = new ArrayList<SimpleValueReference>();
-    private List<SimpleValueReference> fieldValues = new ArrayList<SimpleValueReference>();
+    public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
+        public IBinaryAccessor createElement(IAType type) {
+            return new ARecordAccessor((ARecordType) type);
+        }
+    };
+
+    // access results: field names, field types, and field values
+    private List<IBinaryAccessor> fieldNames = new ArrayList<IBinaryAccessor>();
+    private List<IBinaryAccessor> fieldTypeTags = new ArrayList<IBinaryAccessor>();
+    private List<IBinaryAccessor> fieldValues = new ArrayList<IBinaryAccessor>();
+
+    // accessor allocator
+    AccessorAllocator allocator = new AccessorAllocator();
 
     private byte[] typeBuffer = new byte[32768];
     private ResettableByteArrayOutputStream typeBos = new ResettableByteArrayOutputStream();
@@ -51,13 +65,8 @@
     private int numberOfSchemaFields;
     private int offsetArrayOffset;
     private int[] fieldOffsets;
-    private int fieldCursor = -1;
     private ATypeTag typeTag;
-    private SimpleValueReference nullReference = new SimpleValueReference();
-
-    private byte[] data;
-    private int start;
-    private int len;
+    private IBinaryAccessor nullReference = AFlatValueAccessor.FACTORY.createElement(null);
 
     public ARecordAccessor(ARecordType inputType) {
         this.inputRecType = inputType;
@@ -72,11 +81,17 @@
             for (int i = 0; i < numberOfSchemaFields; i++) {
                 ATypeTag ftypeTag = fieldTypes[i].getTypeTag();
 
+                if (fieldTypes[i].getTypeTag() == ATypeTag.UNION
+                        && NonTaggedFormatUtil.isOptionalField((AUnionType) fieldTypes[i]))
+                    // optional field: add the embedded non-null type tag
+                    ftypeTag = ((AUnionType) fieldTypes[i]).getUnionList()
+                            .get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST).getTypeTag();
+
                 // add type tag Reference
                 int tagStart = typeBos.size();
                 typeDos.writeByte(ftypeTag.serialize());
                 int tagEnd = typeBos.size();
-                SimpleValueReference typeTagReference = new SimpleValueReference();
+                IBinaryAccessor typeTagReference = AFlatValueAccessor.FACTORY.createElement(null);
                 typeTagReference.reset(typeBuffer, tagStart, tagEnd - tagStart);
                 fieldTypeTags.add(typeTagReference);
 
@@ -85,7 +100,7 @@
                 typeDos.writeByte(ATypeTag.STRING.serialize());
                 typeDos.writeUTF(fieldNameStrs[i]);
                 int nameEnd = typeBos.size();
-                SimpleValueReference typeNameReference = new SimpleValueReference();
+                IBinaryAccessor typeNameReference = AFlatValueAccessor.FACTORY.createElement(null);
                 typeNameReference.reset(typeBuffer, nameStart, nameEnd - nameStart);
                 fieldNames.add(typeNameReference);
             }
@@ -106,15 +121,21 @@
     private void reset() {
         typeBos.setByteArray(typeBuffer, closedPartTypeInfoSize);
         dataBos.setByteArray(dataBuffer, 0);
-        fieldCursor = -1;
+        // reset the allocator
+        allocator.reset();
+
+        // clean up the returned containers
+        for (int i = fieldNames.size() - 1; i >= numberOfSchemaFields; i--)
+            fieldNames.remove(i);
+        for (int i = fieldTypeTags.size() - 1; i >= numberOfSchemaFields; i--)
+            fieldTypeTags.remove(i);
+        fieldValues.clear();
     }
 
     public void reset(byte[] b, int start, int len) {
         // clear the previous states
         reset();
-        this.data = b;
-        this.start = start;
-        this.len = len;
+        super.reset(b, start, len);
 
         boolean isExpanded = false;
         int openPartOffset = 0;
@@ -153,23 +174,24 @@
                     offsetArrayOffset += 4;
                 }
                 for (int fieldNumber = 0; fieldNumber < numberOfSchemaFields; fieldNumber++) {
-                    next();
                     if (hasNullableFields) {
                         byte b1 = b[nullBitMapOffset + fieldNumber / 8];
                         int p = 1 << (7 - (fieldNumber % 8));
                         if ((b1 & p) == 0) {
                             // set null value (including type tag inside)
-                            nextFieldValue().reset(nullReference);
+                            fieldValues.add(nullReference);
                             continue;
                         }
                     }
                     IAType[] fieldTypes = inputRecType.getFieldTypes();
                     int fieldValueLength = 0;
 
+                    IAType fieldType = fieldTypes[fieldNumber];
                     if (fieldTypes[fieldNumber].getTypeTag() == ATypeTag.UNION) {
                         if (NonTaggedFormatUtil.isOptionalField((AUnionType) fieldTypes[fieldNumber])) {
-                            typeTag = ((AUnionType) fieldTypes[fieldNumber]).getUnionList()
-                                    .get(NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST).getTypeTag();
+                            fieldType = ((AUnionType) fieldTypes[fieldNumber]).getUnionList().get(
+                                    NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
+                            typeTag = fieldType.getTypeTag();
                             fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b, fieldOffsets[fieldNumber],
                                     typeTag, false);
                         }
@@ -183,14 +205,15 @@
                     dataDos.writeByte(typeTag.serialize());
                     dataDos.write(b, fieldOffsets[fieldNumber], fieldValueLength);
                     int fend = dataBos.size();
-                    nextFieldValue().reset(dataBuffer, fstart, fend - fstart);
+                    IBinaryAccessor fieldValue = allocator.allocateFieldValue(fieldType);
+                    fieldValue.reset(dataBuffer, fstart, fend - fstart);
+                    fieldValues.add(fieldValue);
                 }
             }
             if (isExpanded) {
                 int numberOfOpenFields = AInt32SerializerDeserializer.getInt(b, openPartOffset);
                 int fieldOffset = openPartOffset + 4 + (8 * numberOfOpenFields);
                 for (int i = 0; i < numberOfOpenFields; i++) {
-                    next();
                     // set the field name (including a type tag, which is
                     // astring)
                     int fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b, fieldOffset, ATypeTag.STRING,
@@ -199,16 +222,24 @@
                     dataDos.writeByte(ATypeTag.STRING.serialize());
                     dataDos.write(b, fieldOffset, fieldValueLength);
                     int fnend = dataBos.size();
-                    nextFieldName().reset(dataBuffer, fnstart, fnend - fnstart);
+                    IBinaryAccessor fieldName = allocator.allocateFieldName();
+                    fieldName.reset(dataBuffer, fnstart, fnend - fnstart);
+                    fieldNames.add(fieldName);
                     fieldOffset += fieldValueLength;
 
                     // set the field type tag
-                    nextFieldType().reset(b, fieldOffset, 1);
+                    IBinaryAccessor fieldTypeTag = allocator.allocateFieldType();
+                    fieldTypeTag.reset(b, fieldOffset, 1);
+                    fieldTypeTags.add(fieldTypeTag);
                     typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[fieldOffset]);
 
                     // set the field value (already including type tag)
                     fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b, fieldOffset, typeTag, true) + 1;
-                    nextFieldValue().reset(b, fieldOffset, fieldValueLength);
+
+                    // allocate
+                    IBinaryAccessor fieldValueAccessor = allocator.allocateFieldValue(typeTag);
+                    fieldValueAccessor.reset(b, fieldOffset, fieldValueLength);
+                    fieldValues.add(fieldValueAccessor);
                     fieldOffset += fieldValueLength;
                 }
             }
@@ -217,68 +248,21 @@
         }
     }
 
-    private void next() {
-        fieldCursor++;
-    }
-
-    private SimpleValueReference nextFieldName() {
-        if (fieldCursor < fieldNames.size()) {
-            return fieldNames.get(fieldCursor);
-        } else {
-            SimpleValueReference fieldNameReference = new SimpleValueReference();
-            fieldNames.add(fieldNameReference);
-            return fieldNameReference;
-        }
-    }
-
-    private SimpleValueReference nextFieldType() {
-        if (fieldCursor < fieldTypeTags.size()) {
-            return fieldTypeTags.get(fieldCursor);
-        } else {
-            SimpleValueReference fieldTypeReference = new SimpleValueReference();
-            fieldTypeTags.add(fieldTypeReference);
-            return fieldTypeReference;
-        }
-    }
-
-    private SimpleValueReference nextFieldValue() {
-        if (fieldCursor < fieldValues.size()) {
-            return fieldValues.get(fieldCursor);
-        } else {
-            SimpleValueReference fieldValueReference = new SimpleValueReference();
-            fieldValues.add(fieldValueReference);
-            return fieldValueReference;
-        }
-    }
-
-    public int getCursor() {
-        return fieldCursor;
-    }
-
-    public List<SimpleValueReference> getFieldNames() {
+    public List<IBinaryAccessor> getFieldNames() {
         return fieldNames;
     }
 
-    public List<SimpleValueReference> getFieldTypeTags() {
+    public List<IBinaryAccessor> getFieldTypeTags() {
         return fieldTypeTags;
     }
 
-    public List<SimpleValueReference> getFieldValues() {
+    public List<IBinaryAccessor> getFieldValues() {
         return fieldValues;
     }
 
     @Override
-    public byte[] getBytes() {
-        return data;
+    public <R, T> R accept(IBinaryAccessorVisitor<R, T> vistor, T tag) throws AsterixException {
+        return vistor.visit(this, tag);
     }
 
-    @Override
-    public int getStartIndex() {
-        return start;
-    }
-
-    @Override
-    public int getLength() {
-        return len;
-    }
 }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AbstractBinaryAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AbstractBinaryAccessor.java
new file mode 100644
index 0000000..3e027b8
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AbstractBinaryAccessor.java
@@ -0,0 +1,48 @@
+/*
+ * 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.runtime.accessors;
+
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+
+public abstract class AbstractBinaryAccessor implements IBinaryAccessor {
+
+    private byte[] data;
+    private int start;
+    private int len;
+    
+    @Override
+    public byte[] getBytes() {
+        return data;
+    }
+
+    @Override
+    public int getLength() {
+        return len;
+    }
+
+    @Override
+    public int getStartIndex() {
+        return start;
+    }
+
+    @Override
+    public void reset(byte[] b, int start, int len) {
+        this.data = b;
+        this.start = start;
+        this.len = len;
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AccessorAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AccessorAllocator.java
new file mode 100644
index 0000000..a44885b
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AccessorAllocator.java
@@ -0,0 +1,75 @@
+/*
+ * 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.runtime.accessors;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.accessors.base.DefaultOpenFieldType;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.util.container.IElementAllocator;
+import edu.uci.ics.asterix.runtime.util.container.ListElementAllocator;
+
+public class AccessorAllocator {
+
+    private IElementAllocator<IBinaryAccessor, IAType> flatArtifactAllocator = new ListElementAllocator<IBinaryAccessor, IAType>(
+            AFlatValueAccessor.FACTORY);
+    private IElementAllocator<IBinaryAccessor, IAType> nestedRecValueAllocator = new ListElementAllocator<IBinaryAccessor, IAType>(
+            ARecordAccessor.FACTORY);
+    private IElementAllocator<IBinaryAccessor, IAType> nestedListValueAllocator = new ListElementAllocator<IBinaryAccessor, IAType>(
+            AListAccessor.FACTORY);
+
+    public IBinaryAccessor allocateFieldName() {
+        return flatArtifactAllocator.allocate(null);
+    }
+
+    public IBinaryAccessor allocateFieldType() {
+        return flatArtifactAllocator.allocate(null);
+    }
+
+    public IBinaryAccessor allocateFieldValue(IAType type) {
+        if(type == null)
+            return flatArtifactAllocator.allocate(null);
+        else if (type.getTypeTag().equals(ATypeTag.RECORD))
+            return nestedRecValueAllocator.allocate(type);
+        else if (type.getTypeTag().equals(ATypeTag.UNORDEREDLIST) || type.getTypeTag().equals(ATypeTag.ORDEREDLIST))
+            return nestedListValueAllocator.allocate(type);
+        else
+            return flatArtifactAllocator.allocate(null);
+    }
+    
+    public IBinaryAccessor allocateFieldValue(ATypeTag typeTag) {
+        if(typeTag == null)
+            return flatArtifactAllocator.allocate(null);
+        else if (typeTag.equals(ATypeTag.RECORD))
+            return nestedRecValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+        else if (typeTag.equals(ATypeTag.UNORDEREDLIST))
+            return nestedListValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE);
+        else if(typeTag.equals(ATypeTag.ORDEREDLIST))
+            return nestedListValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE);
+        else
+            return flatArtifactAllocator.allocate(null);
+    }
+
+    public IBinaryAccessor allocateNestedListValue(IAType type) {
+        return nestedListValueAllocator.allocate(type);
+    }
+
+    public void reset() {
+        flatArtifactAllocator.reset();
+        nestedRecValueAllocator.reset();
+        nestedListValueAllocator.reset();
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/DefaultOpenFieldType.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/DefaultOpenFieldType.java
new file mode 100644
index 0000000..9da464f
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/DefaultOpenFieldType.java
@@ -0,0 +1,50 @@
+/*
+ * 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.runtime.accessors.base;
+
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnorderedListType;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.IAType;
+
+public class DefaultOpenFieldType {
+
+    // nested open field rec type
+    public static ARecordType NESTED_OPEN_RECORD_TYPE = new ARecordType("nested-open", new String[] {},
+            new IAType[] {}, true);
+
+    // nested open list type
+    public static AOrderedListType NESTED_OPEN_AORDERED_LIST_TYPE = new AOrderedListType(BuiltinType.ANY,
+            "nested-ordered-list");
+
+    // nested open list type
+    public static AUnorderedListType NESTED_OPEN_AUNORDERED_LIST_TYPE = new AUnorderedListType(BuiltinType.ANY,
+            "nested-unordered-list");
+    
+    public static IAType getDefaultOpenFieldType(ATypeTag tag){
+        if(tag.equals(ATypeTag.RECORD))
+            return NESTED_OPEN_RECORD_TYPE;
+        if(tag.equals(ATypeTag.ORDEREDLIST))
+            return NESTED_OPEN_AORDERED_LIST_TYPE;
+        if(tag.equals(ATypeTag.UNORDEREDLIST))
+            return NESTED_OPEN_AUNORDERED_LIST_TYPE;
+        else
+            return null;
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/IBinaryAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/IBinaryAccessor.java
new file mode 100644
index 0000000..37d8b80
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/base/IBinaryAccessor.java
@@ -0,0 +1,27 @@
+/*
+ * 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.runtime.accessors.base;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
+
+public interface IBinaryAccessor extends IValueReference {
+
+    public void reset(byte[] b, int start, int len);
+
+    public <R, T> R accept(IBinaryAccessorVisitor<R, T> vistor, T tag) throws AsterixException;
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ACastVisitor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ACastVisitor.java
new file mode 100644
index 0000000..54b0960
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ACastVisitor.java
@@ -0,0 +1,74 @@
+/*
+ * 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.runtime.accessors.cast;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.AbstractCollectionType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.accessors.AFlatValueAccessor;
+import edu.uci.ics.asterix.runtime.accessors.AListAccessor;
+import edu.uci.ics.asterix.runtime.accessors.ARecordAccessor;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
+
+public class ACastVisitor implements IBinaryAccessorVisitor<Void, Triple<IBinaryAccessor, IAType, Boolean>> {
+
+    private Map<IBinaryAccessor, ARecordCaster> raccessorToCaster = new HashMap<IBinaryAccessor, ARecordCaster>();
+    private Map<IBinaryAccessor, AListCaster> laccessorToCaster = new HashMap<IBinaryAccessor, AListCaster>();
+
+    @Override
+    public Void visit(AListAccessor accessor, Triple<IBinaryAccessor, IAType, Boolean> arg) throws AsterixException {
+        AListCaster caster = laccessorToCaster.get(accessor);
+        if (caster == null) {
+            caster = new AListCaster();
+            laccessorToCaster.put(accessor, caster);
+        }
+        try {
+            caster.castList(accessor, arg.first, (AbstractCollectionType) arg.second, this);
+        } catch (Exception e) {
+            throw new AsterixException(e);
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(ARecordAccessor accessor, Triple<IBinaryAccessor, IAType, Boolean> arg) throws AsterixException {
+        ARecordCaster caster = raccessorToCaster.get(accessor);
+        if (caster == null) {
+            caster = new ARecordCaster();
+            raccessorToCaster.put(accessor, caster);
+        }
+        try {
+            caster.castRecord(accessor, arg.first, (ARecordType) arg.second, this);
+        } catch (Exception e) {
+            throw new AsterixException(e);
+        }
+        return null;
+    }
+
+    @Override
+    public Void visit(AFlatValueAccessor accessor, Triple<IBinaryAccessor, IAType, Boolean> arg) {
+        // set the pointer for result
+        arg.first.reset(accessor.getBytes(), accessor.getStartIndex(), accessor.getLength());
+        return null;
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/AListCaster.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/AListCaster.java
new file mode 100644
index 0000000..aba06b5
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/AListCaster.java
@@ -0,0 +1,101 @@
+/*
+ * 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.runtime.accessors.cast;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import edu.uci.ics.asterix.builders.OrderedListBuilder;
+import edu.uci.ics.asterix.builders.UnorderedListBuilder;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.types.AOrderedListType;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.AUnorderedListType;
+import edu.uci.ics.asterix.om.types.AbstractCollectionType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.accessors.AFlatValueAccessor;
+import edu.uci.ics.asterix.runtime.accessors.AListAccessor;
+import edu.uci.ics.asterix.runtime.accessors.base.DefaultOpenFieldType;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
+import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
+
+class AListCaster {
+
+    private IAType reqItemType;
+    private IBinaryAccessor itemTempReference = AFlatValueAccessor.FACTORY.createElement(null);
+    private Triple<IBinaryAccessor, IAType, Boolean> itemVisitorArg = new Triple<IBinaryAccessor, IAType, Boolean>(
+            itemTempReference, null, null);
+
+    private UnorderedListBuilder unOrderedListBuilder = new UnorderedListBuilder();
+    private OrderedListBuilder orderedListBuilder = new OrderedListBuilder();
+
+    private byte[] dataBuffer = new byte[32768];
+    private ResettableByteArrayOutputStream dataBos = new ResettableByteArrayOutputStream();
+    private DataOutput dataDos = new DataOutputStream(dataBos);
+
+    public AListCaster() {
+
+    }
+
+    public void castList(AListAccessor listAccessor, IBinaryAccessor resultAccessor, AbstractCollectionType reqType,
+            ACastVisitor visitor) throws IOException, AsterixException {
+        if (reqType.getTypeTag().equals(ATypeTag.UNORDEREDLIST)) {
+            unOrderedListBuilder.reset((AUnorderedListType) reqType);
+        }
+        if (reqType.getTypeTag().equals(ATypeTag.ORDEREDLIST)) {
+            orderedListBuilder.reset((AOrderedListType) reqType);
+        }
+        dataBos.setByteArray(dataBuffer, 0);
+
+        List<IBinaryAccessor> itemTags = listAccessor.getItemTags();
+        List<IBinaryAccessor> items = listAccessor.getItems();
+
+        int start = dataBos.size();
+        for (int i = 0; i < items.size(); i++) {
+            IBinaryAccessor itemTypeTag = itemTags.get(i);
+            IBinaryAccessor item = items.get(i);
+            ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(itemTypeTag.getBytes()[itemTypeTag
+                    .getStartIndex()]);
+            if (reqItemType == null || reqItemType.getTypeTag().equals(ATypeTag.ANY)) {
+                itemVisitorArg.second = DefaultOpenFieldType.getDefaultOpenFieldType(typeTag);
+                item.accept(visitor, itemVisitorArg);
+            } else {
+                if (typeTag != reqItemType.getTypeTag())
+                    throw new AsterixException("mismatched item type");
+                itemVisitorArg.second = reqItemType;
+                item.accept(visitor, itemVisitorArg);
+            }
+            if (reqType.getTypeTag().equals(ATypeTag.ORDEREDLIST)) {
+                orderedListBuilder.addItem(itemVisitorArg.first);
+            }
+            if (reqType.getTypeTag().equals(ATypeTag.UNORDEREDLIST)) {
+                unOrderedListBuilder.addItem(itemVisitorArg.first);
+            }
+        }
+        if (reqType.getTypeTag().equals(ATypeTag.ORDEREDLIST)) {
+            orderedListBuilder.write(dataDos, true);
+        }
+        if (reqType.getTypeTag().equals(ATypeTag.UNORDEREDLIST)) {
+            unOrderedListBuilder.write(dataDos, true);
+        }
+        int end = dataBos.size();
+        resultAccessor.reset(dataBuffer, start, end - start);
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordCaster.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ARecordCaster.java
similarity index 70%
rename from asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordCaster.java
rename to asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ARecordCaster.java
index 505e769..a4efa58 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/ARecordCaster.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ARecordCaster.java
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-package edu.uci.ics.asterix.runtime.util;
+package edu.uci.ics.asterix.runtime.accessors.cast;
 
 import java.io.DataOutput;
 import java.io.DataOutputStream;
@@ -22,19 +22,27 @@
 import java.util.List;
 
 import edu.uci.ics.asterix.builders.RecordBuilder;
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
 import edu.uci.ics.asterix.dataflow.data.nontagged.AqlNullWriterFactory;
 import edu.uci.ics.asterix.om.types.ARecordType;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.AUnionType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
 import edu.uci.ics.asterix.om.types.IAType;
 import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
+import edu.uci.ics.asterix.runtime.accessors.AFlatValueAccessor;
+import edu.uci.ics.asterix.runtime.accessors.ARecordAccessor;
+import edu.uci.ics.asterix.runtime.accessors.base.DefaultOpenFieldType;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
+import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
 import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
 import edu.uci.ics.hyracks.api.dataflow.value.INullWriter;
 import edu.uci.ics.hyracks.data.std.accessors.PointableBinaryComparatorFactory;
 import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
 
-public class ARecordCaster {
+class ARecordCaster {
 
     // describe closed fields in the required type
     private int[] fieldPermutation;
@@ -44,9 +52,9 @@
     private boolean[] openFields;
     private int[] fieldNamesSortedIndex;
 
-    private List<SimpleValueReference> reqFieldNames = new ArrayList<SimpleValueReference>();
+    private List<IBinaryAccessor> reqFieldNames = new ArrayList<IBinaryAccessor>();
     private int[] reqFieldNamesSortedIndex;
-    private List<SimpleValueReference> reqFieldTypeTags = new ArrayList<SimpleValueReference>();
+    private List<IBinaryAccessor> reqFieldTypeTags = new ArrayList<IBinaryAccessor>();
     private ARecordType cachedReqType = null;
 
     private byte[] buffer = new byte[32768];
@@ -54,13 +62,21 @@
     private DataOutputStream dos = new DataOutputStream(bos);
 
     private RecordBuilder recBuilder = new RecordBuilder();
-    private SimpleValueReference nullReference = new SimpleValueReference();
-    private SimpleValueReference nullTypeTag = new SimpleValueReference();
+    private IBinaryAccessor nullReference = AFlatValueAccessor.FACTORY.createElement(null);
+    private IBinaryAccessor nullTypeTag = AFlatValueAccessor.FACTORY.createElement(null);
 
     private int numInputFields = 0;
     private IBinaryComparator fieldNameComparator = PointableBinaryComparatorFactory.of(UTF8StringPointable.FACTORY)
             .createBinaryComparator();
 
+    private byte[] outputBuffer = new byte[32768];
+    private ResettableByteArrayOutputStream outputBos = new ResettableByteArrayOutputStream();
+    private DataOutputStream outputDos = new DataOutputStream(outputBos);
+
+    private IBinaryAccessor fieldTempReference = AFlatValueAccessor.FACTORY.createElement(null);
+    private Triple<IBinaryAccessor, IAType, Boolean> nestedVisitorArg = new Triple<IBinaryAccessor, IAType, Boolean>(
+            fieldTempReference, null, null);
+
     public ARecordCaster() {
         try {
             bos.setByteArray(buffer, 0);
@@ -78,11 +94,12 @@
         }
     }
 
-    public void castRecord(ARecordAccessor recordAccessor, ARecordType reqType, DataOutput output) throws IOException {
-        List<SimpleValueReference> fieldNames = recordAccessor.getFieldNames();
-        List<SimpleValueReference> fieldTypeTags = recordAccessor.getFieldTypeTags();
-        List<SimpleValueReference> fieldValues = recordAccessor.getFieldValues();
-        numInputFields = recordAccessor.getCursor() + 1;
+    public void castRecord(ARecordAccessor recordAccessor, IBinaryAccessor resultAccessor, ARecordType reqType,
+            ACastVisitor visitor) throws IOException, AsterixException {
+        List<IBinaryAccessor> fieldNames = recordAccessor.getFieldNames();
+        List<IBinaryAccessor> fieldTypeTags = recordAccessor.getFieldTypeTags();
+        List<IBinaryAccessor> fieldValues = recordAccessor.getFieldValues();
+        numInputFields = fieldNames.size();
 
         if (openFields == null || numInputFields > openFields.length) {
             openFields = new boolean[numInputFields];
@@ -95,7 +112,8 @@
         // clear the previous states
         reset();
         matchClosedPart(fieldNames, fieldTypeTags, fieldValues);
-        writeOutput(fieldNames, fieldTypeTags, fieldValues, output);
+        writeOutput(fieldNames, fieldTypeTags, fieldValues, outputDos, visitor);
+        resultAccessor.reset(outputBuffer, 0, outputBos.size());
     }
 
     private void reset() {
@@ -105,6 +123,7 @@
             fieldPermutation[i] = -1;
         for (int i = 0; i < numInputFields; i++)
             fieldNamesSortedIndex[i] = i;
+        outputBos.setByteArray(outputBuffer, 0);
     }
 
     private void loadRequiredType(ARecordType reqType) throws IOException {
@@ -136,7 +155,7 @@
             int tagStart = bos.size();
             dos.writeByte(ftypeTag.serialize());
             int tagEnd = bos.size();
-            SimpleValueReference typeTagPointable = new SimpleValueReference();
+            IBinaryAccessor typeTagPointable = AFlatValueAccessor.FACTORY.createElement(null);
             typeTagPointable.reset(buffer, tagStart, tagEnd - tagStart);
             reqFieldTypeTags.add(typeTagPointable);
 
@@ -145,7 +164,7 @@
             dos.write(ATypeTag.STRING.serialize());
             dos.writeUTF(fname);
             int nameEnd = bos.size();
-            SimpleValueReference typeNamePointable = new SimpleValueReference();
+            IBinaryAccessor typeNamePointable = AFlatValueAccessor.FACTORY.createElement(null);
             typeNamePointable.reset(buffer, nameStart, nameEnd - nameStart);
             reqFieldNames.add(typeNamePointable);
         }
@@ -157,8 +176,8 @@
         quickSort(reqFieldNamesSortedIndex, reqFieldNames, 0, reqFieldNamesSortedIndex.length - 1);
     }
 
-    private void matchClosedPart(List<SimpleValueReference> fieldNames, List<SimpleValueReference> fieldTypeTags,
-            List<SimpleValueReference> fieldValues) {
+    private void matchClosedPart(List<IBinaryAccessor> fieldNames, List<IBinaryAccessor> fieldTypeTags,
+            List<IBinaryAccessor> fieldValues) {
         // sort-merge based match
         quickSort(fieldNamesSortedIndex, fieldNames, 0, numInputFields - 1);
         int fnStart = 0;
@@ -168,8 +187,8 @@
             int reqFnPos = reqFieldNamesSortedIndex[reqFnStart];
             int c = compare(fieldNames.get(fnPos), reqFieldNames.get(reqFnPos));
             if (c == 0) {
-                SimpleValueReference fieldTypeTag = fieldTypeTags.get(fnPos);
-                SimpleValueReference reqFieldTypeTag = reqFieldTypeTags.get(reqFnPos);
+                IBinaryAccessor fieldTypeTag = fieldTypeTags.get(fnPos);
+                IBinaryAccessor reqFieldTypeTag = reqFieldTypeTags.get(reqFnPos);
                 if (fieldTypeTag.equals(reqFieldTypeTag) || (
                 // match the null type of optional field
                         optionalFields[reqFnPos] && fieldTypeTag.equals(nullTypeTag))) {
@@ -203,8 +222,9 @@
         }
     }
 
-    private void writeOutput(List<SimpleValueReference> fieldNames, List<SimpleValueReference> fieldTypeTags,
-            List<SimpleValueReference> fieldValues, DataOutput output) throws IOException {
+    private void writeOutput(List<IBinaryAccessor> fieldNames, List<IBinaryAccessor> fieldTypeTags,
+            List<IBinaryAccessor> fieldValues, DataOutput output, ACastVisitor visitor) throws IOException,
+            AsterixException {
         // reset the states of the record builder
         recBuilder.reset(cachedReqType);
         recBuilder.init();
@@ -212,27 +232,43 @@
         // write the closed part
         for (int i = 0; i < fieldPermutation.length; i++) {
             int pos = fieldPermutation[i];
-            SimpleValueReference field;
+            IBinaryAccessor field;
             if (pos >= 0) {
                 field = fieldValues.get(pos);
             } else {
                 field = nullReference;
             }
-            recBuilder.addField(i, field);
+            IAType fType = cachedReqType.getFieldTypes()[i];
+            nestedVisitorArg.second = fType;
+
+            // recursively casting, the result of casting can always be thought
+            // as flat
+            if (optionalFields[i]) {
+                nestedVisitorArg.second = ((AUnionType) fType).getUnionList().get(
+                        NonTaggedFormatUtil.OPTIONAL_TYPE_INDEX_IN_UNION_LIST);
+            }
+            field.accept(visitor, nestedVisitorArg);
+            recBuilder.addField(i, nestedVisitorArg.first);
         }
 
         // write the open part
         for (int i = 0; i < numInputFields; i++) {
             if (openFields[i]) {
-                SimpleValueReference name = fieldNames.get(i);
-                SimpleValueReference field = fieldValues.get(i);
-                recBuilder.addField(name, field);
+                IBinaryAccessor name = fieldNames.get(i);
+                IBinaryAccessor field = fieldValues.get(i);
+                IBinaryAccessor fieldTypeTag = fieldTypeTags.get(i);
+
+                ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER
+                        .deserialize(fieldTypeTag.getBytes()[fieldTypeTag.getStartIndex()]);
+                nestedVisitorArg.second = DefaultOpenFieldType.getDefaultOpenFieldType(typeTag);
+                field.accept(visitor, nestedVisitorArg);
+                recBuilder.addField(name, nestedVisitorArg.first);
             }
         }
         recBuilder.write(output, true);
     }
 
-    private void quickSort(int[] index, List<SimpleValueReference> names, int start, int end) {
+    private void quickSort(int[] index, List<IBinaryAccessor> names, int start, int end) {
         if (end <= start)
             return;
         int i = partition(index, names, start, end);
@@ -240,7 +276,7 @@
         quickSort(index, names, i + 1, end);
     }
 
-    private int partition(int[] index, List<SimpleValueReference> names, int left, int right) {
+    private int partition(int[] index, List<IBinaryAccessor> names, int left, int right) {
         int i = left - 1;
         int j = right;
         while (true) {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/visitor/IBinaryAccessorVisitor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/visitor/IBinaryAccessorVisitor.java
new file mode 100644
index 0000000..e35421a
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/visitor/IBinaryAccessorVisitor.java
@@ -0,0 +1,30 @@
+/*
+ * 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.runtime.accessors.visitor;
+
+import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.runtime.accessors.AFlatValueAccessor;
+import edu.uci.ics.asterix.runtime.accessors.AListAccessor;
+import edu.uci.ics.asterix.runtime.accessors.ARecordAccessor;
+
+public interface IBinaryAccessorVisitor<R, T> {
+
+    public R visit(AListAccessor accessor, T arg) throws AsterixException;
+
+    public R visit(ARecordAccessor accessor, T arg) throws AsterixException;
+
+    public R visit(AFlatValueAccessor accessor, T arg) throws AsterixException;
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
index 705efab..c82bb9b 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
@@ -1,16 +1,18 @@
 package edu.uci.ics.asterix.runtime.evaluators.functions;
 
 import java.io.DataOutput;
-import java.io.IOException;
 
 import edu.uci.ics.asterix.common.functions.FunctionConstants;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
 import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
 import edu.uci.ics.asterix.om.types.ARecordType;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.accessors.ARecordAccessor;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.accessors.cast.ACastVisitor;
 import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import edu.uci.ics.asterix.runtime.util.ARecordAccessor;
-import edu.uci.ics.asterix.runtime.util.ARecordCaster;
 import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import edu.uci.ics.hyracks.algebricks.runtime.base.IEvaluator;
 import edu.uci.ics.hyracks.algebricks.runtime.base.IEvaluatorFactory;
@@ -57,7 +59,10 @@
 
                 return new IEvaluator() {
                     final ARecordAccessor recAccessor = new ARecordAccessor(inputType);
-                    final ARecordCaster caster = new ARecordCaster();
+                    final ARecordAccessor resultAccessor = new ARecordAccessor(reqType);
+                    final ACastVisitor castVisitor = new ACastVisitor();
+                    final Triple<IBinaryAccessor, IAType, Boolean> arg = new Triple<IBinaryAccessor, IAType, Boolean>(
+                            resultAccessor, reqType, Boolean.FALSE);
 
                     @Override
                     public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
@@ -66,8 +71,10 @@
                             recEvaluator.evaluate(tuple);
                             recAccessor.reset(recordBuffer.getBytes(), recordBuffer.getStartIndex(),
                                     recordBuffer.getLength());
-                            caster.castRecord(recAccessor, reqType, out);
-                        } catch (IOException ioe) {
+                            recAccessor.accept(castVisitor, arg);
+                            out.write(resultAccessor.getBytes(), resultAccessor.getStartIndex(),
+                                    resultAccessor.getLength());
+                        } catch (Exception ioe) {
                             throw new AlgebricksException(ioe);
                         }
                     }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/SimpleValueReference.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/SimpleValueReference.java
deleted file mode 100644
index e49218a..0000000
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/SimpleValueReference.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.runtime.util;
-
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
-
-public class SimpleValueReference implements IValueReference {
-
-    private byte[] data;
-    private int start;
-    private int len;
-
-    public void reset(byte[] data, int start, int len) {
-        this.data = data;
-        this.start = start;
-        this.len = len;
-    }
-
-    public void reset(IValueReference ivf) {
-        this.data = ivf.getBytes();
-        this.start = ivf.getStartIndex();
-        this.len = ivf.getLength();
-    }
-
-    @Override
-    public byte[] getBytes() {
-        return data;
-    }
-
-    @Override
-    public int getStartIndex() {
-        return start;
-    }
-
-    @Override
-    public int getLength() {
-        return len;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (!(o instanceof IValueReference))
-            return false;
-        IValueReference ivf = (IValueReference) o;
-        byte[] odata = ivf.getBytes();
-        int ostart = ivf.getStartIndex();
-        int olen = ivf.getLength();
-
-        if (len != olen)
-            return false;
-        for (int i = 0; i < len; i++) {
-            if (data[start + i] != odata[ostart + i])
-                return false;
-        }
-        return true;
-    }
-}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementAllocator.java
new file mode 100644
index 0000000..8d17cb7
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementAllocator.java
@@ -0,0 +1,23 @@
+/*
+ * 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.runtime.util.container;
+
+public interface IElementAllocator<E, T> {
+
+    public E allocate(T arg);
+
+    public void reset();
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementFactory.java
new file mode 100644
index 0000000..4698c25
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementFactory.java
@@ -0,0 +1,21 @@
+/*
+ * 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.runtime.util.container;
+
+public interface IElementFactory<E, T> {
+
+    public E createElement(T arg);
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/ListElementAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/ListElementAllocator.java
new file mode 100644
index 0000000..447b740
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/ListElementAllocator.java
@@ -0,0 +1,45 @@
+/*
+ * 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.runtime.util.container;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ListElementAllocator<E, T> implements IElementAllocator<E, T> {
+
+    private IElementFactory<E, T> factory;
+    private List<E> pool = new ArrayList<E>();
+    private int cursor = -1;
+
+    public ListElementAllocator(IElementFactory<E, T> factory) {
+        this.factory = factory;
+    }
+
+    public E allocate(T arg) {
+        cursor++;
+        if (cursor < pool.size()) {
+            return pool.get(cursor);
+        } else {
+            E element = factory.createElement(arg);
+            pool.add(element);
+            return element;
+        }
+    }
+
+    public void reset() {
+        cursor = -1;
+    }
+}