Replaced LogicalOperatorReference and LogicalExpressionReference with Mutable from commons-lang.

git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_dev_next@950 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/PrioritizedRuleController.java b/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/PrioritizedRuleController.java
index 570bb2c..129ec26 100644
--- a/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/PrioritizedRuleController.java
+++ b/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/PrioritizedRuleController.java
@@ -16,7 +16,9 @@
 
 import java.util.Collection;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.rewriter.base.AbstractRuleController;
 import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
@@ -38,7 +40,7 @@
     }
 
     @Override
-    public boolean rewriteWithRuleCollection(LogicalOperatorReference root, Collection<IAlgebraicRewriteRule> rules)
+    public boolean rewriteWithRuleCollection(Mutable<ILogicalOperator> root, Collection<IAlgebraicRewriteRule> rules)
             throws AlgebricksException {
         boolean anyRuleFired = false;
         boolean anyChange = false;
diff --git a/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/SequentialFixpointRuleController.java b/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/SequentialFixpointRuleController.java
index 4658041..8be65f4 100644
--- a/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/SequentialFixpointRuleController.java
+++ b/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/SequentialFixpointRuleController.java
@@ -16,7 +16,9 @@
 
 import java.util.Collection;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.rewriter.base.AbstractRuleController;
 import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
@@ -40,7 +42,7 @@
     }
 
     @Override
-    public boolean rewriteWithRuleCollection(LogicalOperatorReference root,
+    public boolean rewriteWithRuleCollection(Mutable<ILogicalOperator> root,
             Collection<IAlgebraicRewriteRule> ruleCollection) throws AlgebricksException {
         boolean anyRuleFired = false;
         boolean anyChange = false;
diff --git a/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/SequentialOnceRuleController.java b/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/SequentialOnceRuleController.java
index 69281a1..5cf62e0 100644
--- a/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/SequentialOnceRuleController.java
+++ b/hyracks-algebricks/hyracks-algebricks-compiler/src/main/java/edu/uci/ics/hyracks/algebricks/compiler/rewriter/rulecontrollers/SequentialOnceRuleController.java
@@ -16,7 +16,9 @@
 
 import java.util.Collection;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.rewriter.base.AbstractRuleController;
 import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
@@ -31,7 +33,7 @@
     }
 
     @Override
-    public boolean rewriteWithRuleCollection(LogicalOperatorReference root, Collection<IAlgebraicRewriteRule> rules)
+    public boolean rewriteWithRuleCollection(Mutable<ILogicalOperator> root, Collection<IAlgebraicRewriteRule> rules)
             throws AlgebricksException {
         boolean fired = false;
         for (IAlgebraicRewriteRule rule : rules) {
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalExpression.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalExpression.java
index 2d19944..a54a88d 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalExpression.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalExpression.java
@@ -18,6 +18,8 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.FunctionalDependency;
 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionVisitor;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -62,7 +64,7 @@
      * @return true if the expression can be broken in at least two conjuncts,
      *         false otherwise.
      */
-    public boolean splitIntoConjuncts(List<LogicalExpressionReference> conjs);
+    public boolean splitIntoConjuncts(List<Mutable<ILogicalExpression>> conjs);
 
     public abstract ILogicalExpression cloneExpression();
 }
\ No newline at end of file
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalOperator.java
index 198d762..719b5df 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalOperator.java
@@ -17,6 +17,8 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
@@ -30,7 +32,7 @@
 
 public interface ILogicalOperator {
 
-    public List<LogicalOperatorReference> getInputs();
+    public List<Mutable<ILogicalOperator>> getInputs();
 
     boolean hasInputs();
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalPlan.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalPlan.java
index bf0f548..c94a9c1 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalPlan.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/ILogicalPlan.java
@@ -16,6 +16,8 @@
 
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 public interface ILogicalPlan {
-    public List<LogicalOperatorReference> getRoots();
+    public List<Mutable<ILogicalOperator>> getRoots();
 }
\ No newline at end of file
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/LogicalExpressionReference.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/LogicalExpressionReference.java
deleted file mode 100644
index 6ab0cb9..0000000
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/LogicalExpressionReference.java
+++ /dev/null
@@ -1,35 +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.hyracks.algebricks.core.algebra.base;
-
-public final class LogicalExpressionReference {
-    private ILogicalExpression expression;
-
-    public LogicalExpressionReference(ILogicalExpression expression) {
-        this.expression = expression;
-    }
-
-    public ILogicalExpression getExpression() {
-        return expression;
-    }
-
-    public void setExpression(ILogicalExpression expression) {
-        this.expression = expression;
-    }
-
-    public String toString() {
-        return expression.toString();
-    }
-}
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/LogicalOperatorReference.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/LogicalOperatorReference.java
deleted file mode 100644
index ce47ff8..0000000
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/base/LogicalOperatorReference.java
+++ /dev/null
@@ -1,39 +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.hyracks.algebricks.core.algebra.base;
-
-public final class LogicalOperatorReference {
-    private ILogicalOperator operator;
-
-    public LogicalOperatorReference() {
-    }
-
-    public LogicalOperatorReference(ILogicalOperator operator) {
-        this.operator = operator;
-    }
-
-    public ILogicalOperator getOperator() {
-        return operator;
-    }
-
-    public void setOperator(ILogicalOperator operator) {
-        this.operator = operator;
-    }
-
-    @Override
-    public String toString() {
-        return operator == null ? "" : operator.toString();
-    }
-}
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
index 6dcaa31..dae055c 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
@@ -21,9 +21,11 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.EquivalenceClass;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
@@ -34,17 +36,20 @@
 public abstract class AbstractFunctionCallExpression extends AbstractLogicalExpression {
 
     public enum FunctionKind {
-        SCALAR, STATEFUL, AGGREGATE, UNNEST
+        SCALAR,
+        STATEFUL,
+        AGGREGATE,
+        UNNEST
     }
 
     protected IFunctionInfo finfo;
-    final private List<LogicalExpressionReference> arguments;
+    final private List<Mutable<ILogicalExpression>> arguments;
     private Object[] opaqueParameters;
     private final FunctionKind kind;
     private Map<Object, IExpressionAnnotation> annotationMap = new HashMap<Object, IExpressionAnnotation>();
 
     public AbstractFunctionCallExpression(FunctionKind kind, IFunctionInfo finfo,
-            List<LogicalExpressionReference> arguments) {
+            List<Mutable<ILogicalExpression>> arguments) {
         this.kind = kind;
         this.finfo = finfo;
         this.arguments = arguments;
@@ -53,13 +58,13 @@
     public AbstractFunctionCallExpression(FunctionKind kind, IFunctionInfo finfo) {
         this.kind = kind;
         this.finfo = finfo;
-        this.arguments = new ArrayList<LogicalExpressionReference>();
+        this.arguments = new ArrayList<Mutable<ILogicalExpression>>();
     }
 
     public AbstractFunctionCallExpression(FunctionKind kind, IFunctionInfo finfo,
-            LogicalExpressionReference... expressions) {
+            Mutable<ILogicalExpression>... expressions) {
         this(kind, finfo);
-        for (LogicalExpressionReference e : expressions) {
+        for (Mutable<ILogicalExpression> e : expressions) {
             this.arguments.add(e);
         }
     }
@@ -76,11 +81,11 @@
         return kind;
     }
 
-    protected List<LogicalExpressionReference> cloneArguments() {
-        List<LogicalExpressionReference> clonedArgs = new ArrayList<LogicalExpressionReference>(arguments.size());
-        for (LogicalExpressionReference e : arguments) {
-            ILogicalExpression e2 = ((AbstractLogicalExpression) e.getExpression()).cloneExpression();
-            clonedArgs.add(new LogicalExpressionReference(e2));
+    protected List<Mutable<ILogicalExpression>> cloneArguments() {
+        List<Mutable<ILogicalExpression>> clonedArgs = new ArrayList<Mutable<ILogicalExpression>>(arguments.size());
+        for (Mutable<ILogicalExpression> e : arguments) {
+            ILogicalExpression e2 = ((AbstractLogicalExpression) e.getValue()).cloneExpression();
+            clonedArgs.add(new MutableObject<ILogicalExpression>(e2));
         }
         return clonedArgs;
     }
@@ -97,7 +102,7 @@
         this.finfo = finfo;
     }
 
-    public List<LogicalExpressionReference> getArguments() {
+    public List<Mutable<ILogicalExpression>> getArguments() {
         return arguments;
     }
 
@@ -106,13 +111,13 @@
         sb.append("function-call: " + finfo.getFunctionIdentifier() + ", Args:[");
         // + arguments;
         boolean first = true;
-        for (LogicalExpressionReference ref : arguments) {
+        for (Mutable<ILogicalExpression> ref : arguments) {
             if (first) {
                 first = false;
             } else {
                 sb.append(", ");
             }
-            sb.append(ref.getExpression());
+            sb.append(ref.getValue());
         }
         sb.append("]");
         return sb.toString();
@@ -125,15 +130,15 @@
 
     @Override
     public void getUsedVariables(Collection<LogicalVariable> vars) {
-        for (LogicalExpressionReference arg : arguments) {
-            arg.getExpression().getUsedVariables(vars);
+        for (Mutable<ILogicalExpression> arg : arguments) {
+            arg.getValue().getUsedVariables(vars);
         }
     }
 
     @Override
     public void substituteVar(LogicalVariable v1, LogicalVariable v2) {
-        for (LogicalExpressionReference arg : arguments) {
-            arg.getExpression().substituteVar(v1, v2);
+        for (Mutable<ILogicalExpression> arg : arguments) {
+            arg.getValue().substituteVar(v1, v2);
         }
     }
 
@@ -142,12 +147,12 @@
             Map<LogicalVariable, EquivalenceClass> equivClasses) {
         FunctionIdentifier funId = getFunctionIdentifier();
         if (funId == AlgebricksBuiltinFunctions.AND) {
-            for (LogicalExpressionReference a : arguments) {
-                a.getExpression().getConstraintsAndEquivClasses(fds, equivClasses);
+            for (Mutable<ILogicalExpression> a : arguments) {
+                a.getValue().getConstraintsAndEquivClasses(fds, equivClasses);
             }
         } else if (funId == AlgebricksBuiltinFunctions.EQ) {
-            ILogicalExpression opLeft = arguments.get(0).getExpression();
-            ILogicalExpression opRight = arguments.get(1).getExpression();
+            ILogicalExpression opLeft = arguments.get(0).getValue();
+            ILogicalExpression opRight = arguments.get(1).getValue();
             if (opLeft.getExpressionTag() == LogicalExpressionTag.CONSTANT
                     && opRight.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 ConstantExpression op1 = (ConstantExpression) opLeft;
@@ -166,12 +171,12 @@
     public void getConstraintsForOuterJoin(Collection<FunctionalDependency> fds, Collection<LogicalVariable> outerVars) {
         FunctionIdentifier funId = getFunctionIdentifier();
         if (funId == AlgebricksBuiltinFunctions.AND) {
-            for (LogicalExpressionReference a : arguments) {
-                a.getExpression().getConstraintsForOuterJoin(fds, outerVars);
+            for (Mutable<ILogicalExpression> a : arguments) {
+                a.getValue().getConstraintsForOuterJoin(fds, outerVars);
             }
         } else if (funId == AlgebricksBuiltinFunctions.EQ) {
-            ILogicalExpression opLeft = arguments.get(0).getExpression();
-            ILogicalExpression opRight = arguments.get(1).getExpression();
+            ILogicalExpression opLeft = arguments.get(0).getValue();
+            ILogicalExpression opRight = arguments.get(1).getValue();
             if (opLeft.getExpressionTag() == LogicalExpressionTag.VARIABLE
                     && opRight.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 LogicalVariable var1 = ((VariableReferenceExpression) opLeft).getVariableReference();
@@ -196,8 +201,8 @@
             if (!equal)
                 return false;
             for (int i = 0; i < arguments.size(); i++) {
-                ILogicalExpression argument = arguments.get(i).getExpression();
-                ILogicalExpression fceArgument = fce.getArguments().get(i).getExpression();
+                ILogicalExpression argument = arguments.get(i).getValue();
+                ILogicalExpression fceArgument = fce.getArguments().get(i).getValue();
                 if (!argument.equals(fceArgument))
                     return false;
             }
@@ -208,14 +213,14 @@
     @Override
     public int hashCode() {
         int h = finfo.hashCode();
-        for (LogicalExpressionReference e : arguments) {
-            h = h * 41 + e.getExpression().hashCode();
+        for (Mutable<ILogicalExpression> e : arguments) {
+            h = h * 41 + e.getValue().hashCode();
         }
         return h;
     }
 
     @Override
-    public boolean splitIntoConjuncts(List<LogicalExpressionReference> conjs) {
+    public boolean splitIntoConjuncts(List<Mutable<ILogicalExpression>> conjs) {
         if (getFunctionIdentifier() != AlgebricksBuiltinFunctions.AND || arguments.size() <= 1) {
             return false;
         } else {
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/AggregateFunctionCallExpression.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/AggregateFunctionCallExpression.java
index 84a421b..ac77ee2 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/AggregateFunctionCallExpression.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/AggregateFunctionCallExpression.java
@@ -16,7 +16,9 @@
 
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionVisitor;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -47,13 +49,13 @@
     }
 
     public AggregateFunctionCallExpression(IFunctionInfo finfo, boolean isTwoStep,
-            List<LogicalExpressionReference> arguments) {
+            List<Mutable<ILogicalExpression>> arguments) {
         super(FunctionKind.AGGREGATE, finfo, arguments);
         this.twoStep = isTwoStep;
     }
 
     public AggregateFunctionCallExpression(IFunctionInfo finfo, boolean isTwoStep,
-            LogicalExpressionReference... expressions) {
+            Mutable<ILogicalExpression>... expressions) {
         super(FunctionKind.AGGREGATE, finfo, expressions);
         this.twoStep = isTwoStep;
     }
@@ -69,7 +71,7 @@
     @Override
     public AggregateFunctionCallExpression cloneExpression() {
         cloneAnnotations();
-        List<LogicalExpressionReference> clonedArgs = cloneArguments();
+        List<Mutable<ILogicalExpression>> clonedArgs = cloneArguments();
         AggregateFunctionCallExpression fun = new AggregateFunctionCallExpression(finfo, twoStep, clonedArgs);
         fun.setStepTwoAggregate(stepTwoAggregate);
         fun.setStepOneAggregate(stepOneAggregate);
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/ConstantExpression.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/ConstantExpression.java
index 800fee7..2fa0637 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/ConstantExpression.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/ConstantExpression.java
@@ -19,7 +19,9 @@
 import java.util.List;
 import java.util.Map;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionVisitor;
@@ -165,7 +167,7 @@
     }
 
     @Override
-    public boolean splitIntoConjuncts(List<LogicalExpressionReference> conjs) {
+    public boolean splitIntoConjuncts(List<Mutable<ILogicalExpression>> conjs) {
         return false;
     }
 }
\ No newline at end of file
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/ScalarFunctionCallExpression.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/ScalarFunctionCallExpression.java
index 9b1e2dc..fa8838b 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/ScalarFunctionCallExpression.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/ScalarFunctionCallExpression.java
@@ -16,7 +16,9 @@
 
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionVisitor;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -27,18 +29,18 @@
         super(FunctionKind.SCALAR, finfo);
     }
 
-    public ScalarFunctionCallExpression(IFunctionInfo finfo, List<LogicalExpressionReference> arguments) {
+    public ScalarFunctionCallExpression(IFunctionInfo finfo, List<Mutable<ILogicalExpression>> arguments) {
         super(FunctionKind.SCALAR, finfo, arguments);
     }
 
-    public ScalarFunctionCallExpression(IFunctionInfo finfo, LogicalExpressionReference... expressions) {
+    public ScalarFunctionCallExpression(IFunctionInfo finfo, Mutable<ILogicalExpression>... expressions) {
         super(FunctionKind.SCALAR, finfo, expressions);
     }
 
     @Override
     public ScalarFunctionCallExpression cloneExpression() {
         cloneAnnotations();
-        List<LogicalExpressionReference> clonedArgs = cloneArguments();
+        List<Mutable<ILogicalExpression>> clonedArgs = cloneArguments();
         return new ScalarFunctionCallExpression(finfo, clonedArgs);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/StatefulFunctionCallExpression.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/StatefulFunctionCallExpression.java
index 67c3682..c5cd897 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/StatefulFunctionCallExpression.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/StatefulFunctionCallExpression.java
@@ -16,7 +16,9 @@
 
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPropertiesComputer;
@@ -33,13 +35,13 @@
     }
 
     public StatefulFunctionCallExpression(IFunctionInfo finfo, IPropertiesComputer propertiesComputer,
-            List<LogicalExpressionReference> arguments) {
+            List<Mutable<ILogicalExpression>> arguments) {
         super(FunctionKind.STATEFUL, finfo, arguments);
         this.propertiesComputer = propertiesComputer;
     }
 
     public StatefulFunctionCallExpression(IFunctionInfo finfo, IPropertiesComputer propertiesComputer,
-            LogicalExpressionReference... expressions) {
+            Mutable<ILogicalExpression>... expressions) {
         super(FunctionKind.STATEFUL, finfo, expressions);
         this.propertiesComputer = propertiesComputer;
     }
@@ -47,7 +49,7 @@
     @Override
     public StatefulFunctionCallExpression cloneExpression() {
         cloneAnnotations();
-        List<LogicalExpressionReference> clonedArgs = cloneArguments();
+        List<Mutable<ILogicalExpression>> clonedArgs = cloneArguments();
         return new StatefulFunctionCallExpression(finfo, propertiesComputer, clonedArgs);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/UnnestingFunctionCallExpression.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/UnnestingFunctionCallExpression.java
index 25fa964..5f3de4b 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/UnnestingFunctionCallExpression.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/UnnestingFunctionCallExpression.java
@@ -16,7 +16,9 @@
 
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionVisitor;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -29,18 +31,18 @@
         super(FunctionKind.UNNEST, finfo);
     }
 
-    public UnnestingFunctionCallExpression(IFunctionInfo finfo, List<LogicalExpressionReference> arguments) {
+    public UnnestingFunctionCallExpression(IFunctionInfo finfo, List<Mutable<ILogicalExpression>> arguments) {
         super(FunctionKind.UNNEST, finfo, arguments);
     }
 
-    public UnnestingFunctionCallExpression(IFunctionInfo finfo, LogicalExpressionReference... expressions) {
+    public UnnestingFunctionCallExpression(IFunctionInfo finfo, Mutable<ILogicalExpression>... expressions) {
         super(FunctionKind.UNNEST, finfo, expressions);
     }
 
     @Override
     public UnnestingFunctionCallExpression cloneExpression() {
         cloneAnnotations();
-        List<LogicalExpressionReference> clonedArgs = cloneArguments();
+        List<Mutable<ILogicalExpression>> clonedArgs = cloneArguments();
         UnnestingFunctionCallExpression ufce = new UnnestingFunctionCallExpression(finfo, clonedArgs);
         ufce.setReturnsUniqueValues(returnsUniqueValues);
         return ufce;
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/VariableReferenceExpression.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/VariableReferenceExpression.java
index 07d423b..ecd993f 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/VariableReferenceExpression.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/expressions/VariableReferenceExpression.java
@@ -17,7 +17,9 @@
 import java.util.Collection;
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionVisitor;
@@ -87,7 +89,7 @@
     }
 
     @Override
-    public boolean splitIntoConjuncts(List<LogicalExpressionReference> conjs) {
+    public boolean splitIntoConjuncts(List<Mutable<ILogicalExpression>> conjs) {
         return false;
     }
 }
\ No newline at end of file
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractAssignOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractAssignOperator.java
index 438386f..456010a 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractAssignOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractAssignOperator.java
@@ -17,7 +17,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionReferenceTransform;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -28,15 +30,14 @@
  */
 public abstract class AbstractAssignOperator extends AbstractLogicalOperator {
     protected final List<LogicalVariable> variables;
-    protected final List<LogicalExpressionReference> expressions;
+    protected final List<Mutable<ILogicalExpression>> expressions;
 
     public AbstractAssignOperator() {
         this.variables = new ArrayList<LogicalVariable>();
-        this.expressions = new ArrayList<LogicalExpressionReference>();
+        this.expressions = new ArrayList<Mutable<ILogicalExpression>>();
     }
 
-    public AbstractAssignOperator(List<LogicalVariable> variables,
-            List<LogicalExpressionReference> expressions) {
+    public AbstractAssignOperator(List<LogicalVariable> variables, List<Mutable<ILogicalExpression>> expressions) {
         this.variables = variables;
         this.expressions = expressions;
     }
@@ -45,14 +46,14 @@
         return variables;
     }
 
-    public List<LogicalExpressionReference> getExpressions() {
+    public List<Mutable<ILogicalExpression>> getExpressions() {
         return expressions;
     }
 
     @Override
     public void recomputeSchema() {
         schema = new ArrayList<LogicalVariable>();
-        schema.addAll(inputs.get(0).getOperator().getSchema());
+        schema.addAll(inputs.get(0).getValue().getSchema());
         schema.addAll(variables);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractBinaryJoinOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractBinaryJoinOperator.java
index a6eb30f..c2911d4 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractBinaryJoinOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractBinaryJoinOperator.java
@@ -16,34 +16,37 @@
 
 import java.util.ArrayList;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.VariablePropagationPolicy;
 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionReferenceTransform;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 
 public abstract class AbstractBinaryJoinOperator extends AbstractLogicalOperator {
-    protected final LogicalExpressionReference condition;
+    protected final Mutable<ILogicalExpression> condition;
     protected JoinKind joinKind;
 
     public enum JoinKind {
-        INNER, LEFT_OUTER
+        INNER,
+        LEFT_OUTER
     }
 
-    public AbstractBinaryJoinOperator(JoinKind joinKind, LogicalExpressionReference condition) {
+    public AbstractBinaryJoinOperator(JoinKind joinKind, Mutable<ILogicalExpression> condition) {
         this.joinKind = joinKind;
         this.condition = condition;
     }
 
-    public AbstractBinaryJoinOperator(JoinKind joinKind, LogicalExpressionReference condition, LogicalOperatorReference input1,
-            LogicalOperatorReference input2) {
+    public AbstractBinaryJoinOperator(JoinKind joinKind, Mutable<ILogicalExpression> condition,
+            Mutable<ILogicalOperator> input1, Mutable<ILogicalOperator> input2) {
         this(joinKind, condition);
         inputs.add(input1);
         inputs.add(input2);
     }
 
-    public LogicalExpressionReference getCondition() {
+    public Mutable<ILogicalExpression> getCondition() {
         return condition;
     }
 
@@ -54,8 +57,8 @@
     @Override
     public void recomputeSchema() {
         schema = new ArrayList<LogicalVariable>();
-        schema.addAll(inputs.get(0).getOperator().getSchema());
-        schema.addAll(inputs.get(1).getOperator().getSchema());
+        schema.addAll(inputs.get(0).getValue().getSchema());
+        schema.addAll(inputs.get(1).getValue().getSchema());
     }
 
     @Override
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
index 9b1931d..88fd0d5 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
@@ -19,11 +19,12 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IPhysicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -60,12 +61,12 @@
     private boolean bJobGenEnabled = true;
     private Object hostQueryContext;
 
-    final protected List<LogicalOperatorReference> inputs;
+    final protected List<Mutable<ILogicalOperator>> inputs;
     // protected List<LogicalOperatorReference> outputs;
     protected List<LogicalVariable> schema;
 
     public AbstractLogicalOperator() {
-        inputs = new ArrayList<LogicalOperatorReference>();
+        inputs = new ArrayList<Mutable<ILogicalOperator>>();
         // outputs = new ArrayList<LogicalOperatorReference>();
     }
 
@@ -118,7 +119,7 @@
     }
 
     @Override
-    public final List<LogicalOperatorReference> getInputs() {
+    public final List<Mutable<ILogicalOperator>> getInputs() {
         return inputs;
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractOperatorWithNestedPlans.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractOperatorWithNestedPlans.java
index ec4e6ef..ea4f3e0 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractOperatorWithNestedPlans.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractOperatorWithNestedPlans.java
@@ -19,8 +19,10 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 
 public abstract class AbstractOperatorWithNestedPlans extends AbstractLogicalOperator {
@@ -43,10 +45,10 @@
         return true;
     }
 
-    public LinkedList<LogicalOperatorReference> allRootsInReverseOrder() {
-        LinkedList<LogicalOperatorReference> allRoots = new LinkedList<LogicalOperatorReference>();
+    public LinkedList<Mutable<ILogicalOperator>> allRootsInReverseOrder() {
+        LinkedList<Mutable<ILogicalOperator>> allRoots = new LinkedList<Mutable<ILogicalOperator>>();
         for (ILogicalPlan p : nestedPlans) {
-            for (LogicalOperatorReference r : p.getRoots()) {
+            for (Mutable<ILogicalOperator> r : p.getRoots()) {
                 allRoots.addFirst(r);
             }
         }
@@ -68,10 +70,10 @@
     @Override
     public void recomputeSchema() {
         schema = new ArrayList<LogicalVariable>();
-        schema.addAll(inputs.get(0).getOperator().getSchema());
+        schema.addAll(inputs.get(0).getValue().getSchema());
         for (ILogicalPlan p : nestedPlans) {
-            for (LogicalOperatorReference r : p.getRoots()) {
-                schema.addAll(r.getOperator().getSchema());
+            for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                schema.addAll(r.getValue().getSchema());
             }
         }
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractScanOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractScanOperator.java
index e5132ef..e4e7ec8 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractScanOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractScanOperator.java
@@ -39,7 +39,7 @@
     @Override
     public void recomputeSchema() {
         schema = new ArrayList<LogicalVariable>();
-        schema.addAll(inputs.get(0).getOperator().getSchema());
+        schema.addAll(inputs.get(0).getValue().getSchema());
         schema.addAll(variables);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractUnnestOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractUnnestOperator.java
index 020d83c..22f73ff 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractUnnestOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AbstractUnnestOperator.java
@@ -16,21 +16,23 @@
 
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionReferenceTransform;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 
 public abstract class AbstractUnnestOperator extends AbstractScanOperator {
 
-    protected final LogicalExpressionReference expression;
+    protected final Mutable<ILogicalExpression> expression;
 
-    public AbstractUnnestOperator(List<LogicalVariable> variables, LogicalExpressionReference expression) {
+    public AbstractUnnestOperator(List<LogicalVariable> variables, Mutable<ILogicalExpression> expression) {
         super(variables);
         this.expression = expression;
     }
 
-    public LogicalExpressionReference getExpressionRef() {
+    public Mutable<ILogicalExpression> getExpressionRef() {
         return expression;
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AggregateOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AggregateOperator.java
index ba7c970..1555a76 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AggregateOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AggregateOperator.java
@@ -3,7 +3,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -17,9 +19,9 @@
 
     // private ArrayList<AggregateFunctionCallExpression> expressions;
     // TODO type safe list of expressions
-    private List<LogicalExpressionReference> mergeExpressions;
+    private List<Mutable<ILogicalExpression>> mergeExpressions;
 
-    public AggregateOperator(List<LogicalVariable> variables, List<LogicalExpressionReference> expressions) {
+    public AggregateOperator(List<LogicalVariable> variables, List<Mutable<ILogicalExpression>> expressions) {
         super(variables, expressions);
     }
 
@@ -58,23 +60,23 @@
         schema.addAll(variables);
     }
 
-    public void setMergeExpressions(List<LogicalExpressionReference> merges) {
+    public void setMergeExpressions(List<Mutable<ILogicalExpression>> merges) {
         mergeExpressions = merges;
     }
 
-    public List<LogicalExpressionReference> getMergeExpressions() {
+    public List<Mutable<ILogicalExpression>> getMergeExpressions() {
         return mergeExpressions;
     }
 
     @Override
     public IVariableTypeEnvironment computeOutputTypeEnvironment(ITypingContext ctx) throws AlgebricksException {
-        IVariableTypeEnvironment env = new NonPropagatingTypeEnvironment(ctx.getExpressionTypeComputer(), ctx
-                .getMetadataProvider());
-        IVariableTypeEnvironment env2 = ctx.getOutputTypeEnvironment(inputs.get(0).getOperator());
+        IVariableTypeEnvironment env = new NonPropagatingTypeEnvironment(ctx.getExpressionTypeComputer(),
+                ctx.getMetadataProvider());
+        IVariableTypeEnvironment env2 = ctx.getOutputTypeEnvironment(inputs.get(0).getValue());
         int n = variables.size();
         for (int i = 0; i < n; i++) {
-            Object t = ctx.getExpressionTypeComputer().getType(expressions.get(i).getExpression(), ctx.getMetadataProvider(),
-                    env2);
+            Object t = ctx.getExpressionTypeComputer().getType(expressions.get(i).getValue(),
+                    ctx.getMetadataProvider(), env2);
             env.setVarType(variables.get(i), t);
         }
         return env;
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AssignOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AssignOperator.java
index db57c4b..eedd3a2 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AssignOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/AssignOperator.java
@@ -16,7 +16,9 @@
 
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -35,11 +37,11 @@
 
 public class AssignOperator extends AbstractAssignOperator {
 
-    public AssignOperator(List<LogicalVariable> vars, List<LogicalExpressionReference> exprs) {
+    public AssignOperator(List<LogicalVariable> vars, List<Mutable<ILogicalExpression>> exprs) {
         super(vars, exprs);
     }
 
-    public AssignOperator(LogicalVariable var, LogicalExpressionReference expr) {
+    public AssignOperator(LogicalVariable var, Mutable<ILogicalExpression> expr) {
         super();
         this.variables.add(var);
         this.expressions.add(expr);
@@ -81,8 +83,10 @@
         IVariableTypeEnvironment env = createPropagatingAllInputsTypeEnvironment(ctx);
         int n = variables.size();
         for (int i = 0; i < n; i++) {
-            env.setVarType(variables.get(i), ctx.getExpressionTypeComputer().getType(
-                    expressions.get(i).getExpression(), ctx.getMetadataProvider(), env));
+            env.setVarType(
+                    variables.get(i),
+                    ctx.getExpressionTypeComputer().getType(expressions.get(i).getValue(), ctx.getMetadataProvider(),
+                            env));
         }
         return env;
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/DieOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/DieOperator.java
index fe22219..2e330cf 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/DieOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/DieOperator.java
@@ -16,8 +16,10 @@
 
 import java.util.ArrayList;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -29,20 +31,20 @@
 
 public class DieOperator extends AbstractLogicalOperator {
 
-    private final LogicalExpressionReference afterObjects; // mandatory
+    private final Mutable<ILogicalExpression> afterObjects; // mandatory
 
     public DieOperator(ILogicalExpression maxObjectsExpr) {
-        this.afterObjects = new LogicalExpressionReference(maxObjectsExpr);
+        this.afterObjects = new MutableObject<ILogicalExpression>(maxObjectsExpr);
     }
 
-    public LogicalExpressionReference getAfterObjects() {
+    public Mutable<ILogicalExpression> getAfterObjects() {
         return afterObjects;
     }
 
     @Override
     public void recomputeSchema() {
         schema = new ArrayList<LogicalVariable>();
-        schema.addAll(inputs.get(0).getOperator().getSchema());
+        schema.addAll(inputs.get(0).getValue().getSchema());
     }
 
     @Override
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/DistinctOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/DistinctOperator.java
index 593e505..4d479e1 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/DistinctOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/DistinctOperator.java
@@ -17,8 +17,9 @@
 import java.util.ArrayList;

 import java.util.List;

 

+import org.apache.commons.lang3.mutable.Mutable;

+

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

@@ -31,9 +32,9 @@
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;

 

 public class DistinctOperator extends AbstractLogicalOperator {

-    private final List<LogicalExpressionReference> expressions;

+    private final List<Mutable<ILogicalExpression>> expressions;

 

-    public DistinctOperator(List<LogicalExpressionReference> expressions) {

+    public DistinctOperator(List<Mutable<ILogicalExpression>> expressions) {

         this.expressions = expressions;

     }

 

@@ -42,13 +43,13 @@
         return LogicalOperatorTag.DISTINCT;

     }

 

-    public List<LogicalExpressionReference> getExpressions() {

+    public List<Mutable<ILogicalExpression>> getExpressions() {

         return expressions;

     }

 

     @Override

     public void recomputeSchema() {

-        schema = new ArrayList<LogicalVariable>(inputs.get(0).getOperator().getSchema());

+        schema = new ArrayList<LogicalVariable>(inputs.get(0).getValue().getSchema());

     }

 

     @Override

@@ -59,7 +60,7 @@
     @Override

     public boolean acceptExpressionTransform(ILogicalExpressionReferenceTransform visitor) throws AlgebricksException {

         boolean changed = false;

-        for (LogicalExpressionReference e : expressions) {

+        for (Mutable<ILogicalExpression> e : expressions) {

             if (visitor.transform(e)) {

                 changed = true;

             }

@@ -79,8 +80,8 @@
 

     public List<LogicalVariable> getDistinctByVarList() {

         List<LogicalVariable> varList = new ArrayList<LogicalVariable>(expressions.size());

-        for (LogicalExpressionReference eRef : expressions) {

-            ILogicalExpression e = eRef.getExpression();

+        for (Mutable<ILogicalExpression> eRef : expressions) {

+            ILogicalExpression e = eRef.getValue();

             if (e.getExpressionTag() == LogicalExpressionTag.VARIABLE) {

                 VariableReferenceExpression v = (VariableReferenceExpression) e;

                 varList.add(v.getVariableReference());

@@ -90,8 +91,8 @@
     }

 

     public boolean isDistinctByVar(LogicalVariable var) {

-        for (LogicalExpressionReference eRef : expressions) {

-            ILogicalExpression e = eRef.getExpression();

+        for (Mutable<ILogicalExpression> eRef : expressions) {

+            ILogicalExpression e = eRef.getValue();

             if (e.getExpressionTag() == LogicalExpressionTag.VARIABLE) {

                 VariableReferenceExpression v = (VariableReferenceExpression) e;

                 if (v.getVariableReference() == var) {

diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/ExchangeOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/ExchangeOperator.java
index f0899c9..3e046b5 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/ExchangeOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/ExchangeOperator.java
@@ -52,9 +52,9 @@
 
     @Override
     public void recomputeSchema() throws AlgebricksException {
-        AbstractLogicalOperator cld = (AbstractLogicalOperator) inputs.get(0).getOperator();
+        AbstractLogicalOperator cld = (AbstractLogicalOperator) inputs.get(0).getValue();
         OperatorPropertiesUtil.computeSchemaRecIfNull(cld);
-        List<LogicalVariable> inputSchema = inputs.get(0).getOperator().getSchema();
+        List<LogicalVariable> inputSchema = inputs.get(0).getValue().getSchema();
         schema = new ArrayList<LogicalVariable>(inputSchema);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/GroupByOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/GroupByOperator.java
index 9bc37d4..762f034 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/GroupByOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/GroupByOperator.java
@@ -18,12 +18,13 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -42,33 +43,33 @@
 public class GroupByOperator extends AbstractOperatorWithNestedPlans {
     // If the LogicalVariable in a pair is null, it means that the GroupBy is
     // only grouping by the expression, without producing a new variable.
-    private final List<Pair<LogicalVariable, LogicalExpressionReference>> gByList;
-    private final List<Pair<LogicalVariable, LogicalExpressionReference>> decorList;
+    private final List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> gByList;
+    private final List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorList;
 
     // In decorList, if the variable (first member of the pair) is null, the
     // second member of the pair is variable reference which is propagated.
 
     public GroupByOperator() {
         super();
-        gByList = new ArrayList<Pair<LogicalVariable, LogicalExpressionReference>>();
-        decorList = new ArrayList<Pair<LogicalVariable, LogicalExpressionReference>>();
+        gByList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
+        decorList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
     }
 
-    public GroupByOperator(List<Pair<LogicalVariable, LogicalExpressionReference>> groupByList,
-            List<Pair<LogicalVariable, LogicalExpressionReference>> decorList, List<ILogicalPlan> nestedPlans) {
+    public GroupByOperator(List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByList,
+            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorList, List<ILogicalPlan> nestedPlans) {
         super(nestedPlans);
         this.decorList = decorList;
         this.gByList = groupByList;
     }
 
     public void addGbyExpression(LogicalVariable variable, ILogicalExpression expression) {
-        this.gByList.add(new Pair<LogicalVariable, LogicalExpressionReference>(variable,
-                new LogicalExpressionReference(expression)));
+        this.gByList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(variable,
+                new MutableObject<ILogicalExpression>(expression)));
     }
 
     public void addDecorExpression(LogicalVariable variable, ILogicalExpression expression) {
-        this.decorList.add(new Pair<LogicalVariable, LogicalExpressionReference>(variable,
-                new LogicalExpressionReference(expression)));
+        this.decorList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(variable,
+                new MutableObject<ILogicalExpression>(expression)));
     }
 
     @Override
@@ -76,7 +77,7 @@
         return LogicalOperatorTag.GROUP;
     }
 
-    public List<Pair<LogicalVariable, LogicalExpressionReference>> getGroupByList() {
+    public List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> getGroupByList() {
         return gByList;
     }
 
@@ -90,8 +91,8 @@
 
     public List<LogicalVariable> getGbyVarList() {
         List<LogicalVariable> varList = new ArrayList<LogicalVariable>(gByList.size());
-        for (Pair<LogicalVariable, LogicalExpressionReference> ve : gByList) {
-            ILogicalExpression expr = ve.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> ve : gByList) {
+            ILogicalExpression expr = ve.second.getValue();
             if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 VariableReferenceExpression v = (VariableReferenceExpression) expr;
                 varList.add(v.getVariableReference());
@@ -100,11 +101,11 @@
         return varList;
     }
 
-    public static String veListToString(List<Pair<LogicalVariable, LogicalExpressionReference>> vePairList) {
+    public static String veListToString(List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> vePairList) {
         StringBuilder sb = new StringBuilder();
         sb.append("[");
         boolean fst = true;
-        for (Pair<LogicalVariable, LogicalExpressionReference> ve : vePairList) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> ve : vePairList) {
             if (fst) {
                 fst = false;
             } else {
@@ -113,7 +114,7 @@
             if (ve.first != null) {
                 sb.append(ve.first + " := " + ve.second);
             } else {
-                sb.append(ve.second.getExpression());
+                sb.append(ve.second.getValue());
             }
         }
         sb.append("]");
@@ -123,10 +124,10 @@
     @Override
     public void recomputeSchema() {
         super.recomputeSchema();
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gByList) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gByList) {
             schema.add(p.first);
         }
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : decorList) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : decorList) {
             schema.add(getDecorVariable(p));
         }
     }
@@ -134,12 +135,12 @@
     @Override
     public void getProducedVariablesExceptNestedPlans(Collection<LogicalVariable> vars) {
         // super.getProducedVariables(vars);
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gByList) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gByList) {
             if (p.first != null) {
                 vars.add(p.first);
             }
         }
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : decorList) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : decorList) {
             if (p.first != null) {
                 vars.add(p.first);
             }
@@ -148,11 +149,11 @@
 
     @Override
     public void getUsedVariablesExceptNestedPlans(Collection<LogicalVariable> vars) {
-        for (Pair<LogicalVariable, LogicalExpressionReference> g : gByList) {
-            g.second.getExpression().getUsedVariables(vars);
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> g : gByList) {
+            g.second.getValue().getUsedVariables(vars);
         }
-        for (Pair<LogicalVariable, LogicalExpressionReference> g : decorList) {
-            g.second.getExpression().getUsedVariables(vars);
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> g : decorList) {
+            g.second.getValue().getUsedVariables(vars);
         }
         // super.getUsedVariables(vars);
     }
@@ -164,8 +165,8 @@
             @Override
             public void propagateVariables(IOperatorSchema target, IOperatorSchema... sources)
                     throws AlgebricksException {
-                for (Pair<LogicalVariable, LogicalExpressionReference> p : gByList) {
-                    ILogicalExpression expr = p.second.getExpression();
+                for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gByList) {
+                    ILogicalExpression expr = p.second.getValue();
                     if (p.first != null) {
                         target.addVariable(p.first);
                     } else {
@@ -176,8 +177,8 @@
                         target.addVariable(v.getVariableReference());
                     }
                 }
-                for (Pair<LogicalVariable, LogicalExpressionReference> p : decorList) {
-                    ILogicalExpression expr = p.second.getExpression();
+                for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : decorList) {
+                    ILogicalExpression expr = p.second.getValue();
                     if (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                         throw new AlgebricksException("pre-sorted group-by expects variable references.");
                     }
@@ -197,12 +198,12 @@
     @Override
     public boolean acceptExpressionTransform(ILogicalExpressionReferenceTransform visitor) throws AlgebricksException {
         boolean b = false;
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gByList) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gByList) {
             if (visitor.transform(p.second)) {
                 b = true;
             }
         }
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : decorList) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : decorList) {
             if (visitor.transform(p.second)) {
                 b = true;
             }
@@ -215,16 +216,16 @@
         return visitor.visitGroupByOperator(this, arg);
     }
 
-    public static LogicalVariable getDecorVariable(Pair<LogicalVariable, LogicalExpressionReference> p) {
+    public static LogicalVariable getDecorVariable(Pair<LogicalVariable, Mutable<ILogicalExpression>> p) {
         if (p.first != null) {
             return p.first;
         } else {
-            VariableReferenceExpression e = (VariableReferenceExpression) p.second.getExpression();
+            VariableReferenceExpression e = (VariableReferenceExpression) p.second.getValue();
             return e.getVariableReference();
         }
     }
 
-    public List<Pair<LogicalVariable, LogicalExpressionReference>> getDecorList() {
+    public List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> getDecorList() {
         return decorList;
     }
 
@@ -237,17 +238,17 @@
         ITypeEnvPointer[] envPointers = new ITypeEnvPointer[n];
         int i = 0;
         for (ILogicalPlan p : nestedPlans) {
-            for (LogicalOperatorReference r : p.getRoots()) {
+            for (Mutable<ILogicalOperator> r : p.getRoots()) {
                 envPointers[i] = new OpRefTypeEnvPointer(r, ctx);
                 i++;
             }
         }
-        IVariableTypeEnvironment env = new PropagatingTypeEnvironment(ctx.getExpressionTypeComputer(), ctx
-                .getNullableTypeComputer(), ctx.getMetadataProvider(), TypePropagationPolicy.ALL, envPointers);
-        ILogicalOperator child = inputs.get(0).getOperator();
+        IVariableTypeEnvironment env = new PropagatingTypeEnvironment(ctx.getExpressionTypeComputer(),
+                ctx.getNullableTypeComputer(), ctx.getMetadataProvider(), TypePropagationPolicy.ALL, envPointers);
+        ILogicalOperator child = inputs.get(0).getValue();
         IVariableTypeEnvironment env2 = ctx.getOutputTypeEnvironment(child);
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : getGroupByList()) {
-            ILogicalExpression expr = p.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : getGroupByList()) {
+            ILogicalExpression expr = p.second.getValue();
             if (p.first != null) {
                 env.setVarType(p.first, env2.getType(expr));
                 if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
@@ -255,17 +256,17 @@
                     env.setVarType(v1, env2.getVarType(v1));
                 }
             } else {
-                VariableReferenceExpression vre = (VariableReferenceExpression) p.second.getExpression();
+                VariableReferenceExpression vre = (VariableReferenceExpression) p.second.getValue();
                 LogicalVariable v2 = vre.getVariableReference();
                 env.setVarType(v2, env2.getVarType(v2));
             }
         }
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : getDecorList()) {
-            ILogicalExpression expr = p.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : getDecorList()) {
+            ILogicalExpression expr = p.second.getValue();
             if (p.first != null) {
                 env.setVarType(p.first, env2.getType(expr));
             } else {
-                VariableReferenceExpression vre = (VariableReferenceExpression) p.second.getExpression();
+                VariableReferenceExpression vre = (VariableReferenceExpression) p.second.getValue();
                 LogicalVariable v2 = vre.getVariableReference();
                 env.setVarType(v2, env2.getVarType(v2));
             }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/IndexInsertDeleteOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/IndexInsertDeleteOperator.java
index ca032a2..7264763 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/IndexInsertDeleteOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/IndexInsertDeleteOperator.java
@@ -3,7 +3,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -18,12 +20,12 @@
 public class IndexInsertDeleteOperator extends AbstractLogicalOperator {
 
     private final IDataSourceIndex<?, ?> dataSourceIndex;
-    private final List<LogicalExpressionReference> primaryKeyExprs;
-    private final List<LogicalExpressionReference> secondaryKeyExprs;
+    private final List<Mutable<ILogicalExpression>> primaryKeyExprs;
+    private final List<Mutable<ILogicalExpression>> secondaryKeyExprs;
     private final Kind operation;
 
     public IndexInsertDeleteOperator(IDataSourceIndex<?, ?> dataSourceIndex,
-            List<LogicalExpressionReference> primaryKeyExprs, List<LogicalExpressionReference> secondaryKeyExprs,
+            List<Mutable<ILogicalExpression>> primaryKeyExprs, List<Mutable<ILogicalExpression>> secondaryKeyExprs,
             Kind operation) {
         this.dataSourceIndex = dataSourceIndex;
         this.primaryKeyExprs = primaryKeyExprs;
@@ -34,7 +36,7 @@
     @Override
     public void recomputeSchema() throws AlgebricksException {
         schema = new ArrayList<LogicalVariable>();
-        schema.addAll(inputs.get(0).getOperator().getSchema());
+        schema.addAll(inputs.get(0).getValue().getSchema());
     }
 
     @Override
@@ -78,7 +80,7 @@
         return createPropagatingAllInputsTypeEnvironment(ctx);
     }
 
-    public List<LogicalExpressionReference> getPrimaryKeyExpressions() {
+    public List<Mutable<ILogicalExpression>> getPrimaryKeyExpressions() {
         return primaryKeyExprs;
     }
 
@@ -86,7 +88,7 @@
         return dataSourceIndex;
     }
 
-    public List<LogicalExpressionReference> getSecondaryKeyExpressions() {
+    public List<Mutable<ILogicalExpression>> getSecondaryKeyExpressions() {
         return secondaryKeyExprs;
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/InnerJoinOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/InnerJoinOperator.java
index e9d8c2c..c2f0161 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/InnerJoinOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/InnerJoinOperator.java
@@ -14,8 +14,10 @@
  */
 package edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
 import edu.uci.ics.hyracks.algebricks.core.algebra.typing.ITypingContext;
@@ -24,12 +26,12 @@
 
 public class InnerJoinOperator extends AbstractBinaryJoinOperator {
 
-    public InnerJoinOperator(LogicalExpressionReference condition) {
+    public InnerJoinOperator(Mutable<ILogicalExpression> condition) {
         super(JoinKind.INNER, condition);
     }
 
-    public InnerJoinOperator(LogicalExpressionReference condition, LogicalOperatorReference input1,
-            LogicalOperatorReference input2) {
+    public InnerJoinOperator(Mutable<ILogicalExpression> condition, Mutable<ILogicalOperator> input1,
+            Mutable<ILogicalOperator> input2) {
         super(JoinKind.INNER, condition, input1, input2);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/InsertDeleteOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/InsertDeleteOperator.java
index be69e96..6699228 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/InsertDeleteOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/InsertDeleteOperator.java
@@ -3,7 +3,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -17,16 +19,17 @@
 public class InsertDeleteOperator extends AbstractLogicalOperator {
 
     public enum Kind {
-        INSERT, DELETE
+        INSERT,
+        DELETE
     }
 
     private final IDataSource<?> dataSource;
-    private final LogicalExpressionReference payloadExpr;
-    private final List<LogicalExpressionReference> primaryKeyExprs;
+    private final Mutable<ILogicalExpression> payloadExpr;
+    private final List<Mutable<ILogicalExpression>> primaryKeyExprs;
     private final Kind operation;
 
-    public InsertDeleteOperator(IDataSource<?> dataSource, LogicalExpressionReference payload,
-            List<LogicalExpressionReference> primaryKeyExprs, Kind operation) {
+    public InsertDeleteOperator(IDataSource<?> dataSource, Mutable<ILogicalExpression> payload,
+            List<Mutable<ILogicalExpression>> primaryKeyExprs, Kind operation) {
         this.dataSource = dataSource;
         this.payloadExpr = payload;
         this.primaryKeyExprs = primaryKeyExprs;
@@ -36,7 +39,7 @@
     @Override
     public void recomputeSchema() throws AlgebricksException {
         schema = new ArrayList<LogicalVariable>();
-        schema.addAll(inputs.get(0).getOperator().getSchema());
+        schema.addAll(inputs.get(0).getValue().getSchema());
     }
 
     @Override
@@ -76,7 +79,7 @@
         return createPropagatingAllInputsTypeEnvironment(ctx);
     }
 
-    public List<LogicalExpressionReference> getPrimaryKeyExpressions() {
+    public List<Mutable<ILogicalExpression>> getPrimaryKeyExpressions() {
         return primaryKeyExprs;
     }
 
@@ -84,7 +87,7 @@
         return dataSource;
     }
 
-    public LogicalExpressionReference getPayloadExpression() {
+    public Mutable<ILogicalExpression> getPayloadExpression() {
         return payloadExpr;
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/LeftOuterJoinOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/LeftOuterJoinOperator.java
index 8166b1b..7c5be7e 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/LeftOuterJoinOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/LeftOuterJoinOperator.java
@@ -14,8 +14,10 @@
  */
 package edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.TypePropagationPolicy;
@@ -28,12 +30,12 @@
 
 public class LeftOuterJoinOperator extends AbstractBinaryJoinOperator {
 
-    public LeftOuterJoinOperator(LogicalExpressionReference condition) {
+    public LeftOuterJoinOperator(Mutable<ILogicalExpression> condition) {
         super(JoinKind.LEFT_OUTER, condition);
     }
 
-    public LeftOuterJoinOperator(LogicalExpressionReference condition, LogicalOperatorReference input1,
-            LogicalOperatorReference input2) {
+    public LeftOuterJoinOperator(Mutable<ILogicalExpression> condition, Mutable<ILogicalOperator> input1,
+            Mutable<ILogicalOperator> input2) {
         super(JoinKind.LEFT_OUTER, condition, input1, input2);
     }
 
@@ -54,8 +56,8 @@
         for (int i = 0; i < n; i++) {
             envPointers[i] = new OpRefTypeEnvPointer(inputs.get(i), ctx);
         }
-        return new PropagatingTypeEnvironment(ctx.getExpressionTypeComputer(), ctx.getNullableTypeComputer(), ctx
-                .getMetadataProvider(), TypePropagationPolicy.LEFT_OUTER, envPointers);
+        return new PropagatingTypeEnvironment(ctx.getExpressionTypeComputer(), ctx.getNullableTypeComputer(),
+                ctx.getMetadataProvider(), TypePropagationPolicy.LEFT_OUTER, envPointers);
     }
 
 }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/LimitOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/LimitOperator.java
index 5fedfdc..21738f6 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/LimitOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/LimitOperator.java
@@ -16,8 +16,10 @@
 
 import java.util.ArrayList;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -29,13 +31,13 @@
 
 public class LimitOperator extends AbstractLogicalOperator {
 
-    private final LogicalExpressionReference maxObjects; // mandatory
-    private final LogicalExpressionReference offset; // optional
+    private final Mutable<ILogicalExpression> maxObjects; // mandatory
+    private final Mutable<ILogicalExpression> offset; // optional
     private boolean topmost;
 
     public LimitOperator(ILogicalExpression maxObjectsExpr, ILogicalExpression offsetExpr, boolean topmost) {
-        this.maxObjects = new LogicalExpressionReference(maxObjectsExpr);
-        this.offset = new LogicalExpressionReference(offsetExpr);
+        this.maxObjects = new MutableObject<ILogicalExpression>(maxObjectsExpr);
+        this.offset = new MutableObject<ILogicalExpression>(offsetExpr);
         this.topmost = topmost;
     }
 
@@ -51,11 +53,11 @@
         this(maxObjects, null, true);
     }
 
-    public LogicalExpressionReference getMaxObjects() {
+    public Mutable<ILogicalExpression> getMaxObjects() {
         return maxObjects;
     }
 
-    public LogicalExpressionReference getOffset() {
+    public Mutable<ILogicalExpression> getOffset() {
         return offset;
     }
 
@@ -66,7 +68,7 @@
     @Override
     public void recomputeSchema() {
         schema = new ArrayList<LogicalVariable>();
-        schema.addAll(inputs.get(0).getOperator().getSchema());
+        schema.addAll(inputs.get(0).getValue().getSchema());
     }
 
     @Override
@@ -80,7 +82,7 @@
         if (visitor.transform(maxObjects)) {
             b = true;
         }
-        if (offset.getExpression() != null) {
+        if (offset.getValue() != null) {
             if (visitor.transform(offset)) {
                 b = true;
             }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
index fc17ce4..189a410 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
@@ -16,8 +16,9 @@
 
 import java.util.ArrayList;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -31,14 +32,14 @@
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 
 public class NestedTupleSourceOperator extends AbstractLogicalOperator {
-    private final LogicalOperatorReference dataSourceReference;
+    private final Mutable<ILogicalOperator> dataSourceReference;
 
-    public NestedTupleSourceOperator(LogicalOperatorReference dataSourceReference) {
+    public NestedTupleSourceOperator(Mutable<ILogicalOperator> dataSourceReference) {
         this.dataSourceReference = dataSourceReference;
     }
 
     public ILogicalOperator getSourceOperator() {
-        return dataSourceReference.getOperator().getInputs().get(0).getOperator();
+        return dataSourceReference.getValue().getInputs().get(0).getValue();
     }
 
     @Override
@@ -46,16 +47,16 @@
         return LogicalOperatorTag.NESTEDTUPLESOURCE;
     }
 
-    public LogicalOperatorReference getDataSourceReference() {
+    public Mutable<ILogicalOperator> getDataSourceReference() {
         return dataSourceReference;
     }
 
     @Override
     public void recomputeSchema() {
         schema = new ArrayList<LogicalVariable>();
-        ILogicalOperator topOp = dataSourceReference.getOperator();
-        for (LogicalOperatorReference i : topOp.getInputs()) {
-            schema.addAll(i.getOperator().getSchema());
+        ILogicalOperator topOp = dataSourceReference.getValue();
+        for (Mutable<ILogicalOperator> i : topOp.getInputs()) {
+            schema.addAll(i.getValue().getSchema());
         }
     }
 
@@ -87,7 +88,7 @@
 
             @Override
             public IVariableTypeEnvironment getTypeEnv() {
-                ILogicalOperator op = dataSourceReference.getOperator().getInputs().get(0).getOperator();
+                ILogicalOperator op = dataSourceReference.getValue().getInputs().get(0).getValue();
                 return ctx.getOutputTypeEnvironment(op);
             }
         };
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/OrderOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/OrderOperator.java
index 9c3cef5..3a5cdde 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/OrderOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/OrderOperator.java
@@ -17,7 +17,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -38,7 +40,7 @@
             DESC
         };
 
-        public LogicalExpressionReference getExpressionRef();
+        public Mutable<ILogicalExpression> getExpressionRef();
 
         public OrderKind getKind();
     }
@@ -46,7 +48,7 @@
     public static IOrder ASC_ORDER = new IOrder() {
 
         @Override
-        public LogicalExpressionReference getExpressionRef() {
+        public Mutable<ILogicalExpression> getExpressionRef() {
             return null;
         }
 
@@ -60,7 +62,7 @@
     public static IOrder DESC_ORDER = new IOrder() {
 
         @Override
-        public LogicalExpressionReference getExpressionRef() {
+        public Mutable<ILogicalExpression> getExpressionRef() {
             return null;
         }
 
@@ -71,14 +73,14 @@
     };
 
     public class FunOrder implements IOrder {
-        private final LogicalExpressionReference f;
+        private final Mutable<ILogicalExpression> f;
 
-        public FunOrder(LogicalExpressionReference f) {
+        public FunOrder(Mutable<ILogicalExpression> f) {
             this.f = f;
         }
 
         @Override
-        public LogicalExpressionReference getExpressionRef() {
+        public Mutable<ILogicalExpression> getExpressionRef() {
             return f;
         }
 
@@ -89,17 +91,17 @@
 
     };
 
-    private final List<Pair<IOrder, LogicalExpressionReference>> orderExpressions;
+    private final List<Pair<IOrder, Mutable<ILogicalExpression>>> orderExpressions;
 
     // These are pairs of type (comparison, expr) where comparison is
     // ASC or DESC or a boolean function of arity 2 that can take as
     // arguments results of expr.
 
     public OrderOperator() {
-        orderExpressions = new ArrayList<Pair<IOrder, LogicalExpressionReference>>();
+        orderExpressions = new ArrayList<Pair<IOrder, Mutable<ILogicalExpression>>>();
     }
 
-    public OrderOperator(List<Pair<IOrder, LogicalExpressionReference>> orderExpressions) {
+    public OrderOperator(List<Pair<IOrder, Mutable<ILogicalExpression>>> orderExpressions) {
         this.orderExpressions = orderExpressions;
     }
 
@@ -108,13 +110,13 @@
         return LogicalOperatorTag.ORDER;
     }
 
-    public List<Pair<IOrder, LogicalExpressionReference>> getOrderExpressions() {
+    public List<Pair<IOrder, Mutable<ILogicalExpression>>> getOrderExpressions() {
         return orderExpressions;
     }
 
     @Override
     public void recomputeSchema() {
-        schema = new ArrayList<LogicalVariable>(inputs.get(0).getOperator().getSchema());
+        schema = new ArrayList<LogicalVariable>(inputs.get(0).getValue().getSchema());
     }
 
     @Override
@@ -125,10 +127,10 @@
     @Override
     public boolean acceptExpressionTransform(ILogicalExpressionReferenceTransform visitor) throws AlgebricksException {
         boolean b = false;
-        for (Pair<IOrder, LogicalExpressionReference> p : orderExpressions) {
+        for (Pair<IOrder, Mutable<ILogicalExpression>> p : orderExpressions) {
             if (p.first.getKind() == OrderKind.FUNCTIONCALL) {
                 FunOrder fo = (FunOrder) p.first;
-                LogicalExpressionReference r1 = fo.getExpressionRef();
+                Mutable<ILogicalExpression> r1 = fo.getExpressionRef();
                 if (visitor.transform(r1)) {
                     b = true;
                 }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/PartitioningSplitOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/PartitioningSplitOperator.java
index dc0e4df..a76237b 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/PartitioningSplitOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/PartitioningSplitOperator.java
@@ -16,7 +16,9 @@
 
 import java.util.ArrayList;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -28,15 +30,15 @@
 
 public class PartitioningSplitOperator extends AbstractLogicalOperator {
 
-    private LogicalExpressionReference[] expressions;
+    private Mutable<ILogicalExpression>[] expressions;
     private boolean hasDefault;
 
-    public PartitioningSplitOperator(LogicalExpressionReference[] exprList, boolean defaultBranchDefined) {
+    public PartitioningSplitOperator(Mutable<ILogicalExpression>[] exprList, boolean defaultBranchDefined) {
         expressions = exprList;
         hasDefault = defaultBranchDefined;
     }
 
-    public LogicalExpressionReference[] getExpressions() {
+    public Mutable<ILogicalExpression>[] getExpressions() {
         return expressions;
     }
 
@@ -52,7 +54,7 @@
     @Override
     public void recomputeSchema() {
         schema = new ArrayList<LogicalVariable>();
-        schema.addAll(inputs.get(0).getOperator().getSchema());
+        schema.addAll(inputs.get(0).getValue().getSchema());
     }
 
     @Override
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/ReplicateOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/ReplicateOperator.java
index 0f0c624..f594373 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/ReplicateOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/ReplicateOperator.java
@@ -60,7 +60,7 @@
 
     @Override
     public void recomputeSchema() {
-        schema = new ArrayList<LogicalVariable>(inputs.get(0).getOperator().getSchema());
+        schema = new ArrayList<LogicalVariable>(inputs.get(0).getValue().getSchema());
     }
 
     public void substituteVar(LogicalVariable v1, LogicalVariable v2) {
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/RunningAggregateOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/RunningAggregateOperator.java
index d9be7d4..798597e 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/RunningAggregateOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/RunningAggregateOperator.java
@@ -16,7 +16,9 @@
 
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -27,7 +29,7 @@
 
 public class RunningAggregateOperator extends AbstractAssignOperator {
 
-    public RunningAggregateOperator(List<LogicalVariable> variables, List<LogicalExpressionReference> expressions) {
+    public RunningAggregateOperator(List<LogicalVariable> variables, List<Mutable<ILogicalExpression>> expressions) {
         super(variables, expressions);
     }
 
@@ -68,8 +70,8 @@
         for (int i = 0; i < n; i++) {
             env.setVarType(
                     variables.get(i),
-                    ctx.getExpressionTypeComputer().getType(expressions.get(i).getExpression(),
-                            ctx.getMetadataProvider(), env));
+                    ctx.getExpressionTypeComputer().getType(expressions.get(i).getValue(), ctx.getMetadataProvider(),
+                            env));
         }
         return env;
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SelectOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SelectOperator.java
index 93db0e9..c1e038e 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SelectOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SelectOperator.java
@@ -16,8 +16,9 @@
 
 import java.util.ArrayList;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
@@ -36,9 +37,9 @@
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 
 public class SelectOperator extends AbstractLogicalOperator {
-    private final LogicalExpressionReference condition;
+    private final Mutable<ILogicalExpression> condition;
 
-    public SelectOperator(LogicalExpressionReference condition) {
+    public SelectOperator(Mutable<ILogicalExpression> condition) {
         this.condition = condition;
     }
 
@@ -47,13 +48,13 @@
         return LogicalOperatorTag.SELECT;
     }
 
-    public LogicalExpressionReference getCondition() {
+    public Mutable<ILogicalExpression> getCondition() {
         return condition;
     }
 
     @Override
     public void recomputeSchema() {
-        schema = new ArrayList<LogicalVariable>(inputs.get(0).getOperator().getSchema());
+        schema = new ArrayList<LogicalVariable>(inputs.get(0).getValue().getSchema());
     }
 
     @Override
@@ -82,14 +83,14 @@
         envPointers[0] = new OpRefTypeEnvPointer(inputs.get(0), ctx);
         PropagatingTypeEnvironment env = new PropagatingTypeEnvironment(ctx.getExpressionTypeComputer(),
                 ctx.getNullableTypeComputer(), ctx.getMetadataProvider(), TypePropagationPolicy.ALL, envPointers);
-        if (condition.getExpression().getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
-            AbstractFunctionCallExpression f1 = (AbstractFunctionCallExpression) condition.getExpression();
+        if (condition.getValue().getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+            AbstractFunctionCallExpression f1 = (AbstractFunctionCallExpression) condition.getValue();
             if (f1.getFunctionIdentifier() == AlgebricksBuiltinFunctions.NOT) {
-                ILogicalExpression a1 = f1.getArguments().get(0).getExpression();
+                ILogicalExpression a1 = f1.getArguments().get(0).getValue();
                 if (a1.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
                     AbstractFunctionCallExpression f2 = (AbstractFunctionCallExpression) a1;
                     if (f2.getFunctionIdentifier() == AlgebricksBuiltinFunctions.IS_NULL) {
-                        ILogicalExpression a2 = f2.getArguments().get(0).getExpression();
+                        ILogicalExpression a2 = f2.getArguments().get(0).getValue();
                         if (a2.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                             LogicalVariable var = ((VariableReferenceExpression) a2).getVariableReference();
                             env.getNonNullVariables().add(var);
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SinkOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SinkOperator.java
index a40df28..a75a9a9 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SinkOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SinkOperator.java
@@ -19,7 +19,7 @@
 
     @Override
     public void recomputeSchema() throws AlgebricksException {
-        schema = new ArrayList<LogicalVariable>(inputs.get(0).getOperator().getSchema());
+        schema = new ArrayList<LogicalVariable>(inputs.get(0).getValue().getSchema());
     }
 
     @Override
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SubplanOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SubplanOperator.java
index a60d58d..0d1704b 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SubplanOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/SubplanOperator.java
@@ -18,9 +18,11 @@
 import java.util.Collection;

 import java.util.List;

 

+import org.apache.commons.lang3.mutable.Mutable;

+import org.apache.commons.lang3.mutable.MutableObject;

+

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;

@@ -46,12 +48,12 @@
     }

 

     public SubplanOperator(ILogicalOperator planRoot) {

-        ArrayList<LogicalOperatorReference> roots = new ArrayList<LogicalOperatorReference>(1);

-        roots.add(new LogicalOperatorReference(planRoot));

+        ArrayList<Mutable<ILogicalOperator>> roots = new ArrayList<Mutable<ILogicalOperator>>(1);

+        roots.add(new MutableObject<ILogicalOperator>(planRoot));

         nestedPlans.add(new ALogicalPlanImpl(roots));

     }

 

-    public void setRootOp(LogicalOperatorReference opRef) {

+    public void setRootOp(Mutable<ILogicalOperator> opRef) {

         ILogicalPlan p = new ALogicalPlanImpl(opRef);

         nestedPlans.add(p);

     }

@@ -97,7 +99,7 @@
         envPointers[0] = new OpRefTypeEnvPointer(inputs.get(0), ctx);

         int i = 1;

         for (ILogicalPlan p : nestedPlans) {

-            for (LogicalOperatorReference r : p.getRoots()) {

+            for (Mutable<ILogicalOperator> r : p.getRoots()) {

                 envPointers[i] = new OpRefTypeEnvPointer(r, ctx);

                 i++;

             }

diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnionAllOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnionAllOperator.java
index 9b78ae3..cec7d6f 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnionAllOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnionAllOperator.java
@@ -74,7 +74,7 @@
     @Override
     public void recomputeSchema() {
         schema = new ArrayList<LogicalVariable>();
-        for (LogicalVariable v1 : inputs.get(0).getOperator().getSchema()) {
+        for (LogicalVariable v1 : inputs.get(0).getValue().getSchema()) {
             for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> t : varMap) {
                 if (t.first.equals(v1)) {
                     schema.add(t.third);
@@ -83,7 +83,7 @@
                 }
             }
         }
-        for (LogicalVariable v2 : inputs.get(1).getOperator().getSchema()) {
+        for (LogicalVariable v2 : inputs.get(1).getValue().getSchema()) {
             for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> t : varMap) {
                 if (t.second.equals(v2)) {
                     schema.add(t.third);
@@ -101,9 +101,9 @@
 
     @Override
     public IVariableTypeEnvironment computeOutputTypeEnvironment(ITypingContext ctx) throws AlgebricksException {
-        IVariableTypeEnvironment env = new NonPropagatingTypeEnvironment(ctx.getExpressionTypeComputer(), ctx
-                .getMetadataProvider());
-        IVariableTypeEnvironment envLeft = ctx.getOutputTypeEnvironment(inputs.get(0).getOperator());
+        IVariableTypeEnvironment env = new NonPropagatingTypeEnvironment(ctx.getExpressionTypeComputer(),
+                ctx.getMetadataProvider());
+        IVariableTypeEnvironment envLeft = ctx.getOutputTypeEnvironment(inputs.get(0).getValue());
         if (envLeft == null) {
             throw new AlgebricksException("Left input types for union operator are not computed.");
         }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnnestMapOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnnestMapOperator.java
index 7056d83..c4f5cb0 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnnestMapOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnnestMapOperator.java
@@ -16,7 +16,9 @@
 
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -36,7 +38,7 @@
 
     // deprecate UnnestMap
 
-    public UnnestMapOperator(List<LogicalVariable> variables, LogicalExpressionReference expression,
+    public UnnestMapOperator(List<LogicalVariable> variables, Mutable<ILogicalExpression> expression,
             List<Object> variableTypes) {
         super(variables, expression);
         this.variableTypes = variableTypes;
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnnestOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnnestOperator.java
index 613c83b..f85cabb 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnnestOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/UnnestOperator.java
@@ -16,7 +16,9 @@
 
 import java.util.ArrayList;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -29,11 +31,11 @@
     private LogicalVariable positionalVariable;
     private Object positionalVariableType;
 
-    public UnnestOperator(LogicalVariable variable, LogicalExpressionReference expression) {
+    public UnnestOperator(LogicalVariable variable, Mutable<ILogicalExpression> expression) {
         super(makeSingletonList(variable), expression);
     }
 
-    public UnnestOperator(LogicalVariable variable, LogicalExpressionReference expression,
+    public UnnestOperator(LogicalVariable variable, Mutable<ILogicalExpression> expression,
             LogicalVariable positionalVariable, Object positionalVariableType) {
         this(variable, expression);
         this.setPositionalVariable(positionalVariable);
@@ -79,7 +81,7 @@
     @Override
     public IVariableTypeEnvironment computeOutputTypeEnvironment(ITypingContext ctx) throws AlgebricksException {
         IVariableTypeEnvironment env = createPropagatingAllInputsTypeEnvironment(ctx);
-        Object t = env.getType(expression.getExpression());
+        Object t = env.getType(expression.getValue());
         env.setVarType(variables.get(0), t);
         if (positionalVariable != null) {
             env.setVarType(positionalVariable, positionalVariableType);
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/WriteOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/WriteOperator.java
index c3559f1..fdcdfd8 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/WriteOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/WriteOperator.java
@@ -17,7 +17,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -29,15 +31,15 @@
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 
 public class WriteOperator extends AbstractLogicalOperator {
-    private List<LogicalExpressionReference> expressions;
+    private List<Mutable<ILogicalExpression>> expressions;
     private IDataSink dataSink;
 
-    public WriteOperator(List<LogicalExpressionReference> expressions, IDataSink dataSink) {
+    public WriteOperator(List<Mutable<ILogicalExpression>> expressions, IDataSink dataSink) {
         this.expressions = expressions;
         this.dataSink = dataSink;
     }
 
-    public List<LogicalExpressionReference> getExpressions() {
+    public List<Mutable<ILogicalExpression>> getExpressions() {
         return expressions;
     }
 
@@ -80,7 +82,7 @@
     @Override
     public void recomputeSchema() {
         schema = new ArrayList<LogicalVariable>();
-        schema.addAll(inputs.get(0).getOperator().getSchema());
+        schema.addAll(inputs.get(0).getValue().getSchema());
     }
 
     @Override
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/WriteResultOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/WriteResultOperator.java
index e8150d2..6d05c76 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/WriteResultOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/WriteResultOperator.java
@@ -17,7 +17,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -31,11 +33,11 @@
 public class WriteResultOperator extends AbstractLogicalOperator {
 
     private IDataSource<?> dataSource;
-    private LogicalExpressionReference payloadExpr;
-    private List<LogicalExpressionReference> keyExprs;
+    private Mutable<ILogicalExpression> payloadExpr;
+    private List<Mutable<ILogicalExpression>> keyExprs;
 
-    public WriteResultOperator(IDataSource<?> dataSource, LogicalExpressionReference payload,
-            List<LogicalExpressionReference> keyExprs) {
+    public WriteResultOperator(IDataSource<?> dataSource, Mutable<ILogicalExpression> payload,
+            List<Mutable<ILogicalExpression>> keyExprs) {
         this.dataSource = dataSource;
         this.payloadExpr = payload;
         this.keyExprs = keyExprs;
@@ -45,11 +47,11 @@
         return dataSource;
     }
 
-    public LogicalExpressionReference getPayloadExpression() {
+    public Mutable<ILogicalExpression> getPayloadExpression() {
         return payloadExpr;
     }
 
-    public List<LogicalExpressionReference> getKeyExpressions() {
+    public List<Mutable<ILogicalExpression>> getKeyExpressions() {
         return keyExprs;
     }
 
@@ -87,7 +89,7 @@
     @Override
     public void recomputeSchema() {
         schema = new ArrayList<LogicalVariable>();
-        schema.addAll(inputs.get(0).getOperator().getSchema());
+        schema.addAll(inputs.get(0).getValue().getSchema());
     }
 
     @Override
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/FDsAndEquivClassesVisitor.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/FDsAndEquivClassesVisitor.java
index 8ea552a..0c0f257 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/FDsAndEquivClassesVisitor.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/FDsAndEquivClassesVisitor.java
@@ -23,20 +23,20 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.EquivalenceClass;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
@@ -86,7 +86,7 @@
 
     @Override
     public Void visitAssignOperator(AssignOperator op, IOptimizationContext ctx) throws AlgebricksException {
-        ILogicalOperator inp1 = op.getInputs().get(0).getOperator();
+        ILogicalOperator inp1 = op.getInputs().get(0).getValue();
         Map<LogicalVariable, EquivalenceClass> eqClasses = getOrComputeEqClasses(inp1, ctx);
         ctx.putEquivalenceClassMap(op, eqClasses);
         List<LogicalVariable> used = new ArrayList<LogicalVariable>();
@@ -110,7 +110,7 @@
 
     @Override
     public Void visitDataScanOperator(DataSourceScanOperator op, IOptimizationContext ctx) throws AlgebricksException {
-        ILogicalOperator inp1 = op.getInputs().get(0).getOperator();
+        ILogicalOperator inp1 = op.getInputs().get(0).getValue();
         Map<LogicalVariable, EquivalenceClass> eqClasses = getOrComputeEqClasses(inp1, ctx);
         ctx.putEquivalenceClassMap(op, eqClasses);
         List<FunctionalDependency> fds = new ArrayList<FunctionalDependency>(getOrComputeFDs(inp1, ctx));
@@ -121,7 +121,7 @@
 
     @Override
     public Void visitDistinctOperator(DistinctOperator op, IOptimizationContext ctx) throws AlgebricksException {
-        ILogicalOperator op0 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op0 = op.getInputs().get(0).getValue();
         List<FunctionalDependency> functionalDependencies = new ArrayList<FunctionalDependency>();
         ctx.putFDList(op, functionalDependencies);
         for (FunctionalDependency inherited : getOrComputeFDs(op0, ctx)) {
@@ -146,9 +146,9 @@
             }
         }
         Set<LogicalVariable> gbySet = new HashSet<LogicalVariable>();
-        List<LogicalExpressionReference> expressions = op.getExpressions();
-        for (LogicalExpressionReference pRef : expressions) {
-            ILogicalExpression p = pRef.getExpression();
+        List<Mutable<ILogicalExpression>> expressions = op.getExpressions();
+        for (Mutable<ILogicalExpression> pRef : expressions) {
+            ILogicalExpression p = pRef.getValue();
             if (p.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 VariableReferenceExpression v = (VariableReferenceExpression) p;
                 gbySet.add(v.getVariableReference());
@@ -161,9 +161,9 @@
 
         lgp.normalizeGroupingColumns(equivalenceClasses, functionalDependencies);
         Set<LogicalVariable> normSet = lgp.getColumnSet();
-        List<LogicalExpressionReference> newDistinctByList = new ArrayList<LogicalExpressionReference>();
-        for (LogicalExpressionReference p2Ref : expressions) {
-            ILogicalExpression p2 = p2Ref.getExpression();
+        List<Mutable<ILogicalExpression>> newDistinctByList = new ArrayList<Mutable<ILogicalExpression>>();
+        for (Mutable<ILogicalExpression> p2Ref : expressions) {
+            ILogicalExpression p2 = p2Ref.getValue();
             if (p2.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 VariableReferenceExpression var2 = (VariableReferenceExpression) p2;
                 LogicalVariable v2 = var2.getVariableReference();
@@ -202,14 +202,14 @@
 
         List<FunctionalDependency> inheritedFDs = new ArrayList<FunctionalDependency>();
         for (ILogicalPlan p : op.getNestedPlans()) {
-            for (LogicalOperatorReference r : p.getRoots()) {
-                ILogicalOperator op2 = r.getOperator();
+            for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                ILogicalOperator op2 = r.getValue();
                 equivalenceClasses.putAll(getOrComputeEqClasses(op2, ctx));
                 inheritedFDs.addAll(getOrComputeFDs(op2, ctx));
             }
         }
 
-        ILogicalOperator op0 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op0 = op.getInputs().get(0).getValue();
         inheritedFDs.addAll(getOrComputeFDs(op0, ctx));
         Map<LogicalVariable, EquivalenceClass> inheritedEcs = getOrComputeEqClasses(op0, ctx);
         for (FunctionalDependency inherited : inheritedFDs) {
@@ -243,15 +243,15 @@
         }
 
         List<LogicalVariable> premiseGby = new LinkedList<LogicalVariable>();
-        List<Pair<LogicalVariable, LogicalExpressionReference>> gByList = op.getGroupByList();
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gByList) {
+        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> gByList = op.getGroupByList();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gByList) {
             premiseGby.add(p.first);
         }
 
-        List<Pair<LogicalVariable, LogicalExpressionReference>> decorList = op.getDecorList();
+        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorList = op.getDecorList();
 
         LinkedList<LogicalVariable> conclDecor = new LinkedList<LogicalVariable>();
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : decorList) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : decorList) {
             conclDecor.add(GroupByOperator.getDecorVariable(p));
         }
         if (!conclDecor.isEmpty()) {
@@ -259,8 +259,8 @@
         }
 
         Set<LogicalVariable> gbySet = new HashSet<LogicalVariable>();
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gByList) {
-            ILogicalExpression expr = p.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gByList) {
+            ILogicalExpression expr = p.second.getValue();
             if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 VariableReferenceExpression v = (VariableReferenceExpression) expr;
                 gbySet.add(v.getVariableReference());
@@ -269,10 +269,10 @@
         LocalGroupingProperty lgp = new LocalGroupingProperty(gbySet);
         lgp.normalizeGroupingColumns(inheritedEcs, inheritedFDs);
         Set<LogicalVariable> normSet = lgp.getColumnSet();
-        List<Pair<LogicalVariable, LogicalExpressionReference>> newGbyList = new ArrayList<Pair<LogicalVariable, LogicalExpressionReference>>();
+        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> newGbyList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
         boolean changed = false;
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gByList) {
-            ILogicalExpression expr = p.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gByList) {
+            ILogicalExpression expr = p.second.getValue();
             if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 VariableReferenceExpression varRef = (VariableReferenceExpression) expr;
                 LogicalVariable v2 = varRef.getVariableReference();
@@ -309,13 +309,13 @@
         List<FunctionalDependency> functionalDependencies = new ArrayList<FunctionalDependency>();
         ctx.putEquivalenceClassMap(op, equivalenceClasses);
         ctx.putFDList(op, functionalDependencies);
-        ILogicalOperator op0 = op.getInputs().get(0).getOperator();
-        ILogicalOperator op1 = op.getInputs().get(1).getOperator();
+        ILogicalOperator op0 = op.getInputs().get(0).getValue();
+        ILogicalOperator op1 = op.getInputs().get(1).getValue();
         functionalDependencies.addAll(getOrComputeFDs(op0, ctx));
         functionalDependencies.addAll(getOrComputeFDs(op1, ctx));
         equivalenceClasses.putAll(getOrComputeEqClasses(op0, ctx));
         equivalenceClasses.putAll(getOrComputeEqClasses(op1, ctx));
-        ILogicalExpression expr = op.getCondition().getExpression();
+        ILogicalExpression expr = op.getCondition().getValue();
         expr.getConstraintsAndEquivClasses(functionalDependencies, equivalenceClasses);
         return null;
     }
@@ -327,8 +327,8 @@
         List<FunctionalDependency> functionalDependencies = new ArrayList<FunctionalDependency>();
         ctx.putEquivalenceClassMap(op, equivalenceClasses);
         ctx.putFDList(op, functionalDependencies);
-        ILogicalOperator opLeft = op.getInputs().get(0).getOperator();
-        ILogicalOperator opRight = op.getInputs().get(1).getOperator();
+        ILogicalOperator opLeft = op.getInputs().get(0).getValue();
+        ILogicalOperator opRight = op.getInputs().get(1).getValue();
         functionalDependencies.addAll(getOrComputeFDs(opLeft, ctx));
         functionalDependencies.addAll(getOrComputeFDs(opRight, ctx));
         equivalenceClasses.putAll(getOrComputeEqClasses(opLeft, ctx));
@@ -343,7 +343,7 @@
         } else {
             leftSideVars = opLeft.getSchema();
         }
-        ILogicalExpression expr = op.getCondition().getExpression();
+        ILogicalExpression expr = op.getCondition().getValue();
         expr.getConstraintsForOuterJoin(functionalDependencies, leftSideVars);
         return null;
     }
@@ -363,8 +363,8 @@
     @Override
     public Void visitNestedTupleSourceOperator(NestedTupleSourceOperator op, IOptimizationContext ctx)
             throws AlgebricksException {
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) op.getDataSourceReference().getOperator();
-        ILogicalOperator inp1 = op1.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) op.getDataSourceReference().getValue();
+        ILogicalOperator inp1 = op1.getInputs().get(0).getValue();
         Map<LogicalVariable, EquivalenceClass> eqClasses = getOrComputeEqClasses(inp1, ctx);
         ctx.putEquivalenceClassMap(op, eqClasses);
         List<FunctionalDependency> fds = new ArrayList<FunctionalDependency>(getOrComputeFDs(inp1, ctx));
@@ -425,10 +425,10 @@
         List<FunctionalDependency> functionalDependencies = new ArrayList<FunctionalDependency>();
         ctx.putEquivalenceClassMap(op, equivalenceClasses);
         ctx.putFDList(op, functionalDependencies);
-        ILogicalOperator op0 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op0 = op.getInputs().get(0).getValue();
         functionalDependencies.addAll(getOrComputeFDs(op0, ctx));
         equivalenceClasses.putAll(getOrComputeEqClasses(op0, ctx));
-        ILogicalExpression expr = op.getCondition().getExpression();
+        ILogicalExpression expr = op.getCondition().getValue();
         expr.getConstraintsAndEquivClasses(functionalDependencies, equivalenceClasses);
         return null;
     }
@@ -440,8 +440,8 @@
         ctx.putEquivalenceClassMap(op, equivalenceClasses);
         ctx.putFDList(op, functionalDependencies);
         for (ILogicalPlan p : op.getNestedPlans()) {
-            for (LogicalOperatorReference r : p.getRoots()) {
-                ILogicalOperator op2 = r.getOperator();
+            for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                ILogicalOperator op2 = r.getValue();
                 equivalenceClasses.putAll(getOrComputeEqClasses(op2, ctx));
                 functionalDependencies.addAll(getOrComputeFDs(op2, ctx));
             }
@@ -501,7 +501,7 @@
     }
 
     private void propagateFDsAndEquivClasses(ILogicalOperator op, IOptimizationContext ctx) throws AlgebricksException {
-        ILogicalOperator inp1 = op.getInputs().get(0).getOperator();
+        ILogicalOperator inp1 = op.getInputs().get(0).getValue();
         Map<LogicalVariable, EquivalenceClass> eqClasses = getOrComputeEqClasses(inp1, ctx);
         ctx.putEquivalenceClassMap(op, eqClasses);
         List<FunctionalDependency> fds = getOrComputeFDs(inp1, ctx);
@@ -530,7 +530,7 @@
 
     private void propagateFDsAndEquivClassesForUsedVars(ILogicalOperator op, IOptimizationContext ctx,
             List<LogicalVariable> usedVariables) throws AlgebricksException {
-        ILogicalOperator op2 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op2 = op.getInputs().get(0).getValue();
         Map<LogicalVariable, EquivalenceClass> eqClasses = new HashMap<LogicalVariable, EquivalenceClass>();
         ctx.putEquivalenceClassMap(op, eqClasses);
         List<FunctionalDependency> fds = new ArrayList<FunctionalDependency>();
@@ -584,13 +584,13 @@
 
     private void fdsEqClassesForAbstractUnnestOperator(AbstractUnnestOperator op, IOptimizationContext ctx)
             throws AlgebricksException {
-        ILogicalOperator inp1 = op.getInputs().get(0).getOperator();
+        ILogicalOperator inp1 = op.getInputs().get(0).getValue();
         Map<LogicalVariable, EquivalenceClass> eqClasses = getOrComputeEqClasses(inp1, ctx);
         ctx.putEquivalenceClassMap(op, eqClasses);
         List<FunctionalDependency> fds = getOrComputeFDs(inp1, ctx);
         ctx.putFDList(op, fds);
 
-        ILogicalExpression expr = op.getExpressionRef().getExpression();
+        ILogicalExpression expr = op.getExpressionRef().getValue();
         if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
             AbstractFunctionCallExpression afe = (AbstractFunctionCallExpression) expr;
             if (afe.getKind() == FunctionKind.UNNEST && ((UnnestingFunctionCallExpression) afe).returnsUniqueValues()) {
@@ -612,8 +612,8 @@
     }
 
     private LogicalVariable getNewGbyVar(GroupByOperator g, LogicalVariable v) {
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : g.getGroupByList()) {
-            ILogicalExpression e = p.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : g.getGroupByList()) {
+            ILogicalExpression e = p.second.getValue();
             if (e.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 LogicalVariable v2 = ((VariableReferenceExpression) e).getVariableReference();
                 if (v2 == v) {
@@ -625,8 +625,8 @@
     }
 
     private LogicalVariable getNewDecorVar(GroupByOperator g, LogicalVariable v) {
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : g.getDecorList()) {
-            ILogicalExpression e = p.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : g.getDecorList()) {
+            ILogicalExpression e = p.second.getValue();
             if (e.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 LogicalVariable v2 = ((VariableReferenceExpression) e).getVariableReference();
                 if (v2 == v) {
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismOperatorVisitor.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismOperatorVisitor.java
index 694324c..5d9e6b9 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismOperatorVisitor.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismOperatorVisitor.java
@@ -21,11 +21,12 @@
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression;
@@ -45,6 +46,7 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.PartitioningSplitOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
@@ -58,7 +60,6 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteResultOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
@@ -117,17 +118,17 @@
                 || aop.getPhysicalOperator().getOperatorTag() != op.getPhysicalOperator().getOperatorTag())
             return Boolean.FALSE;
 
-        List<Pair<LogicalVariable, LogicalExpressionReference>> keyLists = op.getGroupByList();
+        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> keyLists = op.getGroupByList();
         GroupByOperator gbyOpArg = (GroupByOperator) copyAndSubstituteVar(op, arg);
-        List<Pair<LogicalVariable, LogicalExpressionReference>> keyListsArg = gbyOpArg.getGroupByList();
+        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> keyListsArg = gbyOpArg.getGroupByList();
 
         List<Pair<LogicalVariable, ILogicalExpression>> listLeft = new ArrayList<Pair<LogicalVariable, ILogicalExpression>>();
         List<Pair<LogicalVariable, ILogicalExpression>> listRight = new ArrayList<Pair<LogicalVariable, ILogicalExpression>>();
 
-        for (Pair<LogicalVariable, LogicalExpressionReference> pair : keyLists)
-            listLeft.add(new Pair<LogicalVariable, ILogicalExpression>(pair.first, pair.second.getExpression()));
-        for (Pair<LogicalVariable, LogicalExpressionReference> pair : keyListsArg)
-            listRight.add(new Pair<LogicalVariable, ILogicalExpression>(pair.first, pair.second.getExpression()));
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : keyLists)
+            listLeft.add(new Pair<LogicalVariable, ILogicalExpression>(pair.first, pair.second.getValue()));
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : keyListsArg)
+            listRight.add(new Pair<LogicalVariable, ILogicalExpression>(pair.first, pair.second.getValue()));
 
         boolean isomorphic = VariableUtilities.varListEqualUnordered(listLeft, listRight);
 
@@ -142,13 +143,13 @@
         List<ILogicalPlan> plans = op.getNestedPlans();
         List<ILogicalPlan> plansArg = argOp.getNestedPlans();
         for (int i = 0; i < plans.size(); i++) {
-            List<LogicalOperatorReference> roots = plans.get(i).getRoots();
-            List<LogicalOperatorReference> rootsArg = plansArg.get(i).getRoots();
+            List<Mutable<ILogicalOperator>> roots = plans.get(i).getRoots();
+            List<Mutable<ILogicalOperator>> rootsArg = plansArg.get(i).getRoots();
             if (roots.size() != rootsArg.size())
                 return Boolean.FALSE;
             for (int j = 0; j < roots.size(); j++) {
-                ILogicalOperator topOp1 = roots.get(j).getOperator();
-                ILogicalOperator topOp2 = rootsArg.get(j).getOperator();
+                ILogicalOperator topOp1 = roots.get(j).getValue();
+                ILogicalOperator topOp2 = rootsArg.get(j).getValue();
                 isomorphic = this.checkBottomUp(topOp1, topOp2);
                 if (!isomorphic)
                     return Boolean.FALSE;
@@ -165,7 +166,7 @@
         LimitOperator limitOpArg = (LimitOperator) copyAndSubstituteVar(op, arg);
         if (op.getOffset() != limitOpArg.getOffset())
             return Boolean.FALSE;
-        boolean isomorphic = op.getMaxObjects().getExpression().equals(limitOpArg.getMaxObjects().getExpression());
+        boolean isomorphic = op.getMaxObjects().getValue().equals(limitOpArg.getMaxObjects().getValue());
         return isomorphic;
     }
 
@@ -175,7 +176,7 @@
         if (aop.getOperatorTag() != LogicalOperatorTag.DIE)
             return Boolean.FALSE;
         DieOperator dieOpArg = (DieOperator) copyAndSubstituteVar(op, arg);
-        boolean isomorphic = op.getAfterObjects().getExpression().equals(dieOpArg.getAfterObjects().getExpression());
+        boolean isomorphic = op.getAfterObjects().getValue().equals(dieOpArg.getAfterObjects().getValue());
         return isomorphic;
     }
 
@@ -185,7 +186,7 @@
         if (aop.getOperatorTag() != LogicalOperatorTag.INNERJOIN)
             return Boolean.FALSE;
         InnerJoinOperator joinOpArg = (InnerJoinOperator) copyAndSubstituteVar(op, arg);
-        boolean isomorphic = op.getCondition().getExpression().equals(joinOpArg.getCondition().getExpression());
+        boolean isomorphic = op.getCondition().getValue().equals(joinOpArg.getCondition().getValue());
         return isomorphic;
     }
 
@@ -196,7 +197,7 @@
         if (aop.getOperatorTag() != LogicalOperatorTag.LEFTOUTERJOIN)
             return Boolean.FALSE;
         LeftOuterJoinOperator joinOpArg = (LeftOuterJoinOperator) copyAndSubstituteVar(op, arg);
-        boolean isomorphic = op.getCondition().getExpression().equals(joinOpArg.getCondition().getExpression());
+        boolean isomorphic = op.getCondition().getValue().equals(joinOpArg.getCondition().getValue());
         return isomorphic;
     }
 
@@ -237,7 +238,7 @@
         if (aop.getOperatorTag() != LogicalOperatorTag.SELECT)
             return Boolean.FALSE;
         SelectOperator selectOpArg = (SelectOperator) copyAndSubstituteVar(op, arg);
-        boolean isomorphic = op.getCondition().getExpression().equals(selectOpArg.getCondition().getExpression());
+        boolean isomorphic = op.getCondition().getValue().equals(selectOpArg.getCondition().getValue());
         return isomorphic;
     }
 
@@ -290,13 +291,13 @@
         List<ILogicalPlan> plans = op.getNestedPlans();
         List<ILogicalPlan> plansArg = subplanOpArg.getNestedPlans();
         for (int i = 0; i < plans.size(); i++) {
-            List<LogicalOperatorReference> roots = plans.get(i).getRoots();
-            List<LogicalOperatorReference> rootsArg = plansArg.get(i).getRoots();
+            List<Mutable<ILogicalOperator>> roots = plans.get(i).getRoots();
+            List<Mutable<ILogicalOperator>> rootsArg = plansArg.get(i).getRoots();
             if (roots.size() == rootsArg.size())
                 return Boolean.FALSE;
             for (int j = 0; j < roots.size(); j++) {
-                ILogicalOperator topOp1 = roots.get(j).getOperator();
-                ILogicalOperator topOp2 = rootsArg.get(j).getOperator();
+                ILogicalOperator topOp1 = roots.get(j).getValue();
+                ILogicalOperator topOp2 = rootsArg.get(j).getValue();
                 boolean isomorphic = this.checkBottomUp(topOp1, topOp2);
                 if (!isomorphic)
                     return Boolean.FALSE;
@@ -328,7 +329,7 @@
                 && variableEqual(op.getPositionalVariable(), unnestOpArg.getPositionalVariable());
         if (!isomorphic)
             return Boolean.FALSE;
-        isomorphic = op.getExpressionRef().getExpression().equals(unnestOpArg.getExpressionRef().getExpression());
+        isomorphic = op.getExpressionRef().getValue().equals(unnestOpArg.getExpressionRef().getValue());
         return isomorphic;
     }
 
@@ -341,7 +342,7 @@
         boolean isomorphic = VariableUtilities.varListEqualUnordered(op.getVariables(), unnestOpArg.getVariables());
         if (!isomorphic)
             return Boolean.FALSE;
-        isomorphic = op.getExpressionRef().getExpression().equals(unnestOpArg.getExpressionRef().getExpression());
+        isomorphic = op.getExpressionRef().getValue().equals(unnestOpArg.getExpressionRef().getValue());
         return isomorphic;
     }
 
@@ -462,27 +463,27 @@
         return true;
     }
 
-    private Boolean compareExpressions(List<LogicalExpressionReference> opExprs,
-            List<LogicalExpressionReference> argExprs) {
+    private Boolean compareExpressions(List<Mutable<ILogicalExpression>> opExprs,
+            List<Mutable<ILogicalExpression>> argExprs) {
         if (opExprs.size() != argExprs.size())
             return Boolean.FALSE;
         for (int i = 0; i < opExprs.size(); i++) {
-            boolean isomorphic = opExprs.get(i).getExpression().equals(argExprs.get(i).getExpression());
+            boolean isomorphic = opExprs.get(i).getValue().equals(argExprs.get(i).getValue());
             if (!isomorphic)
                 return Boolean.FALSE;
         }
         return Boolean.TRUE;
     }
 
-    private Boolean compareIOrderAndExpressions(List<Pair<IOrder, LogicalExpressionReference>> opOrderExprs,
-            List<Pair<IOrder, LogicalExpressionReference>> argOrderExprs) {
+    private Boolean compareIOrderAndExpressions(List<Pair<IOrder, Mutable<ILogicalExpression>>> opOrderExprs,
+            List<Pair<IOrder, Mutable<ILogicalExpression>>> argOrderExprs) {
         if (opOrderExprs.size() != argOrderExprs.size())
             return Boolean.FALSE;
         for (int i = 0; i < opOrderExprs.size(); i++) {
             boolean isomorphic = opOrderExprs.get(i).first.equals(argOrderExprs.get(i).first);
             if (!isomorphic)
                 return Boolean.FALSE;
-            isomorphic = opOrderExprs.get(i).second.getExpression().equals(argOrderExprs.get(i).second.getExpression());
+            isomorphic = opOrderExprs.get(i).second.getValue().equals(argOrderExprs.get(i).second.getValue());
             if (!isomorphic)
                 return Boolean.FALSE;
         }
@@ -490,13 +491,13 @@
     }
 
     private Boolean checkBottomUp(ILogicalOperator op1, ILogicalOperator op2) throws AlgebricksException {
-        List<LogicalOperatorReference> inputs1 = op1.getInputs();
-        List<LogicalOperatorReference> inputs2 = op2.getInputs();
+        List<Mutable<ILogicalOperator>> inputs1 = op1.getInputs();
+        List<Mutable<ILogicalOperator>> inputs2 = op2.getInputs();
         if (inputs1.size() != inputs2.size())
             return Boolean.FALSE;
         for (int i = 0; i < inputs1.size(); i++) {
-            ILogicalOperator input1 = inputs1.get(i).getOperator();
-            ILogicalOperator input2 = inputs2.get(i).getOperator();
+            ILogicalOperator input1 = inputs1.get(i).getValue();
+            ILogicalOperator input2 = inputs2.get(i).getValue();
             boolean isomorphic = checkBottomUp(input1, input2);
             if (!isomorphic)
                 return Boolean.FALSE;
@@ -513,7 +514,7 @@
         List<LogicalVariable> liveVars = new ArrayList<LogicalVariable>();
         if (argOp.getInputs().size() > 0)
             for (int i = 0; i < argOp.getInputs().size(); i++)
-                VariableUtilities.getLiveVariables(argOp.getInputs().get(i).getOperator(), liveVars);
+                VariableUtilities.getLiveVariables(argOp.getInputs().get(i).getValue(), liveVars);
         List<LogicalVariable> producedVars = new ArrayList<LogicalVariable>();
         VariableUtilities.getProducedVariables(argOp, producedVars);
         List<LogicalVariable> producedVarsNew = new ArrayList<LogicalVariable>();
@@ -532,12 +533,12 @@
     }
 
     public List<Pair<LogicalVariable, ILogicalExpression>> getPairList(List<LogicalVariable> vars,
-            List<LogicalExpressionReference> exprs) throws AlgebricksException {
+            List<Mutable<ILogicalExpression>> exprs) throws AlgebricksException {
         List<Pair<LogicalVariable, ILogicalExpression>> list = new ArrayList<Pair<LogicalVariable, ILogicalExpression>>();
         if (vars.size() != exprs.size())
             throw new AlgebricksException("variable list size does not equal to expression list size ");
         for (int i = 0; i < vars.size(); i++) {
-            list.add(new Pair<LogicalVariable, ILogicalExpression>(vars.get(i), exprs.get(i).getExpression()));
+            list.add(new Pair<LogicalVariable, ILogicalExpression>(vars.get(i), exprs.get(i).getValue()));
         }
         return list;
     }
@@ -548,18 +549,18 @@
     }
 
     private static ILogicalPlan deepCopy(ILogicalPlan plan) throws AlgebricksException {
-        List<LogicalOperatorReference> roots = plan.getRoots();
-        List<LogicalOperatorReference> newRoots = new ArrayList<LogicalOperatorReference>();
-        for (LogicalOperatorReference opRef : roots)
-            newRoots.add(new LogicalOperatorReference(bottomUpCopyOperators(opRef.getOperator())));
+        List<Mutable<ILogicalOperator>> roots = plan.getRoots();
+        List<Mutable<ILogicalOperator>> newRoots = new ArrayList<Mutable<ILogicalOperator>>();
+        for (Mutable<ILogicalOperator> opRef : roots)
+            newRoots.add(new MutableObject<ILogicalOperator>(bottomUpCopyOperators(opRef.getValue())));
         return new ALogicalPlanImpl(newRoots);
     }
 
     private static ILogicalOperator bottomUpCopyOperators(ILogicalOperator op) throws AlgebricksException {
         ILogicalOperator newOp = deepCopy(op);
         newOp.getInputs().clear();
-        for (LogicalOperatorReference child : op.getInputs())
-            newOp.getInputs().add(new LogicalOperatorReference(bottomUpCopyOperators(child.getOperator())));
+        for (Mutable<ILogicalOperator> child : op.getInputs())
+            newOp.getInputs().add(new MutableObject<ILogicalOperator>(bottomUpCopyOperators(child.getValue())));
         return newOp;
     }
 
@@ -577,7 +578,7 @@
         @Override
         public ILogicalOperator visitAggregateOperator(AggregateOperator op, Void arg) throws AlgebricksException {
             ArrayList<LogicalVariable> newList = new ArrayList<LogicalVariable>();
-            ArrayList<LogicalExpressionReference> newExpressions = new ArrayList<LogicalExpressionReference>();
+            ArrayList<Mutable<ILogicalExpression>> newExpressions = new ArrayList<Mutable<ILogicalExpression>>();
             newList.addAll(op.getVariables());
             deepCopyExpressionRefs(newExpressions, op.getExpressions());
             return new AggregateOperator(newList, newExpressions);
@@ -587,7 +588,7 @@
         public ILogicalOperator visitRunningAggregateOperator(RunningAggregateOperator op, Void arg)
                 throws AlgebricksException {
             ArrayList<LogicalVariable> newList = new ArrayList<LogicalVariable>();
-            ArrayList<LogicalExpressionReference> newExpressions = new ArrayList<LogicalExpressionReference>();
+            ArrayList<Mutable<ILogicalExpression>> newExpressions = new ArrayList<Mutable<ILogicalExpression>>();
             newList.addAll(op.getVariables());
             deepCopyExpressionRefs(newExpressions, op.getExpressions());
             return new RunningAggregateOperator(newList, newExpressions);
@@ -601,14 +602,14 @@
 
         @Override
         public ILogicalOperator visitGroupByOperator(GroupByOperator op, Void arg) throws AlgebricksException {
-            List<Pair<LogicalVariable, LogicalExpressionReference>> groupByList = new ArrayList<Pair<LogicalVariable, LogicalExpressionReference>>();
-            List<Pair<LogicalVariable, LogicalExpressionReference>> decoList = new ArrayList<Pair<LogicalVariable, LogicalExpressionReference>>();
+            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
+            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decoList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
             ArrayList<ILogicalPlan> newSubplans = new ArrayList<ILogicalPlan>();
-            for (Pair<LogicalVariable, LogicalExpressionReference> pair : op.getGroupByList())
-                groupByList.add(new Pair<LogicalVariable, LogicalExpressionReference>(pair.first,
+            for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : op.getGroupByList())
+                groupByList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(pair.first,
                         deepCopyExpressionRef(pair.second)));
-            for (Pair<LogicalVariable, LogicalExpressionReference> pair : op.getDecorList())
-                decoList.add(new Pair<LogicalVariable, LogicalExpressionReference>(pair.first,
+            for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : op.getDecorList())
+                decoList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(pair.first,
                         deepCopyExpressionRef(pair.second)));
             for (ILogicalPlan plan : op.getNestedPlans()) {
                 newSubplans.add(IsomorphismOperatorVisitor.deepCopy(plan));
@@ -618,13 +619,13 @@
 
         @Override
         public ILogicalOperator visitLimitOperator(LimitOperator op, Void arg) throws AlgebricksException {
-            return new LimitOperator(deepCopyExpressionRef(op.getMaxObjects()).getExpression(), deepCopyExpressionRef(
-                    op.getOffset()).getExpression(), op.isTopmostLimitOp());
+            return new LimitOperator(deepCopyExpressionRef(op.getMaxObjects()).getValue(), deepCopyExpressionRef(
+                    op.getOffset()).getValue(), op.isTopmostLimitOp());
         }
 
         @Override
         public ILogicalOperator visitDieOperator(DieOperator op, Void arg) throws AlgebricksException {
-            return new DieOperator(deepCopyExpressionRef(op.getAfterObjects()).getExpression());
+            return new DieOperator(deepCopyExpressionRef(op.getAfterObjects()).getValue());
         }
 
         @Override
@@ -654,7 +655,7 @@
         @Override
         public ILogicalOperator visitAssignOperator(AssignOperator op, Void arg) throws AlgebricksException {
             ArrayList<LogicalVariable> newList = new ArrayList<LogicalVariable>();
-            ArrayList<LogicalExpressionReference> newExpressions = new ArrayList<LogicalExpressionReference>();
+            ArrayList<Mutable<ILogicalExpression>> newExpressions = new ArrayList<Mutable<ILogicalExpression>>();
             newList.addAll(op.getVariables());
             deepCopyExpressionRefs(newExpressions, op.getExpressions());
             return new AssignOperator(newList, newExpressions);
@@ -675,9 +676,9 @@
         @Override
         public ILogicalOperator visitPartitioningSplitOperator(PartitioningSplitOperator op, Void arg)
                 throws AlgebricksException {
-            ArrayList<LogicalExpressionReference> newExpressions = new ArrayList<LogicalExpressionReference>();
+            ArrayList<Mutable<ILogicalExpression>> newExpressions = new ArrayList<Mutable<ILogicalExpression>>();
             deepCopyExpressionRefs(newExpressions, Arrays.asList(op.getExpressions()));
-            return new PartitioningSplitOperator(newExpressions.toArray(new LogicalExpressionReference[0]),
+            return new PartitioningSplitOperator(newExpressions.toArray(new Mutable[0]),
                     op.hasDefault());
         }
 
@@ -737,7 +738,7 @@
 
         @Override
         public ILogicalOperator visitDistinctOperator(DistinctOperator op, Void arg) throws AlgebricksException {
-            ArrayList<LogicalExpressionReference> newExpressions = new ArrayList<LogicalExpressionReference>();
+            ArrayList<Mutable<ILogicalExpression>> newExpressions = new ArrayList<Mutable<ILogicalExpression>>();
             deepCopyExpressionRefs(newExpressions, op.getExpressions());
             return new DistinctOperator(newExpressions);
         }
@@ -749,14 +750,14 @@
 
         @Override
         public ILogicalOperator visitWriteOperator(WriteOperator op, Void arg) throws AlgebricksException {
-            ArrayList<LogicalExpressionReference> newExpressions = new ArrayList<LogicalExpressionReference>();
+            ArrayList<Mutable<ILogicalExpression>> newExpressions = new ArrayList<Mutable<ILogicalExpression>>();
             deepCopyExpressionRefs(newExpressions, op.getExpressions());
             return new WriteOperator(newExpressions, op.getDataSink());
         }
 
         @Override
         public ILogicalOperator visitWriteResultOperator(WriteResultOperator op, Void arg) throws AlgebricksException {
-            ArrayList<LogicalExpressionReference> newKeyExpressions = new ArrayList<LogicalExpressionReference>();
+            ArrayList<Mutable<ILogicalExpression>> newKeyExpressions = new ArrayList<Mutable<ILogicalExpression>>();
             deepCopyExpressionRefs(newKeyExpressions, op.getKeyExpressions());
             return new WriteResultOperator(op.getDataSource(), deepCopyExpressionRef(op.getPayloadExpression()),
                     newKeyExpressions);
@@ -764,7 +765,7 @@
 
         @Override
         public ILogicalOperator visitInsertDeleteOperator(InsertDeleteOperator op, Void arg) throws AlgebricksException {
-            List<LogicalExpressionReference> newKeyExpressions = new ArrayList<LogicalExpressionReference>();
+            List<Mutable<ILogicalExpression>> newKeyExpressions = new ArrayList<Mutable<ILogicalExpression>>();
             deepCopyExpressionRefs(newKeyExpressions, op.getPrimaryKeyExpressions());
             return new InsertDeleteOperator(op.getDataSource(), deepCopyExpressionRef(op.getPayloadExpression()),
                     newKeyExpressions, op.getOperation());
@@ -773,9 +774,9 @@
         @Override
         public ILogicalOperator visitIndexInsertDeleteOperator(IndexInsertDeleteOperator op, Void arg)
                 throws AlgebricksException {
-            List<LogicalExpressionReference> newPrimaryKeyExpressions = new ArrayList<LogicalExpressionReference>();
+            List<Mutable<ILogicalExpression>> newPrimaryKeyExpressions = new ArrayList<Mutable<ILogicalExpression>>();
             deepCopyExpressionRefs(newPrimaryKeyExpressions, op.getPrimaryKeyExpressions());
-            List<LogicalExpressionReference> newSecondaryKeyExpressions = new ArrayList<LogicalExpressionReference>();
+            List<Mutable<ILogicalExpression>> newSecondaryKeyExpressions = new ArrayList<Mutable<ILogicalExpression>>();
             deepCopyExpressionRefs(newSecondaryKeyExpressions, op.getSecondaryKeyExpressions());
             return new IndexInsertDeleteOperator(op.getDataSourceIndex(), newPrimaryKeyExpressions,
                     newSecondaryKeyExpressions, op.getOperation());
@@ -786,23 +787,23 @@
             return new SinkOperator();
         }
 
-        private void deepCopyExpressionRefs(List<LogicalExpressionReference> newExprs,
-                List<LogicalExpressionReference> oldExprs) {
-            for (LogicalExpressionReference oldExpr : oldExprs)
-                newExprs.add(new LogicalExpressionReference(((AbstractLogicalExpression) oldExpr.getExpression())
+        private void deepCopyExpressionRefs(List<Mutable<ILogicalExpression>> newExprs,
+                List<Mutable<ILogicalExpression>> oldExprs) {
+            for (Mutable<ILogicalExpression> oldExpr : oldExprs)
+                newExprs.add(new MutableObject<ILogicalExpression>(((AbstractLogicalExpression) oldExpr.getValue())
                         .cloneExpression()));
         }
 
-        private LogicalExpressionReference deepCopyExpressionRef(LogicalExpressionReference oldExpr) {
-            return new LogicalExpressionReference(
-                    ((AbstractLogicalExpression) oldExpr.getExpression()).cloneExpression());
+        private Mutable<ILogicalExpression> deepCopyExpressionRef(Mutable<ILogicalExpression> oldExpr) {
+            return new MutableObject<ILogicalExpression>(
+                    ((AbstractLogicalExpression) oldExpr.getValue()).cloneExpression());
         }
 
-        private List<Pair<IOrder, LogicalExpressionReference>> deepCopyOrderAndExpression(
-                List<Pair<IOrder, LogicalExpressionReference>> ordersAndExprs) {
-            List<Pair<IOrder, LogicalExpressionReference>> newOrdersAndExprs = new ArrayList<Pair<IOrder, LogicalExpressionReference>>();
-            for (Pair<IOrder, LogicalExpressionReference> pair : ordersAndExprs)
-                newOrdersAndExprs.add(new Pair<IOrder, LogicalExpressionReference>(pair.first,
+        private List<Pair<IOrder, Mutable<ILogicalExpression>>> deepCopyOrderAndExpression(
+                List<Pair<IOrder, Mutable<ILogicalExpression>>> ordersAndExprs) {
+            List<Pair<IOrder, Mutable<ILogicalExpression>>> newOrdersAndExprs = new ArrayList<Pair<IOrder, Mutable<ILogicalExpression>>>();
+            for (Pair<IOrder, Mutable<ILogicalExpression>> pair : ordersAndExprs)
+                newOrdersAndExprs.add(new Pair<IOrder, Mutable<ILogicalExpression>>(pair.first,
                         deepCopyExpressionRef(pair.second)));
             return newOrdersAndExprs;
         }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismVariableMappingVisitor.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismVariableMappingVisitor.java
index 214d6da..340b855 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismVariableMappingVisitor.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismVariableMappingVisitor.java
@@ -19,11 +19,12 @@
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractAssignOperator;
@@ -253,13 +254,13 @@
     }
 
     private void mapChildren(ILogicalOperator op, ILogicalOperator opArg) throws AlgebricksException {
-        List<LogicalOperatorReference> inputs = op.getInputs();
-        List<LogicalOperatorReference> inputsArg = opArg.getInputs();
+        List<Mutable<ILogicalOperator>> inputs = op.getInputs();
+        List<Mutable<ILogicalOperator>> inputsArg = opArg.getInputs();
         if (inputs.size() != inputsArg.size())
             throw new AlgebricksException("children are not isomoprhic");
         for (int i = 0; i < inputs.size(); i++) {
-            ILogicalOperator input = inputs.get(i).getOperator();
-            ILogicalOperator inputArg = inputsArg.get(i).getOperator();
+            ILogicalOperator input = inputs.get(i).getValue();
+            ILogicalOperator inputArg = inputsArg.get(i).getValue();
             input.accept(this, inputArg);
         }
     }
@@ -298,23 +299,23 @@
     private void mapVariablesForGroupBy(ILogicalOperator left, ILogicalOperator right) throws AlgebricksException {
         GroupByOperator leftOp = (GroupByOperator) left;
         GroupByOperator rightOp = (GroupByOperator) right;
-        List<Pair<LogicalVariable, LogicalExpressionReference>> leftPairs = leftOp.getGroupByList();
-        List<Pair<LogicalVariable, LogicalExpressionReference>> rightPairs = rightOp.getGroupByList();
+        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> leftPairs = leftOp.getGroupByList();
+        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> rightPairs = rightOp.getGroupByList();
         mapVarExprPairList(leftPairs, rightPairs);
         leftPairs = leftOp.getDecorList();
         rightPairs = rightOp.getDecorList();
         mapVarExprPairList(leftPairs, rightPairs);
     }
 
-    private void mapVarExprPairList(List<Pair<LogicalVariable, LogicalExpressionReference>> leftPairs,
-            List<Pair<LogicalVariable, LogicalExpressionReference>> rightPairs) {
+    private void mapVarExprPairList(List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> leftPairs,
+            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> rightPairs) {
         if (leftPairs.size() != rightPairs.size())
             return;
         for (int i = 0; i < leftPairs.size(); i++) {
-            ILogicalExpression exprLeft = leftPairs.get(i).second.getExpression();
+            ILogicalExpression exprLeft = leftPairs.get(i).second.getValue();
             LogicalVariable leftVar = leftPairs.get(i).first;
             for (int j = 0; j < leftPairs.size(); j++) {
-                ILogicalExpression exprRight = copyExpressionAndSubtituteVars(rightPairs.get(j).second).getExpression();
+                ILogicalExpression exprRight = copyExpressionAndSubtituteVars(rightPairs.get(j).second).getValue();
                 if (exprLeft.equals(exprRight)) {
                     LogicalVariable rightVar = rightPairs.get(j).first;
                     if (rightVar != null && leftVar != null) {
@@ -327,16 +328,16 @@
     }
 
     private void mapVariablesForAbstractAssign(List<LogicalVariable> variablesLeft,
-            List<LogicalExpressionReference> exprsLeft, List<LogicalVariable> variablesRight,
-            List<LogicalExpressionReference> exprsRight) {
+            List<Mutable<ILogicalExpression>> exprsLeft, List<LogicalVariable> variablesRight,
+            List<Mutable<ILogicalExpression>> exprsRight) {
         if (variablesLeft.size() != variablesRight.size())
             return;
         int size = variablesLeft.size();
         for (int i = 0; i < size; i++) {
-            ILogicalExpression exprLeft = exprsLeft.get(i).getExpression();
+            ILogicalExpression exprLeft = exprsLeft.get(i).getValue();
             LogicalVariable left = variablesLeft.get(i);
             for (int j = 0; j < size; j++) {
-                ILogicalExpression exprRight = copyExpressionAndSubtituteVars(exprsRight.get(j)).getExpression();
+                ILogicalExpression exprRight = copyExpressionAndSubtituteVars(exprsRight.get(j)).getValue();
                 if (exprLeft.equals(exprRight)) {
                     LogicalVariable right = variablesRight.get(j);
                     variableMapping.put(right, left);
@@ -354,13 +355,13 @@
         if (plans.size() != plansArg.size())
             return;
         for (int i = 0; i < plans.size(); i++) {
-            List<LogicalOperatorReference> roots = plans.get(i).getRoots();
-            List<LogicalOperatorReference> rootsArg = plansArg.get(i).getRoots();
+            List<Mutable<ILogicalOperator>> roots = plans.get(i).getRoots();
+            List<Mutable<ILogicalOperator>> rootsArg = plansArg.get(i).getRoots();
             if (roots.size() != rootsArg.size())
                 return;
             for (int j = 0; j < roots.size(); j++) {
-                ILogicalOperator topOp1 = roots.get(j).getOperator();
-                ILogicalOperator topOp2 = rootsArg.get(j).getOperator();
+                ILogicalOperator topOp1 = roots.get(j).getValue();
+                ILogicalOperator topOp2 = rootsArg.get(j).getValue();
                 topOp1.accept(this, topOp2);
             }
         }
@@ -371,11 +372,11 @@
         mapVariables(op, arg);
     }
 
-    private LogicalExpressionReference copyExpressionAndSubtituteVars(LogicalExpressionReference expr) {
-        ILogicalExpression copy = ((AbstractLogicalExpression) expr.getExpression()).cloneExpression();
+    private Mutable<ILogicalExpression> copyExpressionAndSubtituteVars(Mutable<ILogicalExpression> expr) {
+        ILogicalExpression copy = ((AbstractLogicalExpression) expr.getValue()).cloneExpression();
         for (Entry<LogicalVariable, LogicalVariable> entry : variableMapping.entrySet())
             copy.substituteVar(entry.getKey(), entry.getValue());
-        return new LogicalExpressionReference(copy);
+        return new MutableObject<ILogicalExpression>(copy);
     }
 
     private void mapVariablesForUnion(ILogicalOperator op, ILogicalOperator arg) {
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalPropertiesVisitor.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalPropertiesVisitor.java
index 950772d..30ad3ab 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalPropertiesVisitor.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalPropertiesVisitor.java
@@ -14,10 +14,11 @@
  */
 package edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.OperatorAnnotations;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IExpressionEvalSizeComputer;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableEvalSizeEnvironment;
@@ -66,8 +67,8 @@
 
     private static void computeLogicalPropertiesRec(ILogicalOperator op, LogicalPropertiesVisitor visitor,
             IOptimizationContext context) throws AlgebricksException {
-        for (LogicalOperatorReference ref : op.getInputs()) {
-            computeLogicalPropertiesRec(ref.getOperator(), visitor, context);
+        for (Mutable<ILogicalOperator> ref : op.getInputs()) {
+            computeLogicalPropertiesRec(ref.getValue(), visitor, context);
         }
         op.accept(visitor, context);
         if (AlgebricksConfig.DEBUG) {
@@ -263,7 +264,7 @@
     }
 
     private LogicalPropertiesVectorImpl propagateCardinality(ILogicalOperator op, IOptimizationContext context) {
-        ILogicalOperator op0 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op0 = op.getInputs().get(0).getValue();
         ILogicalPropertiesVector v0 = context.getLogicalPropertiesVector(op0);
         if (v0 == null) {
             return null;
@@ -280,13 +281,13 @@
             IVariableEvalSizeEnvironment varSizeEnv = context.getVariableEvalSizeEnvironment();
             IExpressionEvalSizeComputer evalSize = context.getExpressionEvalSizeComputer();
             if (evalSize != null) {
-                ILogicalOperator op0 = op.getInputs().get(0).getOperator();
+                ILogicalOperator op0 = op.getInputs().get(0).getValue();
                 ILogicalPropertiesVector v0 = context.getLogicalPropertiesVector(op0);
                 if (v0 != null) {
                     long frames0 = v0.getMaxOutputFrames();
                     long overhead = 0; // added per tuple
-                    for (LogicalExpressionReference exprRef : op.getExpressions()) {
-                        int sz = evalSize.getEvalSize(exprRef.getExpression(), varSizeEnv);
+                    for (Mutable<ILogicalExpression> exprRef : op.getExpressions()) {
+                        int sz = evalSize.getEvalSize(exprRef.getValue(), varSizeEnv);
                         if (sz == -1) {
                             return;
                         }
@@ -310,7 +311,7 @@
             throws AlgebricksException {
         LogicalPropertiesVectorImpl v = propagateCardinality(op, context);
         // propagate also max number of frames (conservatively)
-        ILogicalOperator op0 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op0 = op.getInputs().get(0).getValue();
         ILogicalPropertiesVector v0 = context.getLogicalPropertiesVector(op0);
         if (v0 != null) {
             v.setMaxOutputFrames(v0.getMaxOutputFrames());
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/ProducedVariableVisitor.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/ProducedVariableVisitor.java
index 1e991f1..cd05624 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/ProducedVariableVisitor.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/ProducedVariableVisitor.java
@@ -18,9 +18,11 @@
 import java.util.Collection;

 import java.util.List;

 

+import org.apache.commons.lang3.mutable.Mutable;

+

+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;

+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;

@@ -99,16 +101,16 @@
     @Override

     public Void visitGroupByOperator(GroupByOperator op, Void arg) throws AlgebricksException {

         for (ILogicalPlan p : op.getNestedPlans()) {

-            for (LogicalOperatorReference r : p.getRoots()) {

-                VariableUtilities.getLiveVariables(r.getOperator(), producedVariables);

+            for (Mutable<ILogicalOperator> r : p.getRoots()) {

+                VariableUtilities.getLiveVariables(r.getValue(), producedVariables);

             }

         }

-        for (Pair<LogicalVariable, LogicalExpressionReference> p : op.getGroupByList()) {

+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : op.getGroupByList()) {

             if (p.first != null) {

                 producedVariables.add(p.first);

             }

         }

-        for (Pair<LogicalVariable, LogicalExpressionReference> p : op.getDecorList()) {

+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : op.getDecorList()) {

             if (p.first != null) {

                 producedVariables.add(p.first);

             }

@@ -182,8 +184,8 @@
     @Override

     public Void visitSubplanOperator(SubplanOperator op, Void arg) throws AlgebricksException {

         for (ILogicalPlan p : op.getNestedPlans()) {

-            for (LogicalOperatorReference r : p.getRoots()) {

-                VariableUtilities.getLiveVariables(r.getOperator(), producedVariables);

+            for (Mutable<ILogicalOperator> r : p.getRoots()) {

+                VariableUtilities.getLiveVariables(r.getValue(), producedVariables);

             }

         }

         return null;

diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/SchemaVariableVisitor.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/SchemaVariableVisitor.java
index be03961..6aa3796 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/SchemaVariableVisitor.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/SchemaVariableVisitor.java
@@ -16,12 +16,12 @@
 

 import java.util.Collection;

 

+import org.apache.commons.lang3.mutable.Mutable;

+

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;

@@ -103,20 +103,20 @@
     @Override

     public Void visitGroupByOperator(GroupByOperator op, Void arg) throws AlgebricksException {

         for (ILogicalPlan p : op.getNestedPlans()) {

-            for (LogicalOperatorReference r : p.getRoots()) {

-                VariableUtilities.getLiveVariables(r.getOperator(), schemaVariables);

+            for (Mutable<ILogicalOperator> r : p.getRoots()) {

+                VariableUtilities.getLiveVariables(r.getValue(), schemaVariables);

             }

         }

-        for (Pair<LogicalVariable, LogicalExpressionReference> p : op.getGroupByList()) {

+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : op.getGroupByList()) {

             if (p.first != null) {

                 schemaVariables.add(p.first);

             }

         }

-        for (Pair<LogicalVariable, LogicalExpressionReference> p : op.getDecorList()) {

+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : op.getDecorList()) {

             if (p.first != null) {

                 schemaVariables.add(p.first);

             } else {

-                ILogicalExpression e = p.second.getExpression();

+                ILogicalExpression e = p.second.getValue();

                 if (e.getExpressionTag() == LogicalExpressionTag.VARIABLE) {

                     schemaVariables.add(((VariableReferenceExpression) e).getVariableReference());

                 }

@@ -194,13 +194,13 @@
 

     @Override

     public Void visitSubplanOperator(SubplanOperator op, Void arg) throws AlgebricksException {

-        for (LogicalOperatorReference c : op.getInputs()) {

-            VariableUtilities.getLiveVariables(c.getOperator(), schemaVariables);

+        for (Mutable<ILogicalOperator> c : op.getInputs()) {

+            VariableUtilities.getLiveVariables(c.getValue(), schemaVariables);

         }

         VariableUtilities.getProducedVariables(op, schemaVariables);

         for (ILogicalPlan p : op.getNestedPlans()) {

-            for (LogicalOperatorReference r : p.getRoots()) {

-                VariableUtilities.getLiveVariables(r.getOperator(), schemaVariables);

+            for (Mutable<ILogicalOperator> r : p.getRoots()) {

+                VariableUtilities.getLiveVariables(r.getValue(), schemaVariables);

             }

         }

         return null;

@@ -237,8 +237,8 @@
     }

 

     private void standardLayout(ILogicalOperator op) throws AlgebricksException {

-        for (LogicalOperatorReference c : op.getInputs()) {

-            VariableUtilities.getLiveVariables(c.getOperator(), schemaVariables);

+        for (Mutable<ILogicalOperator> c : op.getInputs()) {

+            VariableUtilities.getLiveVariables(c.getValue(), schemaVariables);

         }

         VariableUtilities.getProducedVariables(op, schemaVariables);

     }

diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/SubstituteVariableVisitor.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/SubstituteVariableVisitor.java
index d463805..b85c798 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/SubstituteVariableVisitor.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/SubstituteVariableVisitor.java
@@ -17,11 +17,11 @@
 import java.util.ArrayList;

 import java.util.List;

 

+import org.apache.commons.lang3.mutable.Mutable;

+

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;

@@ -40,6 +40,7 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;

+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.PartitioningSplitOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;

@@ -53,7 +54,6 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteResultOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;

 import edu.uci.ics.hyracks.algebricks.core.algebra.typing.ITypingContext;

 import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;

 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalOperatorVisitor;

@@ -80,7 +80,7 @@
             if (variables.get(i).equals(pair.first)) {

                 variables.set(i, pair.second);

             } else {

-                op.getExpressions().get(i).getExpression().substituteVar(pair.first, pair.second);

+                op.getExpressions().get(i).getValue().substituteVar(pair.first, pair.second);

             }

         }

         substVarTypes(op, pair);

@@ -96,7 +96,7 @@
             if (variables.get(i).equals(pair.first)) {

                 variables.set(i, pair.second);

             } else {

-                op.getExpressions().get(i).getExpression().substituteVar(pair.first, pair.second);

+                op.getExpressions().get(i).getValue().substituteVar(pair.first, pair.second);

             }

         }

         substVarTypes(op, pair);

@@ -120,8 +120,8 @@
     @Override

     public Void visitDistinctOperator(DistinctOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

-        for (LogicalExpressionReference eRef : op.getExpressions()) {

-            eRef.getExpression().substituteVar(pair.first, pair.second);

+        for (Mutable<ILogicalExpression> eRef : op.getExpressions()) {

+            eRef.getValue().substituteVar(pair.first, pair.second);

         }

         substVarTypes(op, pair);

         return null;

@@ -145,8 +145,8 @@
         subst(pair.first, pair.second, op.getGroupByList());

         subst(pair.first, pair.second, op.getDecorList());

         for (ILogicalPlan p : op.getNestedPlans()) {

-            for (LogicalOperatorReference r : p.getRoots()) {

-                OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getOperator(), pair.first,

+            for (Mutable<ILogicalOperator> r : p.getRoots()) {

+                OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getValue(), pair.first,

                         pair.second, goThroughNts, ctx);

             }

         }

@@ -157,7 +157,7 @@
     @Override

     public Void visitInnerJoinOperator(InnerJoinOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

-        op.getCondition().getExpression().substituteVar(pair.first, pair.second);

+        op.getCondition().getValue().substituteVar(pair.first, pair.second);

         substVarTypes(op, pair);

         return null;

     }

@@ -165,7 +165,7 @@
     @Override

     public Void visitLeftOuterJoinOperator(LeftOuterJoinOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

-        op.getCondition().getExpression().substituteVar(pair.first, pair.second);

+        op.getCondition().getValue().substituteVar(pair.first, pair.second);

         substVarTypes(op, pair);

         return null;

     }

@@ -173,8 +173,8 @@
     @Override

     public Void visitLimitOperator(LimitOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

-        op.getMaxObjects().getExpression().substituteVar(pair.first, pair.second);

-        ILogicalExpression offset = op.getOffset().getExpression();

+        op.getMaxObjects().getValue().substituteVar(pair.first, pair.second);

+        ILogicalExpression offset = op.getOffset().getValue();

         if (offset != null) {

             offset.substituteVar(pair.first, pair.second);

         }

@@ -185,7 +185,7 @@
     @Override

     public Void visitDieOperator(DieOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

-        op.getAfterObjects().getExpression().substituteVar(pair.first, pair.second);

+        op.getAfterObjects().getValue().substituteVar(pair.first, pair.second);

         substVarTypes(op, pair);

         return null;

     }

@@ -199,8 +199,8 @@
     @Override

     public Void visitOrderOperator(OrderOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

-        for (Pair<IOrder, LogicalExpressionReference> oe : op.getOrderExpressions()) {

-            oe.second.getExpression().substituteVar(pair.first, pair.second);

+        for (Pair<IOrder, Mutable<ILogicalExpression>> oe : op.getOrderExpressions()) {

+            oe.second.getValue().substituteVar(pair.first, pair.second);

         }

         substVarTypes(op, pair);

         return null;

@@ -209,8 +209,8 @@
     @Override

     public Void visitPartitioningSplitOperator(PartitioningSplitOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

-        for (LogicalExpressionReference e : op.getExpressions()) {

-            e.getExpression().substituteVar(pair.first, pair.second);

+        for (Mutable<ILogicalExpression> e : op.getExpressions()) {

+            e.getValue().substituteVar(pair.first, pair.second);

         }

         substVarTypes(op, pair);

         return null;

@@ -240,7 +240,7 @@
             if (variables.get(i).equals(pair.first)) {

                 variables.set(i, pair.second);

             } else {

-                op.getExpressions().get(i).getExpression().substituteVar(pair.first, pair.second);

+                op.getExpressions().get(i).getValue().substituteVar(pair.first, pair.second);

             }

         }

         substVarTypes(op, pair);

@@ -258,7 +258,7 @@
 

     @Override

     public Void visitSelectOperator(SelectOperator op, Pair<LogicalVariable, LogicalVariable> pair) {

-        op.getCondition().getExpression().substituteVar(pair.first, pair.second);

+        op.getCondition().getValue().substituteVar(pair.first, pair.second);

         return null;

     }

 

@@ -266,8 +266,8 @@
     public Void visitSubplanOperator(SubplanOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

         for (ILogicalPlan p : op.getNestedPlans()) {

-            for (LogicalOperatorReference r : p.getRoots()) {

-                OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getOperator(), pair.first,

+            for (Mutable<ILogicalOperator> r : p.getRoots()) {

+                OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getValue(), pair.first,

                         pair.second, goThroughNts, ctx);

             }

         }

@@ -303,7 +303,7 @@
                 return null;

             }

         }

-        op.getExpressionRef().getExpression().substituteVar(pair.first, pair.second);

+        op.getExpressionRef().getValue().substituteVar(pair.first, pair.second);

         substVarTypes(op, pair);

         return null;

     }

@@ -318,7 +318,7 @@
                 return null;

             }

         }

-        op.getExpressionRef().getExpression().substituteVar(pair.first, pair.second);

+        op.getExpressionRef().getValue().substituteVar(pair.first, pair.second);

         substVarTypes(op, pair);

         return null;

     }

@@ -326,8 +326,8 @@
     @Override

     public Void visitWriteOperator(WriteOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

-        for (LogicalExpressionReference e : op.getExpressions()) {

-            e.getExpression().substituteVar(pair.first, pair.second);

+        for (Mutable<ILogicalExpression> e : op.getExpressions()) {

+            e.getValue().substituteVar(pair.first, pair.second);

         }

         substVarTypes(op, pair);

         return null;

@@ -336,22 +336,22 @@
     @Override

     public Void visitWriteResultOperator(WriteResultOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

-        op.getPayloadExpression().getExpression().substituteVar(pair.first, pair.second);

-        for (LogicalExpressionReference e : op.getKeyExpressions()) {

-            e.getExpression().substituteVar(pair.first, pair.second);

+        op.getPayloadExpression().getValue().substituteVar(pair.first, pair.second);

+        for (Mutable<ILogicalExpression> e : op.getKeyExpressions()) {

+            e.getValue().substituteVar(pair.first, pair.second);

         }

         substVarTypes(op, pair);

         return null;

     }

 

     private void subst(LogicalVariable v1, LogicalVariable v2,

-            List<Pair<LogicalVariable, LogicalExpressionReference>> varExprPairList) {

-        for (Pair<LogicalVariable, LogicalExpressionReference> ve : varExprPairList) {

+            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> varExprPairList) {

+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> ve : varExprPairList) {

             if (ve.first != null && ve.first.equals(v1)) {

                 ve.first = v2;

                 return;

             }

-            ve.second.getExpression().substituteVar(v1, v2);

+            ve.second.getValue().substituteVar(v1, v2);

         }

     }

 

@@ -374,9 +374,9 @@
     @Override

     public Void visitInsertDeleteOperator(InsertDeleteOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

-        op.getPayloadExpression().getExpression().substituteVar(pair.first, pair.second);

-        for (LogicalExpressionReference e : op.getPrimaryKeyExpressions()) {

-            e.getExpression().substituteVar(pair.first, pair.second);

+        op.getPayloadExpression().getValue().substituteVar(pair.first, pair.second);

+        for (Mutable<ILogicalExpression> e : op.getPrimaryKeyExpressions()) {

+            e.getValue().substituteVar(pair.first, pair.second);

         }

         substVarTypes(op, pair);

         return null;

@@ -385,11 +385,11 @@
     @Override

     public Void visitIndexInsertDeleteOperator(IndexInsertDeleteOperator op, Pair<LogicalVariable, LogicalVariable> pair)

             throws AlgebricksException {

-        for (LogicalExpressionReference e : op.getPrimaryKeyExpressions()) {

-            e.getExpression().substituteVar(pair.first, pair.second);

+        for (Mutable<ILogicalExpression> e : op.getPrimaryKeyExpressions()) {

+            e.getValue().substituteVar(pair.first, pair.second);

         }

-        for (LogicalExpressionReference e : op.getSecondaryKeyExpressions()) {

-            e.getExpression().substituteVar(pair.first, pair.second);

+        for (Mutable<ILogicalExpression> e : op.getSecondaryKeyExpressions()) {

+            e.getValue().substituteVar(pair.first, pair.second);

         }

         substVarTypes(op, pair);

         return null;

diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/UsedVariableVisitor.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/UsedVariableVisitor.java
index 08512d8..d9d6a6a 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/UsedVariableVisitor.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/UsedVariableVisitor.java
@@ -17,10 +17,11 @@
 import java.util.Collection;

 import java.util.List;

 

+import org.apache.commons.lang3.mutable.Mutable;

+

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;

+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;

@@ -37,6 +38,7 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;

+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.PartitioningSplitOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;

@@ -50,7 +52,6 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteResultOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;

 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalOperatorVisitor;

 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;

 import edu.uci.ics.hyracks.algebricks.core.utils.Pair;

@@ -66,16 +67,16 @@
 

     @Override

     public Void visitAggregateOperator(AggregateOperator op, Void arg) {

-        for (LogicalExpressionReference exprRef : op.getExpressions()) {

-            exprRef.getExpression().getUsedVariables(usedVariables);

+        for (Mutable<ILogicalExpression> exprRef : op.getExpressions()) {

+            exprRef.getValue().getUsedVariables(usedVariables);

         }

         return null;

     }

 

     @Override

     public Void visitAssignOperator(AssignOperator op, Void arg) {

-        for (LogicalExpressionReference exprRef : op.getExpressions()) {

-            exprRef.getExpression().getUsedVariables(usedVariables);

+        for (Mutable<ILogicalExpression> exprRef : op.getExpressions()) {

+            exprRef.getValue().getUsedVariables(usedVariables);

         }

         return null;

     }

@@ -88,8 +89,8 @@
 

     @Override

     public Void visitDistinctOperator(DistinctOperator op, Void arg) {

-        for (LogicalExpressionReference eRef : op.getExpressions()) {

-            eRef.getExpression().getUsedVariables(usedVariables);

+        for (Mutable<ILogicalExpression> eRef : op.getExpressions()) {

+            eRef.getValue().getUsedVariables(usedVariables);

         }

         return null;

     }

@@ -109,35 +110,35 @@
     @Override

     public Void visitGroupByOperator(GroupByOperator op, Void arg) throws AlgebricksException {

         for (ILogicalPlan p : op.getNestedPlans()) {

-            for (LogicalOperatorReference r : p.getRoots()) {

-                VariableUtilities.getUsedVariablesInDescendantsAndSelf(r.getOperator(), usedVariables);

+            for (Mutable<ILogicalOperator> r : p.getRoots()) {

+                VariableUtilities.getUsedVariablesInDescendantsAndSelf(r.getValue(), usedVariables);

             }

         }

-        for (Pair<LogicalVariable, LogicalExpressionReference> g : op.getGroupByList()) {

-            g.second.getExpression().getUsedVariables(usedVariables);

+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> g : op.getGroupByList()) {

+            g.second.getValue().getUsedVariables(usedVariables);

         }

-        for (Pair<LogicalVariable, LogicalExpressionReference> g : op.getDecorList()) {

-            g.second.getExpression().getUsedVariables(usedVariables);

+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> g : op.getDecorList()) {

+            g.second.getValue().getUsedVariables(usedVariables);

         }

         return null;

     }

 

     @Override

     public Void visitInnerJoinOperator(InnerJoinOperator op, Void arg) {

-        op.getCondition().getExpression().getUsedVariables(usedVariables);

+        op.getCondition().getValue().getUsedVariables(usedVariables);

         return null;

     }

 

     @Override

     public Void visitLeftOuterJoinOperator(LeftOuterJoinOperator op, Void arg) {

-        op.getCondition().getExpression().getUsedVariables(usedVariables);

+        op.getCondition().getValue().getUsedVariables(usedVariables);

         return null;

     }

 

     @Override

     public Void visitLimitOperator(LimitOperator op, Void arg) {

-        op.getMaxObjects().getExpression().getUsedVariables(usedVariables);

-        ILogicalExpression offsetExpr = op.getOffset().getExpression();

+        op.getMaxObjects().getValue().getUsedVariables(usedVariables);

+        ILogicalExpression offsetExpr = op.getOffset().getValue();

         if (offsetExpr != null) {

             offsetExpr.getUsedVariables(usedVariables);

         }

@@ -146,7 +147,7 @@
 

     @Override

     public Void visitDieOperator(DieOperator op, Void arg) {

-        op.getAfterObjects().getExpression().getUsedVariables(usedVariables);

+        op.getAfterObjects().getValue().getUsedVariables(usedVariables);

         return null;

     }

 

@@ -158,16 +159,16 @@
 

     @Override

     public Void visitOrderOperator(OrderOperator op, Void arg) {

-        for (Pair<IOrder, LogicalExpressionReference> oe : op.getOrderExpressions()) {

-            oe.second.getExpression().getUsedVariables(usedVariables);

+        for (Pair<IOrder, Mutable<ILogicalExpression>> oe : op.getOrderExpressions()) {

+            oe.second.getValue().getUsedVariables(usedVariables);

         }

         return null;

     }

 

     @Override

     public Void visitPartitioningSplitOperator(PartitioningSplitOperator op, Void arg) {

-        for (LogicalExpressionReference e : op.getExpressions()) {

-            e.getExpression().getUsedVariables(usedVariables);

+        for (Mutable<ILogicalExpression> e : op.getExpressions()) {

+            e.getValue().getUsedVariables(usedVariables);

         }

         return null;

     }

@@ -185,8 +186,8 @@
 

     @Override

     public Void visitRunningAggregateOperator(RunningAggregateOperator op, Void arg) {

-        for (LogicalExpressionReference exprRef : op.getExpressions()) {

-            exprRef.getExpression().getUsedVariables(usedVariables);

+        for (Mutable<ILogicalExpression> exprRef : op.getExpressions()) {

+            exprRef.getValue().getUsedVariables(usedVariables);

         }

         return null;

     }

@@ -204,15 +205,15 @@
 

     @Override

     public Void visitSelectOperator(SelectOperator op, Void arg) {

-        op.getCondition().getExpression().getUsedVariables(usedVariables);

+        op.getCondition().getValue().getUsedVariables(usedVariables);

         return null;

     }

 

     @Override

     public Void visitSubplanOperator(SubplanOperator op, Void arg) throws AlgebricksException {

         for (ILogicalPlan p : op.getNestedPlans()) {

-            for (LogicalOperatorReference r : p.getRoots()) {

-                VariableUtilities.getUsedVariablesInDescendantsAndSelf(r.getOperator(), usedVariables);

+            for (Mutable<ILogicalOperator> r : p.getRoots()) {

+                VariableUtilities.getUsedVariablesInDescendantsAndSelf(r.getValue(), usedVariables);

             }

         }

         return null;

@@ -233,49 +234,49 @@
 

     @Override

     public Void visitUnnestMapOperator(UnnestMapOperator op, Void arg) {

-        op.getExpressionRef().getExpression().getUsedVariables(usedVariables);

+        op.getExpressionRef().getValue().getUsedVariables(usedVariables);

         return null;

     }

 

     @Override

     public Void visitUnnestOperator(UnnestOperator op, Void arg) {

-        op.getExpressionRef().getExpression().getUsedVariables(usedVariables);

+        op.getExpressionRef().getValue().getUsedVariables(usedVariables);

         return null;

     }

 

     @Override

     public Void visitWriteOperator(WriteOperator op, Void arg) {

-        for (LogicalExpressionReference expr : op.getExpressions()) {

-            expr.getExpression().getUsedVariables(usedVariables);

+        for (Mutable<ILogicalExpression> expr : op.getExpressions()) {

+            expr.getValue().getUsedVariables(usedVariables);

         }

         return null;

     }

 

     @Override

     public Void visitWriteResultOperator(WriteResultOperator op, Void arg) {

-        op.getPayloadExpression().getExpression().getUsedVariables(usedVariables);

-        for (LogicalExpressionReference e : op.getKeyExpressions()) {

-            e.getExpression().getUsedVariables(usedVariables);

+        op.getPayloadExpression().getValue().getUsedVariables(usedVariables);

+        for (Mutable<ILogicalExpression> e : op.getKeyExpressions()) {

+            e.getValue().getUsedVariables(usedVariables);

         }

         return null;

     }

 

     @Override

     public Void visitInsertDeleteOperator(InsertDeleteOperator op, Void arg) {

-        op.getPayloadExpression().getExpression().getUsedVariables(usedVariables);

-        for (LogicalExpressionReference e : op.getPrimaryKeyExpressions()) {

-            e.getExpression().getUsedVariables(usedVariables);

+        op.getPayloadExpression().getValue().getUsedVariables(usedVariables);

+        for (Mutable<ILogicalExpression> e : op.getPrimaryKeyExpressions()) {

+            e.getValue().getUsedVariables(usedVariables);

         }

         return null;

     }

 

     @Override

     public Void visitIndexInsertDeleteOperator(IndexInsertDeleteOperator op, Void arg) {

-        for (LogicalExpressionReference e : op.getPrimaryKeyExpressions()) {

-            e.getExpression().getUsedVariables(usedVariables);

+        for (Mutable<ILogicalExpression> e : op.getPrimaryKeyExpressions()) {

+            e.getValue().getUsedVariables(usedVariables);

         }

-        for (LogicalExpressionReference e : op.getSecondaryKeyExpressions()) {

-            e.getExpression().getUsedVariables(usedVariables);

+        for (Mutable<ILogicalExpression> e : op.getSecondaryKeyExpressions()) {

+            e.getValue().getUsedVariables(usedVariables);

         }

         return null;

     }

diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/VariableUtilities.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/VariableUtilities.java
index a918bed..8e9c5b8 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/VariableUtilities.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/logical/visitors/VariableUtilities.java
@@ -19,8 +19,9 @@
 import java.util.List;

 import java.util.Set;

 

+import org.apache.commons.lang3.mutable.Mutable;

+

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;

 import edu.uci.ics.hyracks.algebricks.core.algebra.typing.ITypingContext;

 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalOperatorVisitor;

@@ -51,8 +52,8 @@
             throws AlgebricksException {

         // DFS traversal

         VariableUtilities.getUsedVariables(op, vars);

-        for (LogicalOperatorReference c : op.getInputs()) {

-            getUsedVariablesInDescendantsAndSelf(c.getOperator(), vars);

+        for (Mutable<ILogicalOperator> c : op.getInputs()) {

+            getUsedVariablesInDescendantsAndSelf(c.getValue(), vars);

         }

     }

 

diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractExchangePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractExchangePOperator.java
index 766237c..761c7f2 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractExchangePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractExchangePOperator.java
@@ -15,8 +15,8 @@
 package edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical;
 
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder.TargetConstraint;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
 import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.jobgen.impl.JobGenContext;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -31,7 +31,7 @@
         Pair<IConnectorDescriptor, TargetConstraint> connPair = createConnectorDescriptor(builder.getJobSpec(), op,
                 opSchema, context);
         builder.contributeConnectorWithTargetConstraint(op, connPair.first, connPair.second);
-        ILogicalOperator src = op.getInputs().get(0).getOperator();
+        ILogicalOperator src = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, op, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java
index 61422af..b9352f3 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java
@@ -23,8 +23,8 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator.JoinKind;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.BroadcastPartitioningProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
@@ -64,9 +64,9 @@
         AbstractLogicalOperator op = (AbstractLogicalOperator) iop;
 
         if (op.getExecutionMode() == AbstractLogicalOperator.ExecutionMode.PARTITIONED) {
-            AbstractLogicalOperator op0 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+            AbstractLogicalOperator op0 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
             IPhysicalPropertiesVector pv0 = op0.getPhysicalOperator().getDeliveredProperties();
-            AbstractLogicalOperator op1 = (AbstractLogicalOperator) op.getInputs().get(1).getOperator();
+            AbstractLogicalOperator op1 = (AbstractLogicalOperator) op.getInputs().get(1).getValue();
             IPhysicalPropertiesVector pv1 = op1.getPhysicalOperator().getDeliveredProperties();
 
             if (pv0 == null || pv1 == null) {
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPhysicalOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPhysicalOperator.java
index 038793e..620c161 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPhysicalOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPhysicalOperator.java
@@ -21,9 +21,9 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IPhysicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningRequirementsCoordinator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.PhysicalRequirements;
@@ -105,7 +105,7 @@
             throw new NotImplementedException("Nested plans with several roots are not supported.");
         }
         JobSpecification nestedJob = pc.compilePlan(p, outerPlanSchema);
-        ILogicalOperator topOpInSubplan = p.getRoots().get(0).getOperator();
+        ILogicalOperator topOpInSubplan = p.getRoots().get(0).getValue();
         JobGenContext context = pc.getContext();
         IOperatorSchema topOpInSubplanScm = context.getSchema(topOpInSubplan);
         opSchema.addAllVariables(topOpInSubplanScm);
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPreclusteredGroupByPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPreclusteredGroupByPOperator.java
index 1aee87b..84982aa 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPreclusteredGroupByPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPreclusteredGroupByPOperator.java
@@ -7,23 +7,24 @@
 import java.util.List;
 import java.util.Set;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.EquivalenceClass;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IPhysicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.FunctionalDependency;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty.PropertyType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningRequirementsCoordinator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
@@ -34,7 +35,6 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.PropertiesUtil;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.StructuralPropertiesVector;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.UnorderedPartitionedProperty;
-import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty.PropertyType;
 import edu.uci.ics.hyracks.algebricks.core.utils.Pair;
 
 public abstract class AbstractPreclusteredGroupByPOperator extends AbstractPhysicalOperator {
@@ -64,7 +64,7 @@
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
         List<ILocalStructuralProperty> propsLocal = new LinkedList<ILocalStructuralProperty>();
         GroupByOperator gby = (GroupByOperator) op;
-        ILogicalOperator op2 = gby.getInputs().get(0).getOperator();
+        ILogicalOperator op2 = gby.getInputs().get(0).getValue();
         IPhysicalPropertiesVector childProp = op2.getDeliveredPhysicalProperties();
         IPartitioningProperty pp = childProp.getPartitioningProperty();
         List<ILocalStructuralProperty> childLocals = childProp.getLocalProperties();
@@ -126,10 +126,10 @@
         for (ILogicalPlan p : gby.getNestedPlans()) {
             // try to propagate secondary order requirements from nested
             // groupings
-            for (LogicalOperatorReference r : p.getRoots()) {
-                AbstractLogicalOperator op1 = (AbstractLogicalOperator) r.getOperator();
+            for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                AbstractLogicalOperator op1 = (AbstractLogicalOperator) r.getValue();
                 if (op1.getOperatorTag() == LogicalOperatorTag.AGGREGATE) {
-                    AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getOperator();
+                    AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
                     IPhysicalOperator pop2 = op2.getPhysicalOperator();
                     if (pop2 instanceof AbstractPreclusteredGroupByPOperator) {
                         List<LogicalVariable> sndOrder = ((AbstractPreclusteredGroupByPOperator) pop2).getGbyColumns();
@@ -160,7 +160,7 @@
                     }
                     LocalOrderProperty lop = (LocalOrderProperty) prop;
                     LogicalVariable ord = lop.getColumn();
-                    Pair<LogicalVariable, LogicalExpressionReference> p = getGbyPairByRhsVar(gby, ord);
+                    Pair<LogicalVariable, Mutable<ILogicalExpression>> p = getGbyPairByRhsVar(gby, ord);
                     if (p == null) {
                         p = getDecorPairByRhsVar(gby, ord);
                         if (p == null) {
@@ -168,7 +168,7 @@
                             break;
                         }
                     }
-                    ILogicalExpression e = p.second.getExpression();
+                    ILogicalExpression e = p.second.getValue();
                     if (e.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                         throw new IllegalStateException(
                                 "Right hand side of group-by assignment should have been normalized to a variable reference.");
@@ -177,10 +177,10 @@
                     props.add(new LocalOrderProperty(new OrderColumn(v, lop.getOrder())));
                 }
                 List<FunctionalDependency> fdList = new ArrayList<FunctionalDependency>();
-                for (Pair<LogicalVariable, LogicalExpressionReference> decorPair : gby.getDecorList()) {
+                for (Pair<LogicalVariable, Mutable<ILogicalExpression>> decorPair : gby.getDecorList()) {
                     List<LogicalVariable> hd = gby.getGbyVarList();
                     List<LogicalVariable> tl = new ArrayList<LogicalVariable>(1);
-                    tl.add(((VariableReferenceExpression) decorPair.second.getExpression()).getVariableReference());
+                    tl.add(((VariableReferenceExpression) decorPair.second.getValue()).getVariableReference());
                     fdList.add(new FunctionalDependency(hd, tl));
                 }
                 if (allOk
@@ -200,9 +200,9 @@
         return new PhysicalRequirements(pv, IPartitioningRequirementsCoordinator.NO_COORDINATION);
     }
 
-    private static Pair<LogicalVariable, LogicalExpressionReference> getGbyPairByRhsVar(GroupByOperator gby,
+    private static Pair<LogicalVariable, Mutable<ILogicalExpression>> getGbyPairByRhsVar(GroupByOperator gby,
             LogicalVariable var) {
-        for (Pair<LogicalVariable, LogicalExpressionReference> ve : gby.getGroupByList()) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> ve : gby.getGroupByList()) {
             if (ve.first == var) {
                 return ve;
             }
@@ -210,9 +210,9 @@
         return null;
     }
 
-    private static Pair<LogicalVariable, LogicalExpressionReference> getDecorPairByRhsVar(GroupByOperator gby,
+    private static Pair<LogicalVariable, Mutable<ILogicalExpression>> getDecorPairByRhsVar(GroupByOperator gby,
             LogicalVariable var) {
-        for (Pair<LogicalVariable, LogicalExpressionReference> ve : gby.getDecorList()) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> ve : gby.getDecorList()) {
             if (ve.first == var) {
                 return ve;
             }
@@ -221,8 +221,8 @@
     }
 
     private static LogicalVariable getLhsGbyVar(GroupByOperator gby, LogicalVariable var) {
-        for (Pair<LogicalVariable, LogicalExpressionReference> ve : gby.getGroupByList()) {
-            ILogicalExpression e = ve.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> ve : gby.getGroupByList()) {
+            ILogicalExpression e = ve.second.getValue();
             if (e.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                 throw new IllegalStateException(
                         "Right hand side of group by assignment should have been normalized to a variable reference.");
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
index 2974753..224d94c 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
@@ -27,7 +27,7 @@
 public abstract class AbstractPropagatePropertiesForUsedVariablesPOperator extends AbstractPhysicalOperator {
 
     public void computeDeliveredPropertiesForUsedVariables(ILogicalOperator op, List<LogicalVariable> usedVariables) {
-        ILogicalOperator op2 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op2 = op.getInputs().get(0).getValue();
         IPartitioningProperty pp = op2.getDeliveredPhysicalProperties().getPartitioningProperty();
         List<ILocalStructuralProperty> downPropsLocal = op2.getDeliveredPhysicalProperties().getLocalProperties();
         List<ILocalStructuralProperty> propsLocal = new ArrayList<ILocalStructuralProperty>();
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractStableSortPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractStableSortPOperator.java
index 227ed73..ca09b77 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractStableSortPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AbstractStableSortPOperator.java
@@ -17,10 +17,11 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
@@ -57,7 +58,7 @@
         // invalidate cache
         computeLocalProperties(op);
         // }
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         StructuralPropertiesVector childProp = (StructuralPropertiesVector) op2.getDeliveredPhysicalProperties();
         deliveredProperties = new StructuralPropertiesVector(childProp.getPartitioningProperty(), orderProps);
     }
@@ -82,8 +83,8 @@
         orderProps = new LinkedList<ILocalStructuralProperty>();
 
         OrderOperator ord = (OrderOperator) op;
-        for (Pair<IOrder, LogicalExpressionReference> p : ord.getOrderExpressions()) {
-            ILogicalExpression expr = p.second.getExpression();
+        for (Pair<IOrder, Mutable<ILogicalExpression>> p : ord.getOrderExpressions()) {
+            ILogicalExpression expr = p.second.getValue();
             if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 VariableReferenceExpression varRef = (VariableReferenceExpression) expr;
                 LogicalVariable var = varRef.getVariableReference();
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AggregatePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AggregatePOperator.java
index c7215fe..47038ad 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AggregatePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AggregatePOperator.java
@@ -17,10 +17,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
@@ -51,7 +53,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         IPhysicalPropertiesVector childProps = op2.getDeliveredPhysicalProperties();
         deliveredProperties = new StructuralPropertiesVector(childProps.getPartitioningProperty(),
                 new ArrayList<ILocalStructuralProperty>(0));
@@ -69,7 +71,7 @@
             throws AlgebricksException {
         AggregateOperator aggOp = (AggregateOperator) op;
         List<LogicalVariable> variables = aggOp.getVariables();
-        List<LogicalExpressionReference> expressions = aggOp.getExpressions();
+        List<Mutable<ILogicalExpression>> expressions = aggOp.getExpressions();
         int[] outColumns = new int[variables.size()];
         for (int i = 0; i < outColumns.length; i++) {
             outColumns[i] = opSchema.findVariable(variables.get(i));
@@ -78,9 +80,9 @@
         ILogicalExpressionJobGen exprJobGen = context.getExpressionJobGen();
         for (int i = 0; i < aggFactories.length; i++) {
             AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) expressions.get(i)
-                    .getExpression();
-            aggFactories[i] = exprJobGen.createAggregateFunctionFactory(aggFun, context.getTypeEnvironment(op
-                    .getInputs().get(0).getOperator()), inputSchemas, context);
+                    .getValue();
+            aggFactories[i] = exprJobGen.createAggregateFunctionFactory(aggFun,
+                    context.getTypeEnvironment(op.getInputs().get(0).getValue()), inputSchemas, context);
         }
 
         AggregateRuntimeFactory runtime = new AggregateRuntimeFactory(aggFactories);
@@ -89,7 +91,7 @@
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, opSchema, context);
         builder.contributeMicroOperator(aggOp, runtime, recDesc);
         // and contribute one edge from its child
-        ILogicalOperator src = aggOp.getInputs().get(0).getOperator();
+        ILogicalOperator src = aggOp.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, aggOp, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AssignPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AssignPOperator.java
index 276ada9..861765d 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AssignPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/AssignPOperator.java
@@ -16,10 +16,12 @@
 
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ILogicalExpressionJobGen;
@@ -43,7 +45,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        ILogicalOperator op2 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op2 = op.getInputs().get(0).getValue();
         deliveredProperties = op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -59,7 +61,7 @@
             throws AlgebricksException {
         AssignOperator assign = (AssignOperator) op;
         List<LogicalVariable> variables = assign.getVariables();
-        List<LogicalExpressionReference> expressions = assign.getExpressions();
+        List<Mutable<ILogicalExpression>> expressions = assign.getExpressions();
         int[] outColumns = new int[variables.size()];
         for (int i = 0; i < outColumns.length; i++) {
             outColumns[i] = opSchema.findVariable(variables.get(i));
@@ -67,8 +69,8 @@
         IEvaluatorFactory[] evalFactories = new IEvaluatorFactory[expressions.size()];
         ILogicalExpressionJobGen exprJobGen = context.getExpressionJobGen();
         for (int i = 0; i < evalFactories.length; i++) {
-            evalFactories[i] = exprJobGen.createEvaluatorFactory(expressions.get(i).getExpression(), context
-                    .getTypeEnvironment(op.getInputs().get(0).getOperator()), inputSchemas, context);
+            evalFactories[i] = exprJobGen.createEvaluatorFactory(expressions.get(i).getValue(),
+                    context.getTypeEnvironment(op.getInputs().get(0).getValue()), inputSchemas, context);
         }
 
         // TODO push projections into the operator
@@ -80,7 +82,7 @@
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, opSchema, context);
         builder.contributeMicroOperator(assign, runtime, recDesc);
         // and contribute one edge from its child
-        ILogicalOperator src = assign.getInputs().get(0).getOperator();
+        ILogicalOperator src = assign.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, assign, 0);
 
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/BroadcastPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/BroadcastPOperator.java
index 65b6452..0c780d5 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/BroadcastPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/BroadcastPOperator.java
@@ -14,10 +14,10 @@
  */
 package edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical;
 
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder.TargetConstraint;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder.TargetConstraint;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.BroadcastPartitioningProperty;
@@ -48,7 +48,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         IPartitioningProperty pp = new BroadcastPartitioningProperty(domain);
         this.deliveredProperties = new StructuralPropertiesVector(pp, op2.getDeliveredPhysicalProperties()
                 .getLocalProperties());
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/DataSourceScanPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/DataSourceScanPOperator.java
index 7bf4e49..68a6a24 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/DataSourceScanPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/DataSourceScanPOperator.java
@@ -76,7 +76,7 @@
             builder.contributeAlgebricksPartitionConstraint(p.first, p.second);
         }
 
-        ILogicalOperator srcExchange = scan.getInputs().get(0).getOperator();
+        ILogicalOperator srcExchange = scan.getInputs().get(0).getValue();
         builder.contributeGraphEdge(srcExchange, 0, scan, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/ExternalGroupByPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/ExternalGroupByPOperator.java
index a983ce7..c0c369e 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/ExternalGroupByPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/ExternalGroupByPOperator.java
@@ -5,14 +5,14 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
@@ -21,10 +21,10 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningRequirementsCoordinator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
@@ -56,17 +56,17 @@
     private int frameLimit = 0;
     private List<LogicalVariable> columnSet = new ArrayList<LogicalVariable>();
 
-    public ExternalGroupByPOperator(List<Pair<LogicalVariable, LogicalExpressionReference>> gbyList, int frameLimit,
+    public ExternalGroupByPOperator(List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> gbyList, int frameLimit,
             int tableSize) {
         this.tableSize = tableSize;
         this.frameLimit = frameLimit;
         computeColumnSet(gbyList);
     }
 
-    public void computeColumnSet(List<Pair<LogicalVariable, LogicalExpressionReference>> gbyList) {
+    public void computeColumnSet(List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> gbyList) {
         columnSet.clear();
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gbyList) {
-            ILogicalExpression expr = p.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gbyList) {
+            ILogicalExpression expr = p.second.getValue();
             if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 VariableReferenceExpression v = (VariableReferenceExpression) expr;
                 columnSet.add(v.getVariableReference());
@@ -104,13 +104,13 @@
             propsLocal.add(new LocalGroupingProperty(columnSet));
         }
         for (ILogicalPlan p : gOp.getNestedPlans()) {
-            for (LogicalOperatorReference r : p.getRoots()) {
-                ILogicalOperator rOp = r.getOperator();
+            for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                ILogicalOperator rOp = r.getValue();
                 propsLocal.addAll(rOp.getDeliveredPhysicalProperties().getLocalProperties());
             }
         }
 
-        ILogicalOperator op2 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op2 = op.getInputs().get(0).getValue();
         IPhysicalPropertiesVector childProp = op2.getDeliveredPhysicalProperties();
         deliveredProperties = new StructuralPropertiesVector(childProp.getPartitioningProperty(), propsLocal);
     }
@@ -139,8 +139,8 @@
         int numFds = gby.getDecorList().size();
         int fdColumns[] = new int[numFds];
         int j = 0;
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gby.getDecorList()) {
-            ILogicalExpression expr = p.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getDecorList()) {
+            ILogicalExpression expr = p.second.getValue();
             if (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                 throw new AlgebricksException("pre-sorted group-by expects variable references.");
             }
@@ -160,8 +160,8 @@
                     "External group-by currently works only for one nested plan with one root containing"
                             + "an aggregate and a nested-tuple-source.");
         }
-        LogicalOperatorReference r0 = p0.getRoots().get(0);
-        AggregateOperator aggOp = (AggregateOperator) r0.getOperator();
+        Mutable<ILogicalOperator> r0 = p0.getRoots().get(0);
+        AggregateOperator aggOp = (AggregateOperator) r0.getValue();
 
         IPartialAggregationTypeComputer partialAggregationTypeComputer = context.getPartialAggregationTypeComputer();
         List<Object> intermediateTypes = new ArrayList<Object>();
@@ -169,10 +169,10 @@
         ISerializableAggregateFunctionFactory[] aff = new ISerializableAggregateFunctionFactory[n];
         int i = 0;
         ILogicalExpressionJobGen exprJobGen = context.getExpressionJobGen();
-        IVariableTypeEnvironment aggOpInputEnv = context.getTypeEnvironment(aggOp.getInputs().get(0).getOperator());
+        IVariableTypeEnvironment aggOpInputEnv = context.getTypeEnvironment(aggOp.getInputs().get(0).getValue());
         IVariableTypeEnvironment outputEnv = context.getTypeEnvironment(op);
-        for (LogicalExpressionReference exprRef : aggOp.getExpressions()) {
-            AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) exprRef.getExpression();
+        for (Mutable<ILogicalExpression> exprRef : aggOp.getExpressions()) {
+            AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) exprRef.getValue();
             aff[i++] = exprJobGen.createSerializableAggregateFunctionFactory(aggFun, aggOpInputEnv, inputSchemas,
                     context);
             intermediateTypes.add(partialAggregationTypeComputer.getType(aggFun, aggOpInputEnv,
@@ -188,9 +188,9 @@
         }
 
         List<LogicalVariable> keyAndDecVariables = new ArrayList<LogicalVariable>();
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gby.getGroupByList())
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getGroupByList())
             keyAndDecVariables.add(p.first);
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gby.getDecorList())
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getDecorList())
             keyAndDecVariables.add(GroupByOperator.getDecorVariable(p));
 
         for (LogicalVariable var : keyAndDecVariables)
@@ -210,7 +210,7 @@
         localInputSchemas[0] = new OperatorSchemaImpl();
         for (i = 0; i < n; i++) {
             AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) aggOp.getMergeExpressions()
-                    .get(i).getExpression();
+                    .get(i).getValue();
             aggFun.getUsedVariables(usedVars);
         }
         i = 0;
@@ -223,7 +223,7 @@
             localInputSchemas[0].addVariable(usedVar);
         for (i = 0; i < n; i++) {
             AggregateFunctionCallExpression mergeFun = (AggregateFunctionCallExpression) aggOp.getMergeExpressions()
-                    .get(i).getExpression();
+                    .get(i).getValue();
             merges[i] = exprJobGen.createSerializableAggregateFunctionFactory(mergeFun, aggOpInputEnv,
                     localInputSchemas, context);
         }
@@ -238,7 +238,7 @@
                 recordDescriptor, new HashSpillableGroupingTableFactory(tpcf, tableSize), false);
 
         contributeOpDesc(builder, gby, gbyOpDesc);
-        ILogicalOperator src = op.getInputs().get(0).getOperator();
+        ILogicalOperator src = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, op, 0);
     }
 }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/HashPartitionMergeExchangePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/HashPartitionMergeExchangePOperator.java
index 0a44b0a..a54f116 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/HashPartitionMergeExchangePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/HashPartitionMergeExchangePOperator.java
@@ -19,11 +19,11 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder.TargetConstraint;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder.TargetConstraint;
 import edu.uci.ics.hyracks.algebricks.core.algebra.data.IBinaryComparatorFactoryProvider;
 import edu.uci.ics.hyracks.algebricks.core.algebra.data.IBinaryHashFunctionFactoryProvider;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -31,6 +31,7 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder.OrderKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty.PropertyType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.INodeDomain;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningRequirementsCoordinator;
@@ -40,7 +41,6 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.PhysicalRequirements;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.StructuralPropertiesVector;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.UnorderedPartitionedProperty;
-import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty.PropertyType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.jobgen.impl.JobGenContext;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.utils.Pair;
@@ -78,7 +78,7 @@
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
         IPartitioningProperty p = new UnorderedPartitionedProperty(new HashSet<LogicalVariable>(partitionFields),
                 domain);
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         List<ILocalStructuralProperty> op2Locals = op2.getDeliveredPhysicalProperties().getLocalProperties();
         List<ILocalStructuralProperty> locals = new ArrayList<ILocalStructuralProperty>();
         for (ILocalStructuralProperty prop : op2Locals) {
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/HybridHashJoinPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/HybridHashJoinPOperator.java
index 378852b..2d3724a 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/HybridHashJoinPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/HybridHashJoinPOperator.java
@@ -24,9 +24,9 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.data.IBinaryComparatorFactoryProvider;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator.JoinKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator.JoinKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder.OrderKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.jobgen.impl.JobGenContext;
@@ -128,9 +128,9 @@
         }
         contributeOpDesc(builder, (AbstractLogicalOperator) op, opDesc);
 
-        ILogicalOperator src1 = op.getInputs().get(0).getOperator();
+        ILogicalOperator src1 = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src1, 0, op, 0);
-        ILogicalOperator src2 = op.getInputs().get(1).getOperator();
+        ILogicalOperator src2 = op.getInputs().get(1).getValue();
         builder.contributeGraphEdge(src2, 0, op, 1);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InMemoryHashJoinPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InMemoryHashJoinPOperator.java
index e1606f0..08406d4 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InMemoryHashJoinPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InMemoryHashJoinPOperator.java
@@ -24,9 +24,9 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.data.IBinaryComparatorFactoryProvider;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator.JoinKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator.JoinKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder.OrderKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
@@ -112,15 +112,15 @@
         }
         contributeOpDesc(builder, (AbstractLogicalOperator) op, opDesc);
 
-        ILogicalOperator src1 = op.getInputs().get(0).getOperator();
+        ILogicalOperator src1 = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src1, 0, op, 0);
-        ILogicalOperator src2 = op.getInputs().get(1).getOperator();
+        ILogicalOperator src2 = op.getInputs().get(1).getValue();
         builder.contributeGraphEdge(src2, 0, op, 1);
     }
 
     @Override
     protected List<ILocalStructuralProperty> deliveredLocalProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op0 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op0 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         IPhysicalPropertiesVector pv0 = op0.getPhysicalOperator().getDeliveredProperties();
         List<ILocalStructuralProperty> lp0 = pv0.getLocalProperties();
         if (lp0 != null) {
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InMemoryStableSortPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InMemoryStableSortPOperator.java
index 47b5cc4..8b8138f 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InMemoryStableSortPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InMemoryStableSortPOperator.java
@@ -76,7 +76,7 @@
 
         IPushRuntimeFactory runtime = new InMemorySortRuntimeFactory(sortFields, nkcf, comps, null);
         builder.contributeMicroOperator(op, runtime, recDescriptor);
-        ILogicalOperator src = op.getInputs().get(0).getOperator();
+        ILogicalOperator src = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, op, 0);
     }
 }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/IndexInsertDeletePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/IndexInsertDeletePOperator.java
index 6e22ac3..276122f 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/IndexInsertDeletePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/IndexInsertDeletePOperator.java
@@ -53,7 +53,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         deliveredProperties = (StructuralPropertiesVector) op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -83,8 +83,8 @@
         IMetadataProvider mp = context.getMetadataProvider();
 
         JobSpecification spec = builder.getJobSpec();
-        RecordDescriptor inputDesc = JobGenHelper.mkRecordDescriptor(op.getInputs().get(0).getOperator(),
-                inputSchemas[0], context);
+        RecordDescriptor inputDesc = JobGenHelper.mkRecordDescriptor(op.getInputs().get(0).getValue(), inputSchemas[0],
+                context);
 
         Pair<IOperatorDescriptor, AlgebricksPartitionConstraint> runtimeAndConstraints = null;
         if (insertDeleteOp.getOperation() == Kind.INSERT)
@@ -96,7 +96,7 @@
 
         builder.contributeHyracksOperator(insertDeleteOp, runtimeAndConstraints.first);
         builder.contributeAlgebricksPartitionConstraint(runtimeAndConstraints.first, runtimeAndConstraints.second);
-        ILogicalOperator src = insertDeleteOp.getInputs().get(0).getOperator();
+        ILogicalOperator src = insertDeleteOp.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, insertDeleteOp, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InsertDeletePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InsertDeletePOperator.java
index 44b54c8..2863aa6 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InsertDeletePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/InsertDeletePOperator.java
@@ -47,7 +47,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         deliveredProperties = (StructuralPropertiesVector) op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -71,8 +71,8 @@
         InsertDeleteOperator insertDeleteOp = (InsertDeleteOperator) op;
         IMetadataProvider mp = context.getMetadataProvider();
         JobSpecification spec = builder.getJobSpec();
-        RecordDescriptor inputDesc = JobGenHelper.mkRecordDescriptor(op.getInputs().get(0).getOperator(),
-                inputSchemas[0], context);
+        RecordDescriptor inputDesc = JobGenHelper.mkRecordDescriptor(op.getInputs().get(0).getValue(), inputSchemas[0],
+                context);
 
         Pair<IOperatorDescriptor, AlgebricksPartitionConstraint> runtimeAndConstraints = null;
         if (insertDeleteOp.getOperation() == Kind.INSERT)
@@ -84,7 +84,7 @@
 
         builder.contributeHyracksOperator(insertDeleteOp, runtimeAndConstraints.first);
         builder.contributeAlgebricksPartitionConstraint(runtimeAndConstraints.first, runtimeAndConstraints.second);
-        ILogicalOperator src = insertDeleteOp.getInputs().get(0).getOperator();
+        ILogicalOperator src = insertDeleteOp.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, insertDeleteOp, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/MicroPreclusteredGroupByPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/MicroPreclusteredGroupByPOperator.java
index 8d424d1..bf59352 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/MicroPreclusteredGroupByPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/MicroPreclusteredGroupByPOperator.java
@@ -2,10 +2,11 @@
 
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
@@ -50,8 +51,8 @@
         int fdColumns[] = new int[numFds];
         IVariableTypeEnvironment env = context.getTypeEnvironment(op);
         int j = 0;
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gby.getDecorList()) {
-            ILogicalExpression expr = p.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getDecorList()) {
+            ILogicalExpression expr = p.second.getValue();
             if (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                 throw new AlgebricksException("pre-sorted group-by expects variable references.");
             }
@@ -67,12 +68,12 @@
         IBinaryComparatorFactory[] comparatorFactories = JobGenHelper.variablesToAscBinaryComparatorFactories(
                 columnList, env, context);
         RecordDescriptor recordDescriptor = JobGenHelper.mkRecordDescriptor(op, opSchema, context);
-        RecordDescriptor inputRecordDesc = JobGenHelper.mkRecordDescriptor(op.getInputs().get(0).getOperator(),
+        RecordDescriptor inputRecordDesc = JobGenHelper.mkRecordDescriptor(op.getInputs().get(0).getValue(),
                 inputSchemas[0], context);
         MicroPreClusteredGroupRuntimeFactory runtime = new MicroPreClusteredGroupRuntimeFactory(keys,
                 comparatorFactories, aggregatorFactory, inputRecordDesc, recordDescriptor, null);
         builder.contributeMicroOperator(gby, runtime, recordDescriptor);
-        ILogicalOperator src = op.getInputs().get(0).getOperator();
+        ILogicalOperator src = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, op, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/NLJoinPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/NLJoinPOperator.java
index 6787158..5978b10 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/NLJoinPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/NLJoinPOperator.java
@@ -24,9 +24,9 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.data.IBinaryBooleanInspector;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ILogicalExpressionJobGen;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator.JoinKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator.JoinKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.BroadcastPartitioningProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
@@ -89,7 +89,7 @@
         AbstractLogicalOperator op = (AbstractLogicalOperator) iop;
 
         if (op.getExecutionMode() == AbstractLogicalOperator.ExecutionMode.PARTITIONED) {
-            AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(1).getOperator();
+            AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(1).getValue();
             IPhysicalPropertiesVector pv1 = op2.getPhysicalOperator().getDeliveredProperties();
             if (pv1 == null) {
                 pp = null;
@@ -126,10 +126,10 @@
         IOperatorSchema[] conditionInputSchemas = new IOperatorSchema[1];
         conditionInputSchemas[0] = propagatedSchema;
         ILogicalExpressionJobGen exprJobGen = context.getExpressionJobGen();
-        IEvaluatorFactory cond = exprJobGen.createEvaluatorFactory(join.getCondition().getExpression(), context
-                .getTypeEnvironment(op), conditionInputSchemas, context);
-        ITuplePairComparatorFactory comparatorFactory = new TuplePairEvaluatorFactory(cond, context
-                .getBinaryBooleanInspector());
+        IEvaluatorFactory cond = exprJobGen.createEvaluatorFactory(join.getCondition().getValue(),
+                context.getTypeEnvironment(op), conditionInputSchemas, context);
+        ITuplePairComparatorFactory comparatorFactory = new TuplePairEvaluatorFactory(cond,
+                context.getBinaryBooleanInspector());
         JobSpecification spec = builder.getJobSpec();
         IOperatorDescriptor opDesc = null;
 
@@ -145,9 +145,9 @@
         }
         contributeOpDesc(builder, (AbstractLogicalOperator) op, opDesc);
 
-        ILogicalOperator src1 = op.getInputs().get(0).getOperator();
+        ILogicalOperator src1 = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src1, 0, op, 0);
-        ILogicalOperator src2 = op.getInputs().get(1).getOperator();
+        ILogicalOperator src2 = op.getInputs().get(1).getValue();
         builder.contributeGraphEdge(src2, 0, op, 1);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/NestedTupleSourcePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/NestedTupleSourcePOperator.java
index 321ecf4..5a4a204 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/NestedTupleSourcePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/NestedTupleSourcePOperator.java
@@ -14,10 +14,11 @@
  */
 package edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
@@ -48,9 +49,8 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        LogicalOperatorReference dataSource = ((NestedTupleSourceOperator) op).getDataSourceReference();
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) dataSource.getOperator().getInputs().get(0)
-                .getOperator();
+        Mutable<ILogicalOperator> dataSource = ((NestedTupleSourceOperator) op).getDataSourceReference();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) dataSource.getValue().getInputs().get(0).getValue();
         IPhysicalPropertiesVector inheritedProps = op2.getDeliveredPhysicalProperties();
         deliveredProperties = (StructuralPropertiesVector) inheritedProps.clone();
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/OneToOneExchangePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/OneToOneExchangePOperator.java
index b7b4668..0ed17d8 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/OneToOneExchangePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/OneToOneExchangePOperator.java
@@ -14,10 +14,10 @@
  */
 package edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical;
 
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder.TargetConstraint;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder.TargetConstraint;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
@@ -41,7 +41,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         deliveredProperties = (StructuralPropertiesVector) op2.getDeliveredPhysicalProperties().clone();
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/PreSortedDistinctByPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/PreSortedDistinctByPOperator.java
index 5fba08d..c97e57f 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/PreSortedDistinctByPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/PreSortedDistinctByPOperator.java
@@ -24,8 +24,8 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder.OrderKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
@@ -66,7 +66,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         IPartitioningProperty pp = op2.getDeliveredPhysicalProperties().getPartitioningProperty();
         List<ILocalStructuralProperty> propsLocal = op2.getDeliveredPhysicalProperties().getLocalProperties();
         deliveredProperties = new StructuralPropertiesVector(pp, propsLocal);
@@ -117,7 +117,7 @@
 
         contributeOpDesc(builder, (AbstractLogicalOperator) op, opDesc);
 
-        ILogicalOperator src = op.getInputs().get(0).getOperator();
+        ILogicalOperator src = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, op, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/PreclusteredGroupByPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/PreclusteredGroupByPOperator.java
index a539315..780e4b4 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/PreclusteredGroupByPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/PreclusteredGroupByPOperator.java
@@ -16,10 +16,11 @@
 
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
@@ -64,8 +65,8 @@
         int numFds = gby.getDecorList().size();
         int fdColumns[] = new int[numFds];
         int j = 0;
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gby.getDecorList()) {
-            ILogicalExpression expr = p.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getDecorList()) {
+            ILogicalExpression expr = p.second.getValue();
             if (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                 throw new AlgebricksException("pre-sorted group-by expects variable references.");
             }
@@ -88,7 +89,7 @@
 
         contributeOpDesc(builder, (AbstractLogicalOperator) op, opDesc);
 
-        ILogicalOperator src = op.getInputs().get(0).getOperator();
+        ILogicalOperator src = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, op, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/ReplicatePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/ReplicatePOperator.java
index ca7675c..b42dd5b 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/ReplicatePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/ReplicatePOperator.java
@@ -51,7 +51,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         deliveredProperties = (StructuralPropertiesVector) op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -67,7 +67,7 @@
 
         SplitOperatorDescriptor splitOpDesc = new SplitOperatorDescriptor(spec, recDescriptor, outputArity);
         contributeOpDesc(builder, (AbstractLogicalOperator) op, splitOpDesc);
-        ILogicalOperator src = op.getInputs().get(0).getOperator();
+        ILogicalOperator src = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, op, 0);
     }
 }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/RunningAggregatePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/RunningAggregatePOperator.java
index 87ccc05..3647deb 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/RunningAggregatePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/RunningAggregatePOperator.java
@@ -16,10 +16,12 @@
 
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ILogicalExpressionJobGen;
@@ -53,7 +55,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         deliveredProperties = (StructuralPropertiesVector) op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -62,8 +64,8 @@
             IPhysicalPropertiesVector reqdByParent) {
         IPartitioningProperty pp = null;
         RunningAggregateOperator ragg = (RunningAggregateOperator) op;
-        for (LogicalExpressionReference exprRef : ragg.getExpressions()) {
-            StatefulFunctionCallExpression f = (StatefulFunctionCallExpression) exprRef.getExpression();
+        for (Mutable<ILogicalExpression> exprRef : ragg.getExpressions()) {
+            StatefulFunctionCallExpression f = (StatefulFunctionCallExpression) exprRef.getValue();
             IPartitioningProperty p = f.getRequiredPartitioningProperty();
             if (p != null) {
                 if (pp == null) {
@@ -84,7 +86,7 @@
             throws AlgebricksException {
         RunningAggregateOperator ragg = (RunningAggregateOperator) op;
         List<LogicalVariable> variables = ragg.getVariables();
-        List<LogicalExpressionReference> expressions = ragg.getExpressions();
+        List<Mutable<ILogicalExpression>> expressions = ragg.getExpressions();
         int[] outColumns = new int[variables.size()];
         for (int i = 0; i < outColumns.length; i++) {
             outColumns[i] = opSchema.findVariable(variables.get(i));
@@ -92,9 +94,9 @@
         IRunningAggregateFunctionFactory[] runningAggFuns = new IRunningAggregateFunctionFactory[expressions.size()];
         ILogicalExpressionJobGen exprJobGen = context.getExpressionJobGen();
         for (int i = 0; i < runningAggFuns.length; i++) {
-            StatefulFunctionCallExpression expr = (StatefulFunctionCallExpression) expressions.get(i).getExpression();
-            runningAggFuns[i] = exprJobGen.createRunningAggregateFunctionFactory(expr, context.getTypeEnvironment(op
-                    .getInputs().get(0).getOperator()), inputSchemas, context);
+            StatefulFunctionCallExpression expr = (StatefulFunctionCallExpression) expressions.get(i).getValue();
+            runningAggFuns[i] = exprJobGen.createRunningAggregateFunctionFactory(expr,
+                    context.getTypeEnvironment(op.getInputs().get(0).getValue()), inputSchemas, context);
         }
 
         // TODO push projections into the operator
@@ -107,7 +109,7 @@
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, opSchema, context);
         builder.contributeMicroOperator(ragg, runtime, recDesc);
         // and contribute one edge from its child
-        ILogicalOperator src = ragg.getInputs().get(0).getOperator();
+        ILogicalOperator src = ragg.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, ragg, 0);
 
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SinkPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SinkPOperator.java
index fe501e2..0375246 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SinkPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SinkPOperator.java
@@ -43,7 +43,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         deliveredProperties = (StructuralPropertiesVector) op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -60,7 +60,7 @@
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, propagatedSchema, context);
         SinkRuntimeFactory runtime = new SinkRuntimeFactory();
         builder.contributeMicroOperator(op, runtime, recDesc);
-        ILogicalOperator src = op.getInputs().get(0).getOperator();
+        ILogicalOperator src = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, op, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SinkWritePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SinkWritePOperator.java
index ec664bb..123b0e1 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SinkWritePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SinkWritePOperator.java
@@ -14,11 +14,12 @@
  */
 package edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
@@ -56,7 +57,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        ILogicalOperator op2 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op2 = op.getInputs().get(0).getValue();
         deliveredProperties = op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -77,8 +78,8 @@
         WriteOperator write = (WriteOperator) op;
         int[] columns = new int[write.getExpressions().size()];
         int i = 0;
-        for (LogicalExpressionReference exprRef : write.getExpressions()) {
-            ILogicalExpression expr = exprRef.getExpression();
+        for (Mutable<ILogicalExpression> exprRef : write.getExpressions()) {
+            ILogicalExpression expr = exprRef.getValue();
             if (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                 throw new NotImplementedException("Only writing variable expressions is supported.");
             }
@@ -87,8 +88,8 @@
             columns[i++] = inputSchemas[0].findVariable(v);
         }
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, propagatedSchema, context);
-        RecordDescriptor inputDesc = JobGenHelper.mkRecordDescriptor(op.getInputs().get(0).getOperator(),
-                inputSchemas[0], context);
+        RecordDescriptor inputDesc = JobGenHelper.mkRecordDescriptor(op.getInputs().get(0).getValue(), inputSchemas[0],
+                context);
 
         IPrinterFactory[] pf = JobGenHelper.mkPrinterFactories(inputSchemas[0], context.getTypeEnvironment(op),
                 context, columns);
@@ -99,7 +100,7 @@
                 columns, pf, inputDesc);
 
         builder.contributeMicroOperator(write, runtime.first, recDesc, runtime.second);
-        ILogicalOperator src = write.getInputs().get(0).getOperator();
+        ILogicalOperator src = write.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, write, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SortMergeExchangePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SortMergeExchangePOperator.java
index 185a671..98c9be3 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SortMergeExchangePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SortMergeExchangePOperator.java
@@ -17,16 +17,17 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder.TargetConstraint;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder.TargetConstraint;
 import edu.uci.ics.hyracks.algebricks.core.algebra.data.IBinaryComparatorFactoryProvider;
 import edu.uci.ics.hyracks.algebricks.core.algebra.data.IBinaryHashFunctionFactoryProvider;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty.PropertyType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningRequirementsCoordinator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
@@ -34,7 +35,6 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.OrderColumn;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.PhysicalRequirements;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.StructuralPropertiesVector;
-import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty.PropertyType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.jobgen.impl.JobGenContext;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.utils.Pair;
@@ -79,7 +79,7 @@
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context)
             throws AlgebricksException {
-        AbstractLogicalOperator inp1 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator inp1 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         IPhysicalPropertiesVector pv1 = inp1.getDeliveredPhysicalProperties();
         if (pv1 == null) {
             inp1.computeDeliveredPhysicalProperties(context);
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StableSortPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StableSortPOperator.java
index 623bd90..73c7dd6 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StableSortPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StableSortPOperator.java
@@ -92,7 +92,7 @@
         ExternalSortOperatorDescriptor sortOpDesc = new ExternalSortOperatorDescriptor(spec, maxNumberOfFrames,
                 sortFields, nkcf, comps, recDescriptor);
         contributeOpDesc(builder, (AbstractLogicalOperator) op, sortOpDesc);
-        ILogicalOperator src = op.getInputs().get(0).getOperator();
+        ILogicalOperator src = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, op, 0);
     }
 }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamDiePOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamDiePOperator.java
index ee2cee3..82ea31c 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamDiePOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamDiePOperator.java
@@ -50,7 +50,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        ILogicalOperator op2 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op2 = op.getInputs().get(0).getValue();
         deliveredProperties = op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -69,13 +69,13 @@
         DieOperator die = (DieOperator) op;
         ILogicalExpressionJobGen exprJobGen = context.getExpressionJobGen();
         IVariableTypeEnvironment env = context.getTypeEnvironment(op);
-        IEvaluatorFactory afterObjectsFact = exprJobGen.createEvaluatorFactory(die.getAfterObjects().getExpression(),
+        IEvaluatorFactory afterObjectsFact = exprJobGen.createEvaluatorFactory(die.getAfterObjects().getValue(),
                 env, inputSchemas, context);
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, propagatedSchema, context);
         StreamDieRuntimeFactory runtime = new StreamDieRuntimeFactory(afterObjectsFact, null,
                 context.getBinaryIntegerInspector());
         builder.contributeMicroOperator(die, runtime, recDesc);
-        ILogicalOperator src = die.getInputs().get(0).getOperator();
+        ILogicalOperator src = die.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, die, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamLimitPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamLimitPOperator.java
index a70d6c8..a31b2da 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamLimitPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamLimitPOperator.java
@@ -55,7 +55,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        ILogicalOperator op2 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op2 = op.getInputs().get(0).getValue();
         deliveredProperties = op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -78,17 +78,17 @@
         LimitOperator limit = (LimitOperator) op;
         ILogicalExpressionJobGen exprJobGen = context.getExpressionJobGen();
         IVariableTypeEnvironment env = context.getTypeEnvironment(op);
-        IEvaluatorFactory maxObjectsFact = exprJobGen.createEvaluatorFactory(limit.getMaxObjects().getExpression(),
+        IEvaluatorFactory maxObjectsFact = exprJobGen.createEvaluatorFactory(limit.getMaxObjects().getValue(),
                 env, inputSchemas, context);
-        ILogicalExpression offsetExpr = limit.getOffset().getExpression();
+        ILogicalExpression offsetExpr = limit.getOffset().getValue();
         IEvaluatorFactory offsetFact = (offsetExpr == null) ? null : exprJobGen.createEvaluatorFactory(offsetExpr, env,
                 inputSchemas, context);
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, propagatedSchema, context);
-        StreamLimitRuntimeFactory runtime = new StreamLimitRuntimeFactory(maxObjectsFact, offsetFact, null, context
-                .getBinaryIntegerInspector());
+        StreamLimitRuntimeFactory runtime = new StreamLimitRuntimeFactory(maxObjectsFact, offsetFact, null,
+                context.getBinaryIntegerInspector());
         builder.contributeMicroOperator(limit, runtime, recDesc);
         // and contribute one edge from its child
-        ILogicalOperator src = limit.getInputs().get(0).getOperator();
+        ILogicalOperator src = limit.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, limit, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamProjectPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamProjectPOperator.java
index e28d580..94e2135 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamProjectPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamProjectPOperator.java
@@ -64,7 +64,7 @@
         StreamProjectRuntimeFactory runtime = new StreamProjectRuntimeFactory(projectionList);
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, propagatedSchema, context);
         builder.contributeMicroOperator(project, runtime, recDesc);
-        ILogicalOperator src = project.getInputs().get(0).getOperator();
+        ILogicalOperator src = project.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, project, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamSelectPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamSelectPOperator.java
index 4544e0e..b4112c8 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamSelectPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StreamSelectPOperator.java
@@ -44,7 +44,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        ILogicalOperator op2 = op.getInputs().get(0).getOperator();
+        ILogicalOperator op2 = op.getInputs().get(0).getValue();
         deliveredProperties = op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -60,7 +60,7 @@
             throws AlgebricksException {
         SelectOperator select = (SelectOperator) op;
         ILogicalExpressionJobGen exprJobGen = context.getExpressionJobGen();
-        IEvaluatorFactory cond = exprJobGen.createEvaluatorFactory(select.getCondition().getExpression(),
+        IEvaluatorFactory cond = exprJobGen.createEvaluatorFactory(select.getCondition().getValue(),
                 context.getTypeEnvironment(op), inputSchemas, context);
         StreamSelectRuntimeFactory runtime = new StreamSelectRuntimeFactory(cond, null,
                 context.getBinaryBooleanInspector());
@@ -68,7 +68,7 @@
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, opSchema, context);
         builder.contributeMicroOperator(select, runtime, recDesc);
         // and contribute one edge from its child
-        ILogicalOperator src = select.getInputs().get(0).getOperator();
+        ILogicalOperator src = select.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, select, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StringStreamingScriptPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StringStreamingScriptPOperator.java
index 3ca3f40..dfab5ed 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StringStreamingScriptPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/StringStreamingScriptPOperator.java
@@ -26,8 +26,8 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.jobgen.impl.JobGenHelper;
 import edu.uci.ics.hyracks.algebricks.core.algebra.runtime.operators.std.StringStreamingRuntimeFactory;
 import edu.uci.ics.hyracks.algebricks.core.algebra.scripting.IScriptDescription;
-import edu.uci.ics.hyracks.algebricks.core.algebra.scripting.StringStreamingScriptDescription;
 import edu.uci.ics.hyracks.algebricks.core.algebra.scripting.IScriptDescription.ScriptKind;
+import edu.uci.ics.hyracks.algebricks.core.algebra.scripting.StringStreamingScriptDescription;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
 
@@ -64,7 +64,7 @@
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, propagatedSchema, context);
         builder.contributeMicroOperator(scriptOp, runtime, recDesc);
         // and contribute one edge from its child
-        ILogicalOperator src = scriptOp.getInputs().get(0).getOperator();
+        ILogicalOperator src = scriptOp.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, scriptOp, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SubplanPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SubplanPOperator.java
index 7852cdc..4e6ef69 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SubplanPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/SubplanPOperator.java
@@ -17,11 +17,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
@@ -53,7 +54,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         IPhysicalPropertiesVector childsProperties = op2.getPhysicalOperator().getDeliveredProperties();
         List<ILocalStructuralProperty> propsLocal = new ArrayList<ILocalStructuralProperty>();
         if (childsProperties.getLocalProperties() != null) {
@@ -62,8 +63,8 @@
         // ... get local properties for newly created variables...
         SubplanOperator subplan = (SubplanOperator) op;
         for (ILogicalPlan plan : subplan.getNestedPlans()) {
-            for (LogicalOperatorReference r : plan.getRoots()) {
-                AbstractLogicalOperator rOp = (AbstractLogicalOperator) r.getOperator();
+            for (Mutable<ILogicalOperator> r : plan.getRoots()) {
+                AbstractLogicalOperator rOp = (AbstractLogicalOperator) r.getValue();
                 propsLocal.addAll(rOp.getPhysicalOperator().getDeliveredProperties().getLocalProperties());
             }
         }
@@ -88,7 +89,7 @@
         AlgebricksPipeline[] subplans = compileSubplans(inputSchemas[0], subplan, opSchema, context);
         assert (subplans.length == 1);
         AlgebricksPipeline np = subplans[0];
-        RecordDescriptor inputRecordDesc = JobGenHelper.mkRecordDescriptor(op.getInputs().get(0).getOperator(),
+        RecordDescriptor inputRecordDesc = JobGenHelper.mkRecordDescriptor(op.getInputs().get(0).getValue(),
                 inputSchemas[0], context);
         INullWriterFactory[] nullWriterFactories = new INullWriterFactory[np.getOutputWidth()];
         for (int i = 0; i < nullWriterFactories.length; i++) {
@@ -99,7 +100,7 @@
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, opSchema, context);
         builder.contributeMicroOperator(subplan, runtime, recDesc);
 
-        ILogicalOperator src = op.getInputs().get(0).getOperator();
+        ILogicalOperator src = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, op, 0);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/UnionAllPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/UnionAllPOperator.java
index 1091365..da88dd9 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/UnionAllPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/UnionAllPOperator.java
@@ -52,7 +52,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         IPartitioningProperty pp = op2.getDeliveredPhysicalProperties().getPartitioningProperty();
         this.deliveredProperties = new StructuralPropertiesVector(pp, new ArrayList<ILocalStructuralProperty>(0));
 
@@ -92,9 +92,9 @@
         // level, there is no restrictions
         UnionAllOperatorDescriptor opDesc = new UnionAllOperatorDescriptor(spec, 2, recordDescriptor);
         contributeOpDesc(builder, (AbstractLogicalOperator) op, opDesc);
-        ILogicalOperator src1 = op.getInputs().get(0).getOperator();
+        ILogicalOperator src1 = op.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src1, 0, op, 0);
-        ILogicalOperator src2 = op.getInputs().get(1).getOperator();
+        ILogicalOperator src2 = op.getInputs().get(1).getValue();
         builder.contributeGraphEdge(src2, 0, op, 1);
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/UnnestPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/UnnestPOperator.java
index 5353316..8f838ba 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/UnnestPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/UnnestPOperator.java
@@ -21,9 +21,9 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ILogicalExpressionJobGen;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
@@ -48,7 +48,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         deliveredProperties = op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -62,7 +62,7 @@
                     + unnest.getPositionalVariable());
         }
         int outCol = opSchema.findVariable(unnest.getVariable());
-        ILogicalExpression unnestExpr = unnest.getExpressionRef().getExpression();
+        ILogicalExpression unnestExpr = unnest.getExpressionRef().getValue();
         ILogicalExpressionJobGen exprJobGen = context.getExpressionJobGen();
         boolean exit = false;
         if (unnestExpr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
@@ -77,13 +77,13 @@
             throw new AlgebricksException("Unnest expression " + unnestExpr + " is not an unnesting function call.");
         }
         UnnestingFunctionCallExpression agg = (UnnestingFunctionCallExpression) unnestExpr;
-        IUnnestingFunctionFactory unnestingFactory = exprJobGen.createUnnestingFunctionFactory(agg, context
-                .getTypeEnvironment(op.getInputs().get(0).getOperator()), inputSchemas, context);
+        IUnnestingFunctionFactory unnestingFactory = exprJobGen.createUnnestingFunctionFactory(agg,
+                context.getTypeEnvironment(op.getInputs().get(0).getValue()), inputSchemas, context);
         int[] projectionList = JobGenHelper.projectAllVariables(opSchema);
         UnnestRuntimeFactory unnestRuntime = new UnnestRuntimeFactory(outCol, unnestingFactory, projectionList);
         RecordDescriptor recDesc = JobGenHelper.mkRecordDescriptor(op, opSchema, context);
         builder.contributeMicroOperator(unnest, unnestRuntime, recDesc);
-        ILogicalOperator src = unnest.getInputs().get(0).getOperator();
+        ILogicalOperator src = unnest.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, unnest, 0);
     }
 }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/WriteResultPOperator.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/WriteResultPOperator.java
index 676d6e6..d1f0340 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/WriteResultPOperator.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/operators/physical/WriteResultPOperator.java
@@ -53,7 +53,7 @@
 
     @Override
     public void computeDeliveredProperties(ILogicalOperator op, IOptimizationContext context) {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         deliveredProperties = (StructuralPropertiesVector) op2.getDeliveredPhysicalProperties().clone();
     }
 
@@ -83,7 +83,7 @@
 
         builder.contributeHyracksOperator(writeResultOp, runtimeAndConstraints.first);
         builder.contributeAlgebricksPartitionConstraint(runtimeAndConstraints.first, runtimeAndConstraints.second);
-        ILogicalOperator src = writeResultOp.getInputs().get(0).getOperator();
+        ILogicalOperator src = writeResultOp.getInputs().get(0).getValue();
         builder.contributeGraphEdge(src, 0, writeResultOp, 0);
     }
 }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/plan/ALogicalPlanImpl.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/plan/ALogicalPlanImpl.java
index 34fc909..103f534 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/plan/ALogicalPlanImpl.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/plan/ALogicalPlanImpl.java
@@ -17,34 +17,36 @@
 import java.util.ArrayList;

 import java.util.List;

 

+import org.apache.commons.lang3.mutable.Mutable;

+

+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;

 

 /*

  * Author: Guangqiang Li

  * Created on Jul 9, 2009 

  */

 public class ALogicalPlanImpl implements ILogicalPlan {

-    private List<LogicalOperatorReference> roots;

+    private List<Mutable<ILogicalOperator>> roots;

 

     public ALogicalPlanImpl() {

-        this.roots = new ArrayList<LogicalOperatorReference>();

+        this.roots = new ArrayList<Mutable<ILogicalOperator>>();

     }

 

-    public ALogicalPlanImpl(List<LogicalOperatorReference> roots) {

+    public ALogicalPlanImpl(List<Mutable<ILogicalOperator>> roots) {

         this.roots = roots;

     }

 

-    public ALogicalPlanImpl(LogicalOperatorReference root) {

-        roots = new ArrayList<LogicalOperatorReference>(1);

+    public ALogicalPlanImpl(Mutable<ILogicalOperator> root) {

+        roots = new ArrayList<Mutable<ILogicalOperator>>(1);

         roots.add(root);

     }

 

-    public List<LogicalOperatorReference> getRoots() {

+    public List<Mutable<ILogicalOperator>> getRoots() {

         return roots;

     }

 

-    public void setRoots(List<LogicalOperatorReference> roots) {

+    public void setRoots(List<Mutable<ILogicalOperator>> roots) {

         this.roots = roots;

     }

 }

diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java
index 9a01651..05ae1ec 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java
@@ -16,9 +16,10 @@
 
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
@@ -32,6 +33,7 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IndexInsertDeleteOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.InsertDeleteOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.InsertDeleteOperator.Kind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
@@ -49,7 +51,6 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteResultOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.InsertDeleteOperator.Kind;
 import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalOperatorVisitor;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.utils.Pair;
@@ -104,14 +105,14 @@
     @Override
     public String visitInnerJoinOperator(InnerJoinOperator op, Integer indent) {
         StringBuilder buffer = new StringBuilder();
-        addIndent(buffer, indent).append("join (").append(op.getCondition().getExpression()).append(")");
+        addIndent(buffer, indent).append("join (").append(op.getCondition().getValue()).append(")");
         return buffer.toString();
     }
 
     @Override
     public String visitLeftOuterJoinOperator(LeftOuterJoinOperator op, Integer indent) {
         StringBuilder buffer = new StringBuilder();
-        addIndent(buffer, indent).append("left outer join (").append(op.getCondition().getExpression()).append(")");
+        addIndent(buffer, indent).append("left outer join (").append(op.getCondition().getValue()).append(")");
         return buffer.toString();
     }
 
@@ -126,7 +127,7 @@
     public String visitOrderOperator(OrderOperator op, Integer indent) {
         StringBuilder buffer = new StringBuilder();
         addIndent(buffer, indent).append("order ");
-        for (Pair<OrderOperator.IOrder, LogicalExpressionReference> p : op.getOrderExpressions()) {
+        for (Pair<OrderOperator.IOrder, Mutable<ILogicalExpression>> p : op.getOrderExpressions()) {
             String fst;
             switch (p.first.getKind()) {
                 case ASC: {
@@ -141,7 +142,7 @@
                     fst = p.first.getExpressionRef().toString();
                 }
             }
-            buffer.append("(" + fst + ", " + p.second.getExpression() + ") ");
+            buffer.append("(" + fst + ", " + p.second.getValue() + ") ");
         }
         return buffer.toString();
     }
@@ -172,7 +173,7 @@
     @Override
     public String visitSelectOperator(SelectOperator op, Integer indent) {
         StringBuilder buffer = new StringBuilder();
-        addIndent(buffer, indent).append("select " + "(" + op.getCondition().getExpression() + ")");
+        addIndent(buffer, indent).append("select " + "(" + op.getCondition().getValue() + ")");
         return buffer.toString();
     }
 
@@ -215,7 +216,7 @@
         if (op.getPositionalVariable() != null) {
             buffer.append(" at " + op.getPositionalVariable());
         }
-        buffer.append(" <- " + op.getExpressionRef().getExpression());
+        buffer.append(" <- " + op.getExpressionRef().getValue());
         return buffer.toString();
     }
 
@@ -223,7 +224,7 @@
     public String visitUnnestMapOperator(UnnestMapOperator op, Integer indent) {
         StringBuilder buffer = new StringBuilder();
         addIndent(buffer, indent).append(
-                "unnest-map " + op.getVariables() + " <- " + op.getExpressionRef().getExpression());
+                "unnest-map " + op.getVariables() + " <- " + op.getExpressionRef().getValue());
         return buffer.toString();
     }
 
@@ -238,8 +239,8 @@
     @Override
     public String visitLimitOperator(LimitOperator op, Integer indent) {
         StringBuilder buffer = new StringBuilder();
-        addIndent(buffer, indent).append("limit " + op.getMaxObjects().getExpression());
-        ILogicalExpression offset = op.getOffset().getExpression();
+        addIndent(buffer, indent).append("limit " + op.getMaxObjects().getValue());
+        ILogicalExpression offset = op.getOffset().getValue();
         if (offset != null) {
             buffer.append(", " + offset);
         }
@@ -249,7 +250,7 @@
     @Override
     public String visitDieOperator(DieOperator op, Integer indent) {
         StringBuilder buffer = new StringBuilder();
-        addIndent(buffer, indent).append("die after " + op.getAfterObjects().getExpression());
+        addIndent(buffer, indent).append("die after " + op.getAfterObjects().getValue());
         return buffer.toString();
     }
 
@@ -296,16 +297,16 @@
         return buffer.toString();
     }
 
-    private void pprintExprList(List<LogicalExpressionReference> expressions, StringBuilder buffer) {
+    private void pprintExprList(List<Mutable<ILogicalExpression>> expressions, StringBuilder buffer) {
         buffer.append("[");
         boolean first = true;
-        for (LogicalExpressionReference exprRef : expressions) {
+        for (Mutable<ILogicalExpression> exprRef : expressions) {
             if (first) {
                 first = false;
             } else {
                 buffer.append(", ");
             }
-            buffer.append(exprRef.getExpression());
+            buffer.append(exprRef.getValue());
         }
         buffer.append("]");
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/prettyprint/PlanPrettyPrinter.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/prettyprint/PlanPrettyPrinter.java
index 91f28f6..174db0b 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/prettyprint/PlanPrettyPrinter.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/prettyprint/PlanPrettyPrinter.java
@@ -14,9 +14,11 @@
  */

 package edu.uci.ics.hyracks.algebricks.core.algebra.prettyprint;

 

+import org.apache.commons.lang3.mutable.Mutable;

+

+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;

 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IPhysicalOperator;

-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;

 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;

 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;

@@ -24,14 +26,14 @@
 public class PlanPrettyPrinter {

     public static void printPlan(ILogicalPlan plan, StringBuilder out, LogicalOperatorPrettyPrintVisitor pvisitor,

             int indent) throws AlgebricksException {

-        for (LogicalOperatorReference root : plan.getRoots()) {

-            printOperator((AbstractLogicalOperator) root.getOperator(), out, pvisitor, indent);

+        for (Mutable<ILogicalOperator> root : plan.getRoots()) {

+            printOperator((AbstractLogicalOperator) root.getValue(), out, pvisitor, indent);

         }

     }

 

     public static void printPhysicalOps(ILogicalPlan plan, StringBuilder out, int indent) {

-        for (LogicalOperatorReference root : plan.getRoots()) {

-            printPhysicalOperator((AbstractLogicalOperator) root.getOperator(), indent, out);

+        for (Mutable<ILogicalOperator> root : plan.getRoots()) {

+            printPhysicalOperator((AbstractLogicalOperator) root.getValue(), indent, out);

         }

     }

 

@@ -48,8 +50,8 @@
             appendln(out, " -- |" + op.getExecutionMode() + "|");

         }

 

-        for (LogicalOperatorReference i : op.getInputs()) {

-            printOperator((AbstractLogicalOperator) i.getOperator(), out, pvisitor, indent + 2);

+        for (Mutable<ILogicalOperator> i : op.getInputs()) {

+            printOperator((AbstractLogicalOperator) i.getValue(), out, pvisitor, indent + 2);

         }

 

     }

@@ -69,8 +71,8 @@
             }

         }

 

-        for (LogicalOperatorReference i : op.getInputs()) {

-            printPhysicalOperator((AbstractLogicalOperator) i.getOperator(), indent + 2, out);

+        for (Mutable<ILogicalOperator> i : op.getInputs()) {

+            printPhysicalOperator((AbstractLogicalOperator) i.getValue(), indent + 2, out);

         }

 

     }

diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/runtime/jobgen/impl/PlanCompiler.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/runtime/jobgen/impl/PlanCompiler.java
index afab295..ab170c9 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/runtime/jobgen/impl/PlanCompiler.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/runtime/jobgen/impl/PlanCompiler.java
@@ -20,17 +20,18 @@
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IOperatorSchema;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.api.job.JobSpecification;
 
 public class PlanCompiler {
     private JobGenContext context;
-    private Map<LogicalOperatorReference, List<LogicalOperatorReference>> operatorVisitedToParents = new HashMap<LogicalOperatorReference, List<LogicalOperatorReference>>();
+    private Map<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>> operatorVisitedToParents = new HashMap<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>>();
 
     public PlanCompiler(JobGenContext context) {
         this.context = context;
@@ -44,9 +45,9 @@
         JobSpecification spec = new JobSpecification();
         List<ILogicalOperator> rootOps = new ArrayList<ILogicalOperator>();
         IHyracksJobBuilder builder = new JobBuilder(spec, context.getClusterLocations());
-        for (LogicalOperatorReference opRef : plan.getRoots()) {
+        for (Mutable<ILogicalOperator> opRef : plan.getRoots()) {
             compileOpRef(opRef, spec, builder, outerPlanSchema);
-            rootOps.add(opRef.getOperator());
+            rootOps.add(opRef.getValue());
         }
         reviseEdges(builder);
         operatorVisitedToParents.clear();
@@ -54,24 +55,24 @@
         return spec;
     }
 
-    private void compileOpRef(LogicalOperatorReference opRef, JobSpecification spec, IHyracksJobBuilder builder,
+    private void compileOpRef(Mutable<ILogicalOperator> opRef, JobSpecification spec, IHyracksJobBuilder builder,
             IOperatorSchema outerPlanSchema) throws AlgebricksException {
-        ILogicalOperator op = opRef.getOperator();
+        ILogicalOperator op = opRef.getValue();
         int n = op.getInputs().size();
         IOperatorSchema[] schemas = new IOperatorSchema[n];
         int i = 0;
-        for (LogicalOperatorReference opRef2 : op.getInputs()) {
-            List<LogicalOperatorReference> parents = operatorVisitedToParents.get(opRef2);
+        for (Mutable<ILogicalOperator> opRef2 : op.getInputs()) {
+            List<Mutable<ILogicalOperator>> parents = operatorVisitedToParents.get(opRef2);
             if (parents == null) {
-                parents = new ArrayList<LogicalOperatorReference>();
+                parents = new ArrayList<Mutable<ILogicalOperator>>();
                 operatorVisitedToParents.put(opRef2, parents);
                 parents.add(opRef);
                 compileOpRef(opRef2, spec, builder, outerPlanSchema);
-                schemas[i++] = context.getSchema(opRef2.getOperator());
+                schemas[i++] = context.getSchema(opRef2.getValue());
             } else {
                 if (!parents.contains(opRef))
                     parents.add(opRef);
-                schemas[i++] = context.getSchema(opRef2.getOperator());
+                schemas[i++] = context.getSchema(opRef2.getValue());
                 continue;
             }
         }
@@ -86,14 +87,14 @@
         /**
          * revise the edges for the case of replicate operator
          */
-        for (Entry<LogicalOperatorReference, List<LogicalOperatorReference>> entry : operatorVisitedToParents
+        for (Entry<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>> entry : operatorVisitedToParents
                 .entrySet()) {
-            LogicalOperatorReference child = entry.getKey();
-            List<LogicalOperatorReference> parents = entry.getValue();
+            Mutable<ILogicalOperator> child = entry.getKey();
+            List<Mutable<ILogicalOperator>> parents = entry.getValue();
             if (parents.size() > 1) {
                 int i = 0;
-                for (LogicalOperatorReference parent : parents) {
-                    builder.contributeGraphEdge(child.getOperator(), i, parent.getOperator(), 0);
+                for (Mutable<ILogicalOperator> parent : parents) {
+                    builder.contributeGraphEdge(child.getValue(), i, parent.getValue(), 0);
                     i++;
                 }
             }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/typing/OpRefTypeEnvPointer.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/typing/OpRefTypeEnvPointer.java
index 7c4aaa1..417b900 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/typing/OpRefTypeEnvPointer.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/typing/OpRefTypeEnvPointer.java
@@ -1,21 +1,23 @@
 package edu.uci.ics.hyracks.algebricks.core.algebra.typing;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
 
 public class OpRefTypeEnvPointer implements ITypeEnvPointer {
 
-    private final LogicalOperatorReference op;
+    private final Mutable<ILogicalOperator> op;
     private final ITypingContext ctx;
 
-    public OpRefTypeEnvPointer(LogicalOperatorReference op, ITypingContext ctx) {
+    public OpRefTypeEnvPointer(Mutable<ILogicalOperator> op, ITypingContext ctx) {
         this.op = op;
         this.ctx = ctx;
     }
 
     @Override
     public IVariableTypeEnvironment getTypeEnv() {
-        return ctx.getOutputTypeEnvironment(op.getOperator());
+        return ctx.getOutputTypeEnvironment(op.getValue());
     }
 
     @Override
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/typing/PropagateOperatorInputsTypeEnvironment.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/typing/PropagateOperatorInputsTypeEnvironment.java
index 26109c6..15504cb 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/typing/PropagateOperatorInputsTypeEnvironment.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/typing/PropagateOperatorInputsTypeEnvironment.java
@@ -3,8 +3,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IExpressionTypeComputer;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -40,8 +41,8 @@
         if (t != null) {
             return t;
         }
-        for (LogicalOperatorReference r : op.getInputs()) {
-            ILogicalOperator c = r.getOperator();
+        for (Mutable<ILogicalOperator> r : op.getInputs()) {
+            ILogicalOperator c = r.getValue();
             IVariableTypeEnvironment env = ctx.getOutputTypeEnvironment(c);
             Object t2 = env.getVarType(var, nonNullVariableList);
             if (t2 != null) {
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
index d1299ff..4604198 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
@@ -16,10 +16,12 @@
 
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
@@ -35,15 +37,15 @@
 public class OperatorManipulationUtil {
 
     // Transforms all NestedTupleSource operators to EmptyTupleSource operators
-    public static void ntsToEts(LogicalOperatorReference opRef, IOptimizationContext context)
+    public static void ntsToEts(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
             throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
             EmptyTupleSourceOperator ets = new EmptyTupleSourceOperator();
             context.computeAndSetTypeEnvironmentForOperator(ets);
-            opRef.setOperator(ets);
+            opRef.setValue(ets);
         } else {
-            for (LogicalOperatorReference i : opRef.getOperator().getInputs()) {
+            for (Mutable<ILogicalOperator> i : opRef.getValue().getInputs()) {
                 ntsToEts(i, context);
             }
         }
@@ -52,20 +54,20 @@
     public static ILogicalOperator eliminateSingleSubplanOverEts(SubplanOperator subplan) {
         if (subplan.getNestedPlans().size() > 1) {
             // not a single subplan
-            List<LogicalOperatorReference> subInpList = subplan.getInputs();
+            List<Mutable<ILogicalOperator>> subInpList = subplan.getInputs();
             subInpList.clear();
-            subInpList.add(new LogicalOperatorReference(new EmptyTupleSourceOperator()));
+            subInpList.add(new MutableObject<ILogicalOperator>(new EmptyTupleSourceOperator()));
             return subplan;
         }
         ILogicalPlan plan = subplan.getNestedPlans().get(0);
         if (plan.getRoots().size() > 1) {
             // not a single subplan
-            List<LogicalOperatorReference> subInpList = subplan.getInputs();
+            List<Mutable<ILogicalOperator>> subInpList = subplan.getInputs();
             subInpList.clear();
-            subInpList.add(new LogicalOperatorReference(new EmptyTupleSourceOperator()));
+            subInpList.add(new MutableObject<ILogicalOperator>(new EmptyTupleSourceOperator()));
             return subplan;
         }
-        return plan.getRoots().get(0).getOperator();
+        return plan.getRoots().get(0).getValue();
     }
 
     public static boolean setOperatorMode(AbstractLogicalOperator op) {
@@ -75,7 +77,7 @@
                 // ILogicalExpression e = ((UnnestOperator) op).getExpression();
                 // if (AnalysisUtil.isDataSetCall(e)) {
                 op.setExecutionMode(AbstractLogicalOperator.ExecutionMode.PARTITIONED);
-                AbstractLogicalOperator child = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+                AbstractLogicalOperator child = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
                 if (child.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
                     child.setExecutionMode(AbstractLogicalOperator.ExecutionMode.PARTITIONED);
                 }
@@ -85,8 +87,8 @@
             }
             case NESTEDTUPLESOURCE: {
                 NestedTupleSourceOperator nts = (NestedTupleSourceOperator) op;
-                AbstractLogicalOperator prevOp = (AbstractLogicalOperator) nts.getDataSourceReference().getOperator()
-                        .getInputs().get(0).getOperator();
+                AbstractLogicalOperator prevOp = (AbstractLogicalOperator) nts.getDataSourceReference().getValue()
+                        .getInputs().get(0).getValue();
                 if (prevOp.getExecutionMode() != AbstractLogicalOperator.ExecutionMode.UNPARTITIONED) {
                     nts.setExecutionMode(AbstractLogicalOperator.ExecutionMode.LOCAL);
                     change = true;
@@ -105,9 +107,9 @@
                     }
                 }
 
-                for (LogicalOperatorReference i : op.getInputs()) {
+                for (Mutable<ILogicalOperator> i : op.getInputs()) {
                     boolean exit = false;
-                    AbstractLogicalOperator inputOp = (AbstractLogicalOperator) i.getOperator();
+                    AbstractLogicalOperator inputOp = (AbstractLogicalOperator) i.getValue();
                     switch (inputOp.getExecutionMode()) {
                         case PARTITIONED: {
                             op.setExecutionMode(AbstractLogicalOperator.ExecutionMode.PARTITIONED);
@@ -134,22 +136,22 @@
     public static void substituteVarRec(AbstractLogicalOperator op, LogicalVariable v1, LogicalVariable v2,
             boolean goThroughNts, ITypingContext ctx) throws AlgebricksException {
         VariableUtilities.substituteVariables(op, v1, v2, goThroughNts, ctx);
-        for (LogicalOperatorReference opRef2 : op.getInputs()) {
-            substituteVarRec((AbstractLogicalOperator) opRef2.getOperator(), v1, v2, goThroughNts, ctx);
+        for (Mutable<ILogicalOperator> opRef2 : op.getInputs()) {
+            substituteVarRec((AbstractLogicalOperator) opRef2.getValue(), v1, v2, goThroughNts, ctx);
         }
         if (op.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE && goThroughNts) {
             NestedTupleSourceOperator nts = (NestedTupleSourceOperator) op;
             if (nts.getDataSourceReference() != null) {
-                AbstractLogicalOperator op2 = (AbstractLogicalOperator) nts.getDataSourceReference().getOperator()
-                        .getInputs().get(0).getOperator();
+                AbstractLogicalOperator op2 = (AbstractLogicalOperator) nts.getDataSourceReference().getValue()
+                        .getInputs().get(0).getValue();
                 substituteVarRec(op2, v1, v2, goThroughNts, ctx);
             }
         }
         if (op.hasNestedPlans()) {
             AbstractOperatorWithNestedPlans aonp = (AbstractOperatorWithNestedPlans) op;
             for (ILogicalPlan p : aonp.getNestedPlans()) {
-                for (LogicalOperatorReference ref : p.getRoots()) {
-                    AbstractLogicalOperator aop = (AbstractLogicalOperator) ref.getOperator();
+                for (Mutable<ILogicalOperator> ref : p.getRoots()) {
+                    AbstractLogicalOperator aop = (AbstractLogicalOperator) ref.getValue();
                     substituteVarRec(aop, v1, v2, goThroughNts, ctx);
                 }
             }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/util/OperatorPropertiesUtil.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/util/OperatorPropertiesUtil.java
index 2223991..97bd8ca 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/util/OperatorPropertiesUtil.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/util/OperatorPropertiesUtil.java
@@ -18,12 +18,13 @@
 import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
@@ -84,8 +85,8 @@
         if (op.hasNestedPlans()) {
             AbstractOperatorWithNestedPlans s = (AbstractOperatorWithNestedPlans) op;
             for (ILogicalPlan p : s.getNestedPlans()) {
-                for (LogicalOperatorReference r : p.getRoots()) {
-                    getFreeVariablesInSelfOrDesc((AbstractLogicalOperator) r.getOperator(), freeVars);
+                for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                    getFreeVariablesInSelfOrDesc((AbstractLogicalOperator) r.getValue(), freeVars);
                 }
             }
             s.getUsedVariablesExceptNestedPlans(freeVars);
@@ -93,16 +94,16 @@
             s.getProducedVariablesExceptNestedPlans(produced2);
             freeVars.removeAll(produced);
         }
-        for (LogicalOperatorReference i : op.getInputs()) {
-            getFreeVariablesInSelfOrDesc((AbstractLogicalOperator) i.getOperator(), freeVars);
+        for (Mutable<ILogicalOperator> i : op.getInputs()) {
+            getFreeVariablesInSelfOrDesc((AbstractLogicalOperator) i.getValue(), freeVars);
         }
     }
 
     public static void getFreeVariablesInSubplans(AbstractOperatorWithNestedPlans op, Set<LogicalVariable> freeVars)
             throws AlgebricksException {
         for (ILogicalPlan p : op.getNestedPlans()) {
-            for (LogicalOperatorReference r : p.getRoots()) {
-                getFreeVariablesInSelfOrDesc((AbstractLogicalOperator) r.getOperator(), freeVars);
+            for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                getFreeVariablesInSelfOrDesc((AbstractLogicalOperator) r.getValue(), freeVars);
             }
         }
     }
@@ -122,14 +123,14 @@
     public static void computeSchemaAndPropertiesRecIfNull(AbstractLogicalOperator op, IOptimizationContext context)
             throws AlgebricksException {
         if (op.getSchema() == null) {
-            for (LogicalOperatorReference i : op.getInputs()) {
-                computeSchemaAndPropertiesRecIfNull((AbstractLogicalOperator) i.getOperator(), context);
+            for (Mutable<ILogicalOperator> i : op.getInputs()) {
+                computeSchemaAndPropertiesRecIfNull((AbstractLogicalOperator) i.getValue(), context);
             }
             if (op.hasNestedPlans()) {
                 AbstractOperatorWithNestedPlans a = (AbstractOperatorWithNestedPlans) op;
                 for (ILogicalPlan p : a.getNestedPlans()) {
-                    for (LogicalOperatorReference r : p.getRoots()) {
-                        computeSchemaAndPropertiesRecIfNull((AbstractLogicalOperator) r.getOperator(), context);
+                    for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                        computeSchemaAndPropertiesRecIfNull((AbstractLogicalOperator) r.getValue(), context);
                     }
                 }
             }
@@ -140,14 +141,14 @@
 
     public static void computeSchemaRecIfNull(AbstractLogicalOperator op) throws AlgebricksException {
         if (op.getSchema() == null) {
-            for (LogicalOperatorReference i : op.getInputs()) {
-                computeSchemaRecIfNull((AbstractLogicalOperator) i.getOperator());
+            for (Mutable<ILogicalOperator> i : op.getInputs()) {
+                computeSchemaRecIfNull((AbstractLogicalOperator) i.getValue());
             }
             if (op.hasNestedPlans()) {
                 AbstractOperatorWithNestedPlans a = (AbstractOperatorWithNestedPlans) op;
                 for (ILogicalPlan p : a.getNestedPlans()) {
-                    for (LogicalOperatorReference r : p.getRoots()) {
-                        computeSchemaRecIfNull((AbstractLogicalOperator) r.getOperator());
+                    for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                        computeSchemaRecIfNull((AbstractLogicalOperator) r.getValue());
                     }
                 }
             }
@@ -159,11 +160,11 @@
         if (op.getOperatorTag() != LogicalOperatorTag.SELECT) {
             return false;
         }
-        AbstractLogicalOperator doubleUnder = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator doubleUnder = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         if (doubleUnder.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) {
             return false;
         }
-        ILogicalExpression eu = ((SelectOperator) op).getCondition().getExpression();
+        ILogicalExpression eu = ((SelectOperator) op).getCondition().getValue();
         if (eu.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
             return false;
         }
@@ -171,7 +172,7 @@
         if (f1.getFunctionIdentifier() != AlgebricksBuiltinFunctions.NOT) {
             return false;
         }
-        ILogicalExpression a1 = f1.getArguments().get(0).getExpression();
+        ILogicalExpression a1 = f1.getArguments().get(0).getValue();
         if (a1.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
             return false;
         }
@@ -183,14 +184,14 @@
     }
 
     public static void typePlan(ILogicalPlan p, IOptimizationContext context) throws AlgebricksException {
-        for (LogicalOperatorReference r : p.getRoots()) {
+        for (Mutable<ILogicalOperator> r : p.getRoots()) {
             typeOpRec(r, context);
         }
     }
 
-    public static void typeOpRec(LogicalOperatorReference r, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) r.getOperator();
-        for (LogicalOperatorReference i : op.getInputs()) {
+    public static void typeOpRec(Mutable<ILogicalOperator> r, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) r.getValue();
+        for (Mutable<ILogicalOperator> i : op.getInputs()) {
             typeOpRec(i, context);
         }
         if (op.hasNestedPlans()) {
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/visitors/ILogicalExpressionReferenceTransform.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/visitors/ILogicalExpressionReferenceTransform.java
index e8f2d06..2ad942a 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/visitors/ILogicalExpressionReferenceTransform.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/algebra/visitors/ILogicalExpressionReferenceTransform.java
@@ -14,10 +14,12 @@
  */
 package edu.uci.ics.hyracks.algebricks.core.algebra.visitors;
 
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 
 public interface ILogicalExpressionReferenceTransform {
     // returns true if any change is made to the expression
-    public boolean transform(LogicalExpressionReference expression) throws AlgebricksException;
+    public boolean transform(Mutable<ILogicalExpression> expression) throws AlgebricksException;
 }
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/AbstractRuleController.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/AbstractRuleController.java
index 25441a9..1293d5b 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/AbstractRuleController.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/AbstractRuleController.java
@@ -16,9 +16,11 @@
 
 import java.util.Collection;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
 import edu.uci.ics.hyracks.algebricks.core.algebra.prettyprint.LogicalOperatorPrettyPrintVisitor;
@@ -45,7 +47,7 @@
      * @param ruleClasses
      * @return true iff one of the rules in the collection fired
      */
-    public abstract boolean rewriteWithRuleCollection(LogicalOperatorReference root,
+    public abstract boolean rewriteWithRuleCollection(Mutable<ILogicalOperator> root,
             Collection<IAlgebraicRewriteRule> rules) throws AlgebricksException;
 
     /**
@@ -54,20 +56,20 @@
      * @return true if any rewrite was fired, either on opRef or any operator
      *         under it.
      */
-    protected boolean rewriteOperatorRef(LogicalOperatorReference opRef, IAlgebraicRewriteRule rule)
+    protected boolean rewriteOperatorRef(Mutable<ILogicalOperator> opRef, IAlgebraicRewriteRule rule)
             throws AlgebricksException {
         return rewriteOperatorRef(opRef, rule, true, false);
     }
 
-    private void printRuleApplication(IAlgebraicRewriteRule rule, LogicalOperatorReference opRef)
+    private void printRuleApplication(IAlgebraicRewriteRule rule, Mutable<ILogicalOperator> opRef)
             throws AlgebricksException {
         AlgebricksConfig.ALGEBRICKS_LOGGER.fine(">>>> Rule " + rule.getClass() + " fired.\n");
         StringBuilder sb = new StringBuilder();
-        PlanPrettyPrinter.printOperator((AbstractLogicalOperator) opRef.getOperator(), sb, pvisitor, 0);
+        PlanPrettyPrinter.printOperator((AbstractLogicalOperator) opRef.getValue(), sb, pvisitor, 0);
         AlgebricksConfig.ALGEBRICKS_LOGGER.fine(sb.toString());
     }
 
-    protected boolean rewriteOperatorRef(LogicalOperatorReference opRef, IAlgebraicRewriteRule rule,
+    protected boolean rewriteOperatorRef(Mutable<ILogicalOperator> opRef, IAlgebraicRewriteRule rule,
             boolean enterNestedPlans, boolean fullDFS) throws AlgebricksException {
 
         if (rule.rewritePre(opRef, context)) {
@@ -75,9 +77,9 @@
             return true;
         }
         boolean rewritten = false;
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
 
-        for (LogicalOperatorReference inp : op.getInputs()) {
+        for (Mutable<ILogicalOperator> inp : op.getInputs()) {
             if (rewriteOperatorRef(inp, rule, enterNestedPlans, fullDFS)) {
                 rewritten = true;
                 if (!fullDFS) {
@@ -89,7 +91,7 @@
         if (op.hasNestedPlans() && enterNestedPlans) {
             AbstractOperatorWithNestedPlans o2 = (AbstractOperatorWithNestedPlans) op;
             for (ILogicalPlan p : o2.getNestedPlans()) {
-                for (LogicalOperatorReference r : p.getRoots()) {
+                for (Mutable<ILogicalOperator> r : p.getRoots()) {
                     if (rewriteOperatorRef(r, rule, enterNestedPlans, fullDFS)) {
                         rewritten = true;
                         if (!fullDFS) {
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java
index b8b1066..381f70c 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java
@@ -2,9 +2,11 @@
 
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
@@ -72,7 +74,7 @@
     private void runOptimizationSets(ILogicalPlan plan,
             List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> optimSet) throws AlgebricksException {
         for (Pair<AbstractRuleController, List<IAlgebraicRewriteRule>> ruleList : optimSet) {
-            for (LogicalOperatorReference r : plan.getRoots()) {
+            for (Mutable<ILogicalOperator> r : plan.getRoots()) {
                 ruleList.first.setContext(context);
                 ruleList.first.rewriteWithRuleCollection(r, ruleList.second);
             }
@@ -80,14 +82,14 @@
     }
 
     private static void computeSchemaBottomUpForPlan(ILogicalPlan p) throws AlgebricksException {
-        for (LogicalOperatorReference r : p.getRoots()) {
-            computeSchemaBottomUpForOp((AbstractLogicalOperator) r.getOperator());
+        for (Mutable<ILogicalOperator> r : p.getRoots()) {
+            computeSchemaBottomUpForOp((AbstractLogicalOperator) r.getValue());
         }
     }
 
     private static void computeSchemaBottomUpForOp(AbstractLogicalOperator op) throws AlgebricksException {
-        for (LogicalOperatorReference i : op.getInputs()) {
-            computeSchemaBottomUpForOp((AbstractLogicalOperator) i.getOperator());
+        for (Mutable<ILogicalOperator> i : op.getInputs()) {
+            computeSchemaBottomUpForOp((AbstractLogicalOperator) i.getValue());
         }
         if (op.hasNestedPlans()) {
             AbstractOperatorWithNestedPlans a = (AbstractOperatorWithNestedPlans) op;
diff --git a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/IAlgebraicRewriteRule.java b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/IAlgebraicRewriteRule.java
index c9aeaaa..bfbd636 100644
--- a/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/IAlgebraicRewriteRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-core/src/main/java/edu/uci/ics/hyracks/algebricks/core/rewriter/base/IAlgebraicRewriteRule.java
@@ -14,12 +14,15 @@
  */
 package edu.uci.ics.hyracks.algebricks.core.rewriter.base;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 
 public interface IAlgebraicRewriteRule {
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException;
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException;
 
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException;
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException;
 }
diff --git a/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/PigletCompiler.java b/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/PigletCompiler.java
index cc5f27b..07f6f5d 100644
--- a/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/PigletCompiler.java
+++ b/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/compiler/PigletCompiler.java
@@ -9,6 +9,9 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.compiler.api.HeuristicCompilerFactoryBuilder;
 import edu.uci.ics.hyracks.algebricks.compiler.api.ICompiler;
 import edu.uci.ics.hyracks.algebricks.compiler.api.ICompilerFactory;
@@ -17,8 +20,6 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.data.ISerializerDeserializerProvider;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
@@ -158,21 +159,21 @@
 
     private ILogicalPlan translate(List<ASTNode> ast) throws PigletException {
         Map<String, Relation> symMap = new HashMap<String, Relation>();
-        List<LogicalOperatorReference> roots = new ArrayList<LogicalOperatorReference>();
+        List<Mutable<ILogicalOperator>> roots = new ArrayList<Mutable<ILogicalOperator>>();
         previousOp = null;
         for (ASTNode an : ast) {
             switch (an.getTag()) {
                 case DUMP: {
                     DumpNode dn = (DumpNode) an;
                     Relation input = symMap.get(dn.getAlias());
-                    List<LogicalExpressionReference> expressions = new ArrayList<LogicalExpressionReference>();
+                    List<Mutable<ILogicalExpression>> expressions = new ArrayList<Mutable<ILogicalExpression>>();
                     for (LogicalVariable v : input.schema.values()) {
-                        expressions.add(new LogicalExpressionReference(new VariableReferenceExpression(v)));
+                        expressions.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(v)));
                     }
                     PigletFileDataSink dataSink = new PigletFileDataSink(dn.getFile());
                     ILogicalOperator op = new WriteOperator(expressions, dataSink);
-                    op.getInputs().add(new LogicalOperatorReference(input.op));
-                    roots.add(new LogicalOperatorReference(op));
+                    op.getInputs().add(new MutableObject<ILogicalOperator>(input.op));
+                    roots.add(new MutableObject<ILogicalOperator>(op));
                 }
                     break;
 
@@ -210,7 +211,8 @@
                 PigletFileDataSource ds = new PigletFileDataSource(file, types.toArray());
                 rel.op = new DataSourceScanOperator(variables, ds);
                 rel.op.getInputs().add(
-                        new LogicalOperatorReference(previousOp == null ? new EmptyTupleSourceOperator() : previousOp));
+                        new MutableObject<ILogicalOperator>(previousOp == null ? new EmptyTupleSourceOperator()
+                                : previousOp));
                 return rel;
             }
 
@@ -221,9 +223,9 @@
                 Relation inputRel = findInputRelation(alias, symMap);
                 Pair<Relation, LogicalVariable> tempInput = translateScalarExpression(inputRel, conditionNode);
                 Relation rel = new Relation();
-                rel.op = new SelectOperator(new LogicalExpressionReference(new VariableReferenceExpression(
+                rel.op = new SelectOperator(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(
                         tempInput.second)));
-                rel.op.getInputs().add(new LogicalOperatorReference(tempInput.first.op));
+                rel.op.getInputs().add(new MutableObject<ILogicalOperator>(tempInput.first.op));
                 rel.schema.putAll(tempInput.first.schema);
                 return rel;
             }
@@ -251,11 +253,11 @@
                 List<LogicalVariable> vars = new ArrayList<LogicalVariable>();
                 vars.add(var);
 
-                List<LogicalExpressionReference> exprs = new ArrayList<LogicalExpressionReference>();
-                exprs.add(new LogicalExpressionReference(ce));
+                List<Mutable<ILogicalExpression>> exprs = new ArrayList<Mutable<ILogicalExpression>>();
+                exprs.add(new MutableObject<ILogicalExpression>(ce));
 
                 rel.op = new AssignOperator(vars, exprs);
-                rel.op.getInputs().add(new LogicalOperatorReference(inputRel.op));
+                rel.op.getInputs().add(new MutableObject<ILogicalOperator>(inputRel.op));
                 rel.schema.putAll(inputRel.schema);
 
                 return new Pair<Relation, LogicalVariable>(rel, var);
@@ -263,13 +265,13 @@
 
             case SCALAR_FUNCTION: {
                 ScalarFunctionExpressionNode sfen = (ScalarFunctionExpressionNode) expressionNode;
-                List<LogicalExpressionReference> argExprs = new ArrayList<LogicalExpressionReference>();
+                List<Mutable<ILogicalExpression>> argExprs = new ArrayList<Mutable<ILogicalExpression>>();
                 List<ASTNode> arguments = sfen.getArguments();
                 Relation rel = inputRel;
                 for (ASTNode a : arguments) {
                     Pair<Relation, LogicalVariable> argPair = translateScalarExpression(rel, (ExpressionNode) a);
                     rel = argPair.first;
-                    argExprs.add(new LogicalExpressionReference(new VariableReferenceExpression(argPair.second)));
+                    argExprs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(argPair.second)));
                 }
                 Relation outRel = new Relation();
                 outRel.schema.putAll(rel.schema);
@@ -279,10 +281,10 @@
 
                 IFunctionInfo fInfo = lookupFunction(sfen.getFunctionTag(), sfen.getFunctionName());
 
-                List<LogicalExpressionReference> exprs = new ArrayList<LogicalExpressionReference>();
-                exprs.add(new LogicalExpressionReference(new ScalarFunctionCallExpression(fInfo, argExprs)));
+                List<Mutable<ILogicalExpression>> exprs = new ArrayList<Mutable<ILogicalExpression>>();
+                exprs.add(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(fInfo, argExprs)));
                 outRel.op = new AssignOperator(vars, exprs);
-                outRel.op.getInputs().add(new LogicalOperatorReference(rel.op));
+                outRel.op.getInputs().add(new MutableObject<ILogicalOperator>(rel.op));
                 return new Pair<Relation, LogicalVariable>(outRel, var);
             }
         }
diff --git a/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/PigletExpressionJobGen.java b/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/PigletExpressionJobGen.java
index d06d9a8..63e6f53 100644
--- a/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/PigletExpressionJobGen.java
+++ b/hyracks-algebricks/hyracks-algebricks-examples/piglet-example/src/main/java/edu/uci/ics/hyracks/algebricks/examples/piglet/runtime/PigletExpressionJobGen.java
@@ -4,8 +4,9 @@
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
@@ -70,16 +71,16 @@
             case FUNCTION_CALL: {
                 ScalarFunctionCallExpression sfce = (ScalarFunctionCallExpression) expr;
 
-                List<LogicalExpressionReference> argExprs = sfce.getArguments();
+                List<Mutable<ILogicalExpression>> argExprs = sfce.getArguments();
                 IEvaluatorFactory argEvalFactories[] = new IEvaluatorFactory[argExprs.size()];
                 for (int i = 0; i < argEvalFactories.length; ++i) {
-                    LogicalExpressionReference er = argExprs.get(i);
-                    argEvalFactories[i] = createEvaluatorFactory(er.getExpression(), env, inputSchemas, context);
+                    Mutable<ILogicalExpression> er = argExprs.get(i);
+                    argEvalFactories[i] = createEvaluatorFactory(er.getValue(), env, inputSchemas, context);
                 }
                 IEvaluatorFactory funcEvalFactory;
                 try {
-                    funcEvalFactory = PigletFunctionRegistry.createFunctionEvaluatorFactory(sfce
-                            .getFunctionIdentifier(), argEvalFactories);
+                    funcEvalFactory = PigletFunctionRegistry.createFunctionEvaluatorFactory(
+                            sfce.getFunctionIdentifier(), argEvalFactories);
                 } catch (PigletException e) {
                     throw new AlgebricksException(e);
                 }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/AbstractDecorrelationRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/AbstractDecorrelationRule.java
index 62c4559..fe33d09 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/AbstractDecorrelationRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/AbstractDecorrelationRule.java
@@ -19,11 +19,13 @@
 import java.util.List;
 import java.util.Set;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
@@ -39,7 +41,7 @@
 public abstract class AbstractDecorrelationRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
@@ -52,7 +54,7 @@
         if (op2.getInputs().size() != 1) {
             return false;
         }
-        AbstractLogicalOperator alo = (AbstractLogicalOperator) op2.getInputs().get(0).getOperator();
+        AbstractLogicalOperator alo = (AbstractLogicalOperator) op2.getInputs().get(0).getValue();
         if (descOrSelfIsScanOrJoin(alo)) {
             return true;
         }
@@ -76,16 +78,16 @@
     }
 
     protected void buildVarExprList(Collection<LogicalVariable> vars, IOptimizationContext context, GroupByOperator g,
-            List<Pair<LogicalVariable, LogicalExpressionReference>> outVeList) throws AlgebricksException {
+            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> outVeList) throws AlgebricksException {
         for (LogicalVariable ov : vars) {
             LogicalVariable newVar = context.newVar();
             ILogicalExpression varExpr = new VariableReferenceExpression(newVar);
-            outVeList.add(new Pair<LogicalVariable, LogicalExpressionReference>(ov, new LogicalExpressionReference(
-                    varExpr)));
+            outVeList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(ov,
+                    new MutableObject<ILogicalExpression>(varExpr)));
             for (ILogicalPlan p : g.getNestedPlans()) {
-                for (LogicalOperatorReference r : p.getRoots()) {
-                    OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getOperator(), ov, newVar,
-                            true, context);
+                for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                    OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getValue(), ov, newVar, true,
+                            context);
                 }
             }
             // g.substituteVarInNestedPlans(ov, newVar);
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/AbstractExtractExprRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/AbstractExtractExprRule.java
index f247492..fbacede 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/AbstractExtractExprRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/AbstractExtractExprRule.java
@@ -14,11 +14,13 @@
  */
 package edu.uci.ics.hyracks.algebricks.rewriter.rules;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -26,12 +28,12 @@
 
 public abstract class AbstractExtractExprRule implements IAlgebraicRewriteRule {
 
-    protected LogicalVariable extractExprIntoAssignOpRef(ILogicalExpression gExpr, LogicalOperatorReference opRef2,
+    protected LogicalVariable extractExprIntoAssignOpRef(ILogicalExpression gExpr, Mutable<ILogicalOperator> opRef2,
             IOptimizationContext context) throws AlgebricksException {
         LogicalVariable v = context.newVar();
-        AssignOperator a = new AssignOperator(v, new LogicalExpressionReference(gExpr));
-        a.getInputs().add(new LogicalOperatorReference(opRef2.getOperator()));
-        opRef2.setOperator(a);
+        AssignOperator a = new AssignOperator(v, new MutableObject<ILogicalExpression>(gExpr));
+        a.getInputs().add(new MutableObject<ILogicalOperator>(opRef2.getValue()));
+        opRef2.setValue(a);
         if (gExpr.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
             context.addNotToBeInlinedVar(v);
         }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/BreakSelectIntoConjunctsRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/BreakSelectIntoConjunctsRule.java
index 7902e2c..55eef21 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/BreakSelectIntoConjunctsRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/BreakSelectIntoConjunctsRule.java
@@ -17,11 +17,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
@@ -30,48 +31,48 @@
 
 public class BreakSelectIntoConjunctsRule implements IAlgebraicRewriteRule {
 
-    private List<LogicalExpressionReference> conjs = new ArrayList<LogicalExpressionReference>();
+    private List<Mutable<ILogicalExpression>> conjs = new ArrayList<Mutable<ILogicalExpression>>();
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.SELECT) {
             return false;
         }
         SelectOperator select = (SelectOperator) op;
 
-        ILogicalExpression cond = select.getCondition().getExpression();
+        ILogicalExpression cond = select.getCondition().getValue();
 
         conjs.clear();
         if (!cond.splitIntoConjuncts(conjs)) {
             return false;
         }
 
-        LogicalOperatorReference childOfSelect = select.getInputs().get(0);
+        Mutable<ILogicalOperator> childOfSelect = select.getInputs().get(0);
         boolean fst = true;
         ILogicalOperator botOp = select;
         ILogicalExpression firstExpr = null;
-        for (LogicalExpressionReference eRef : conjs) {
-            ILogicalExpression e = eRef.getExpression();
+        for (Mutable<ILogicalExpression> eRef : conjs) {
+            ILogicalExpression e = eRef.getValue();
             if (fst) {
                 fst = false;
                 firstExpr = e;
             } else {
-                SelectOperator newSelect = new SelectOperator(new LogicalExpressionReference(e));
-                List<LogicalOperatorReference> botInpList = botOp.getInputs();
+                SelectOperator newSelect = new SelectOperator(new MutableObject<ILogicalExpression>(e));
+                List<Mutable<ILogicalOperator>> botInpList = botOp.getInputs();
                 botInpList.clear();
-                botInpList.add(new LogicalOperatorReference(newSelect));
+                botInpList.add(new MutableObject<ILogicalOperator>(newSelect));
                 context.computeAndSetTypeEnvironmentForOperator(botOp);
                 botOp = newSelect;
             }
         }
         botOp.getInputs().add(childOfSelect);
-        select.getCondition().setExpression(firstExpr);
+        select.getCondition().setValue(firstExpr);
         context.computeAndSetTypeEnvironmentForOperator(botOp);
         context.computeAndSetTypeEnvironmentForOperator(select);
 
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ComplexJoinInferenceRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ComplexJoinInferenceRule.java
index 5e02124..2ac387d 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ComplexJoinInferenceRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ComplexJoinInferenceRule.java
@@ -16,11 +16,13 @@
 
 import java.util.HashSet;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
@@ -37,21 +39,22 @@
 public class ComplexJoinInferenceRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        ILogicalOperator op = opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        ILogicalOperator op = opRef.getValue();
         if (!(op instanceof AbstractScanOperator)) {
             return false;
         }
 
-        LogicalOperatorReference opRef2 = op.getInputs().get(0);
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getOperator();
+        Mutable<ILogicalOperator> opRef2 = op.getInputs().get(0);
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
         if (op2.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
             return false;
         }
         SubplanOperator subplan = (SubplanOperator) op2;
 
-        LogicalOperatorReference opRef3 = subplan.getInputs().get(0);
-        AbstractLogicalOperator op3 = (AbstractLogicalOperator) opRef3.getOperator();
+        Mutable<ILogicalOperator> opRef3 = subplan.getInputs().get(0);
+        AbstractLogicalOperator op3 = (AbstractLogicalOperator) opRef3.getValue();
 
         if (op3.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE
                 || op3.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
@@ -73,23 +76,23 @@
         }
 
         ntsToEtsInSubplan(subplan, context);
-        InnerJoinOperator join = new InnerJoinOperator(new LogicalExpressionReference(ConstantExpression.TRUE));
+        InnerJoinOperator join = new InnerJoinOperator(new MutableObject<ILogicalExpression>(ConstantExpression.TRUE));
         join.getInputs().add(opRef3);
-        opRef2.setOperator(OperatorManipulationUtil.eliminateSingleSubplanOverEts(subplan));
-        join.getInputs().add(new LogicalOperatorReference(op));
-        opRef.setOperator(join);
+        opRef2.setValue(OperatorManipulationUtil.eliminateSingleSubplanOverEts(subplan));
+        join.getInputs().add(new MutableObject<ILogicalOperator>(op));
+        opRef.setValue(join);
         context.computeAndSetTypeEnvironmentForOperator(join);
         return true;
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     private static void ntsToEtsInSubplan(SubplanOperator s, IOptimizationContext context) throws AlgebricksException {
         for (ILogicalPlan p : s.getNestedPlans()) {
-            for (LogicalOperatorReference r : p.getRoots()) {
+            for (Mutable<ILogicalOperator> r : p.getRoots()) {
                 OperatorManipulationUtil.ntsToEts(r, context);
             }
         }
@@ -97,8 +100,8 @@
 
     private static boolean subplanHasFreeVariables(SubplanOperator s) throws AlgebricksException {
         for (ILogicalPlan p : s.getNestedPlans()) {
-            for (LogicalOperatorReference r : p.getRoots()) {
-                if (OperatorPropertiesUtil.hasFreeVariablesInSelfOrDesc((AbstractLogicalOperator) r.getOperator())) {
+            for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                if (OperatorPropertiesUtil.hasFreeVariablesInSelfOrDesc((AbstractLogicalOperator) r.getValue())) {
                     return true;
                 }
             }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ConsolidateAssignsRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ConsolidateAssignsRule.java
index 0812576..67e7cf0 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ConsolidateAssignsRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ConsolidateAssignsRule.java
@@ -17,8 +17,10 @@
 import java.util.HashSet;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
@@ -30,19 +32,19 @@
 public class ConsolidateAssignsRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
             return false;
         }
         AssignOperator assign1 = (AssignOperator) op;
 
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) assign1.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) assign1.getInputs().get(0).getValue();
         if (op2.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
             return false;
         }
@@ -60,8 +62,8 @@
         assign1.getVariables().addAll(assign2.getVariables());
         assign1.getExpressions().addAll(assign2.getExpressions());
 
-        LogicalOperatorReference botOpRef = assign2.getInputs().get(0);
-        List<LogicalOperatorReference> asgnInpList = assign1.getInputs();
+        Mutable<ILogicalOperator> botOpRef = assign2.getInputs().get(0);
+        List<Mutable<ILogicalOperator>> asgnInpList = assign1.getInputs();
         asgnInpList.clear();
         asgnInpList.add(botOpRef);
         context.computeAndSetTypeEnvironmentForOperator(assign1);
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ConsolidateSelectsRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ConsolidateSelectsRule.java
index 6484cff..c2bb13d 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ConsolidateSelectsRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ConsolidateSelectsRule.java
@@ -16,9 +16,12 @@
 
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
@@ -31,41 +34,41 @@
 public class ConsolidateSelectsRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.SELECT) {
             return false;
         }
         SelectOperator select = (SelectOperator) op;
 
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) select.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) select.getInputs().get(0).getValue();
         if (op2.getOperatorTag() != LogicalOperatorTag.SELECT) {
             return false;
         }
 
-        AbstractFunctionCallExpression conj = new ScalarFunctionCallExpression(AlgebricksBuiltinFunctions
-                .getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.AND));
-        conj.getArguments().add(new LogicalExpressionReference(select.getCondition().getExpression()));
+        AbstractFunctionCallExpression conj = new ScalarFunctionCallExpression(
+                AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.AND));
+        conj.getArguments().add(new MutableObject<ILogicalExpression>(select.getCondition().getValue()));
         conj.getArguments().add(((SelectOperator) op2).getCondition());
 
-        LogicalOperatorReference botOpRef = select.getInputs().get(0);
+        Mutable<ILogicalOperator> botOpRef = select.getInputs().get(0);
         boolean more = true;
         while (more) {
-            botOpRef = botOpRef.getOperator().getInputs().get(0);
-            AbstractLogicalOperator botOp = (AbstractLogicalOperator) botOpRef.getOperator();
+            botOpRef = botOpRef.getValue().getInputs().get(0);
+            AbstractLogicalOperator botOp = (AbstractLogicalOperator) botOpRef.getValue();
             if (botOp.getOperatorTag() == LogicalOperatorTag.SELECT) {
                 conj.getArguments().add(((SelectOperator) botOp).getCondition());
             } else {
                 more = false;
             }
         }
-        select.getCondition().setExpression(conj);
-        List<LogicalOperatorReference> selInptList = select.getInputs();
+        select.getCondition().setValue(conj);
+        List<Mutable<ILogicalOperator>> selInptList = select.getInputs();
         selInptList.clear();
         selInptList.add(botOpRef);
         context.computeAndSetTypeEnvironmentForOperator(select);
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/EliminateSubplanRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/EliminateSubplanRule.java
index 6a866ae..5c5356c 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/EliminateSubplanRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/EliminateSubplanRule.java
@@ -16,11 +16,13 @@
 
 import java.util.LinkedList;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
@@ -34,7 +36,7 @@
 public class EliminateSubplanRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
@@ -46,15 +48,15 @@
      * there are no aggregates?)
      */
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
             return false;
         }
         SubplanOperator subplan = (SubplanOperator) op;
 
-        LogicalOperatorReference outerRef = subplan.getInputs().get(0);
-        AbstractLogicalOperator outerRefOp = (AbstractLogicalOperator) outerRef.getOperator();
+        Mutable<ILogicalOperator> outerRef = subplan.getInputs().get(0);
+        AbstractLogicalOperator outerRefOp = (AbstractLogicalOperator) outerRef.getValue();
         if (outerRefOp.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
             elimSubplanOverEts(opRef, context);
             return true;
@@ -69,12 +71,12 @@
         return false;
     }
 
-    private boolean elimOneSubplanWithNoFreeVars(LogicalOperatorReference opRef) {
-        SubplanOperator subplan = (SubplanOperator) opRef.getOperator();
+    private boolean elimOneSubplanWithNoFreeVars(Mutable<ILogicalOperator> opRef) {
+        SubplanOperator subplan = (SubplanOperator) opRef.getValue();
         AbstractLogicalOperator rootOp = (AbstractLogicalOperator) subplan.getNestedPlans().get(0).getRoots().get(0)
-                .getOperator();
+                .getValue();
         if (rootOp.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
-            opRef.setOperator(subplan.getInputs().get(0).getOperator());
+            opRef.setValue(subplan.getInputs().get(0).getValue());
             return true;
         } else {
             AbstractLogicalOperator botOp = rootOp;
@@ -82,11 +84,11 @@
                 return false;
             }
             do {
-                LogicalOperatorReference botRef = botOp.getInputs().get(0);
-                botOp = (AbstractLogicalOperator) botRef.getOperator();
+                Mutable<ILogicalOperator> botRef = botOp.getInputs().get(0);
+                botOp = (AbstractLogicalOperator) botRef.getValue();
                 if (botOp.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
-                    botRef.setOperator(subplan.getInputs().get(0).getOperator());
-                    opRef.setOperator(rootOp);
+                    botRef.setValue(subplan.getInputs().get(0).getValue());
+                    opRef.setValue(rootOp);
                     return true;
                 }
             } while (botOp.getInputs().size() == 1);
@@ -94,32 +96,32 @@
         }
     }
 
-    private void elimSubplanOverEts(LogicalOperatorReference opRef, IOptimizationContext ctx)
+    private void elimSubplanOverEts(Mutable<ILogicalOperator> opRef, IOptimizationContext ctx)
             throws AlgebricksException {
-        SubplanOperator subplan = (SubplanOperator) opRef.getOperator();
+        SubplanOperator subplan = (SubplanOperator) opRef.getValue();
         for (ILogicalPlan p : subplan.getNestedPlans()) {
-            for (LogicalOperatorReference r : p.getRoots()) {
+            for (Mutable<ILogicalOperator> r : p.getRoots()) {
                 OperatorManipulationUtil.ntsToEts(r, ctx);
             }
         }
-        LinkedList<LogicalOperatorReference> allRoots = subplan.allRootsInReverseOrder();
+        LinkedList<Mutable<ILogicalOperator>> allRoots = subplan.allRootsInReverseOrder();
         if (allRoots.size() == 1) {
-            opRef.setOperator(allRoots.get(0).getOperator());
+            opRef.setValue(allRoots.get(0).getValue());
         } else {
             ILogicalOperator topOp = null;
-            for (LogicalOperatorReference r : allRoots) {
+            for (Mutable<ILogicalOperator> r : allRoots) {
                 if (topOp == null) {
-                    topOp = r.getOperator();
+                    topOp = r.getValue();
                 } else {
-                    LeftOuterJoinOperator j = new LeftOuterJoinOperator(new LogicalExpressionReference(
+                    LeftOuterJoinOperator j = new LeftOuterJoinOperator(new MutableObject<ILogicalExpression>(
                             ConstantExpression.TRUE));
-                    j.getInputs().add(new LogicalOperatorReference(topOp));
+                    j.getInputs().add(new MutableObject<ILogicalOperator>(topOp));
                     j.getInputs().add(r);
                     ctx.setOutputTypeEnvironment(j, j.computeOutputTypeEnvironment(ctx));
                     topOp = j;
                 }
             }
-            opRef.setOperator(topOp);
+            opRef.setValue(topOp);
         }
     }
 }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java
index eaaf799..5ebaad7 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/EnforceStructuralPropertiesRule.java
@@ -6,13 +6,15 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.EquivalenceClass;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IPhysicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
@@ -43,8 +45,10 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.AsterixNodeGroupDomain;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.FunctionalDependency;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty.PropertyType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.INodeDomain;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty;
+import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty.PartitioningType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningRequirementsCoordinator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.LocalGroupingProperty;
@@ -56,8 +60,6 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.RandomPartitioningProperty;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.StructuralPropertiesVector;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.UnorderedPartitionedProperty;
-import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILocalStructuralProperty.PropertyType;
-import edu.uci.ics.hyracks.algebricks.core.algebra.properties.IPartitioningProperty.PartitioningType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
@@ -74,13 +76,14 @@
     private PhysicalOptimizationConfig physicalOptimizationConfig;
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         // wait for the physical operators to be set first
         if (op.getPhysicalOperator() == null) {
             return false;
@@ -108,7 +111,7 @@
         AlgebricksConfig.ALGEBRICKS_LOGGER.finest(">>>> Structural properties for " + op.getPhysicalOperator() + ": "
                 + op.getDeliveredPhysicalProperties() + "\n");
 
-        context.addToDontApplySet(this, opRef.getOperator());
+        context.addToDontApplySet(this, opRef.getValue());
 
         return changed;
     }
@@ -116,11 +119,11 @@
     private boolean physOptimizePlan(ILogicalPlan plan, IPhysicalPropertiesVector pvector, boolean nestedPlan,
             IOptimizationContext context) throws AlgebricksException {
         boolean changed = false;
-        for (LogicalOperatorReference root : plan.getRoots()) {
+        for (Mutable<ILogicalOperator> root : plan.getRoots()) {
             if (physOptimizeOp(root, pvector, nestedPlan, context)) {
                 changed = true;
             }
-            AbstractLogicalOperator op = (AbstractLogicalOperator) root.getOperator();
+            AbstractLogicalOperator op = (AbstractLogicalOperator) root.getValue();
             op.computeDeliveredPhysicalProperties(context);
             AlgebricksConfig.ALGEBRICKS_LOGGER.finest(">>>> Structural properties for " + op.getPhysicalOperator()
                     + ": " + op.getDeliveredPhysicalProperties() + "\n");
@@ -128,11 +131,11 @@
         return changed;
     }
 
-    private boolean physOptimizeOp(LogicalOperatorReference opRef, IPhysicalPropertiesVector required,
+    private boolean physOptimizeOp(Mutable<ILogicalOperator> opRef, IPhysicalPropertiesVector required,
             boolean nestedPlan, IOptimizationContext context) throws AlgebricksException {
 
         boolean changed = false;
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         optimizeUsingConstraintsAndEquivClasses(op);
         PhysicalRequirements pr = op.getRequiredPhysicalPropertiesForChildren(required);
         IPhysicalPropertiesVector[] reqdProperties = null;
@@ -145,8 +148,8 @@
         INodeDomain childrenDomain = null;
         {
             int j = 0;
-            for (LogicalOperatorReference childRef : op.getInputs()) {
-                AbstractLogicalOperator child = (AbstractLogicalOperator) childRef.getOperator();
+            for (Mutable<ILogicalOperator> childRef : op.getInputs()) {
+                AbstractLogicalOperator child = (AbstractLogicalOperator) childRef.getValue();
                 // recursive call
                 if (physOptimizeOp(childRef, reqdProperties[j], nestedPlan, context)) {
                     changed = true;
@@ -177,18 +180,18 @@
 
         IPartitioningProperty firstDeliveredPartitioning = null;
         int i = 0;
-        for (LogicalOperatorReference childRef : op.getInputs()) {
-            AbstractLogicalOperator child = (AbstractLogicalOperator) childRef.getOperator();
+        for (Mutable<ILogicalOperator> childRef : op.getInputs()) {
+            AbstractLogicalOperator child = (AbstractLogicalOperator) childRef.getValue();
             IPhysicalPropertiesVector delivered = child.getDeliveredPhysicalProperties();
 
             AlgebricksConfig.ALGEBRICKS_LOGGER.finest(">>>> Properties delivered by " + child.getPhysicalOperator()
                     + ": " + delivered + "\n");
             IPartitioningRequirementsCoordinator prc = pr.getPartitioningCoordinator();
-            Pair<Boolean, IPartitioningProperty> pbpp = prc.coordinateRequirements(reqdProperties[i]
-                    .getPartitioningProperty(), firstDeliveredPartitioning, op, context);
+            Pair<Boolean, IPartitioningProperty> pbpp = prc.coordinateRequirements(
+                    reqdProperties[i].getPartitioningProperty(), firstDeliveredPartitioning, op, context);
             boolean mayExpandPartitioningProperties = pbpp.first;
-            IPhysicalPropertiesVector rqd = new StructuralPropertiesVector(pbpp.second, reqdProperties[i]
-                    .getLocalProperties());
+            IPhysicalPropertiesVector rqd = new StructuralPropertiesVector(pbpp.second,
+                    reqdProperties[i].getLocalProperties());
 
             AlgebricksConfig.ALGEBRICKS_LOGGER.finest(">>>> Required properties for " + child.getPhysicalOperator()
                     + ": " + rqd + "\n");
@@ -203,7 +206,7 @@
                 changed = true;
                 addEnforcers(op, i, diff, rqd, delivered, childrenDomain, nestedPlan, context);
 
-                AbstractLogicalOperator newChild = ((AbstractLogicalOperator) op.getInputs().get(i).getOperator());
+                AbstractLogicalOperator newChild = ((AbstractLogicalOperator) op.getInputs().get(i).getValue());
 
                 if (newChild != child) {
                     delivered = newChild.getDeliveredPhysicalProperties();
@@ -245,15 +248,15 @@
                 printOp((AbstractLogicalOperator) op);
             }
             changed = true;
-            AbstractLogicalOperator nextOp = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+            AbstractLogicalOperator nextOp = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
             if (nextOp.getOperatorTag() == LogicalOperatorTag.PROJECT) {
-                nextOp = (AbstractLogicalOperator) nextOp.getInputs().get(0).getOperator();
+                nextOp = (AbstractLogicalOperator) nextOp.getInputs().get(0).getValue();
             }
-            opRef.setOperator(nextOp);
+            opRef.setValue(nextOp);
             // Now, transfer annotations from the original sort op. to this one.
             AbstractLogicalOperator transferTo = nextOp;
             if (transferTo.getOperatorTag() == LogicalOperatorTag.EXCHANGE) {
-                transferTo = (AbstractLogicalOperator) transferTo.getInputs().get(0).getOperator();
+                transferTo = (AbstractLogicalOperator) transferTo.getInputs().get(0).getValue();
             }
             transferTo.getAnnotations().putAll(op.getAnnotations());
             physOptimizeOp(opRef, required, nestedPlan, context);
@@ -334,9 +337,9 @@
     /*
      * We assume delivered to be already normalized.
      */
-    private boolean isRedundantSort(LogicalOperatorReference opRef, IPhysicalPropertiesVector delivered,
+    private boolean isRedundantSort(Mutable<ILogicalOperator> opRef, IPhysicalPropertiesVector delivered,
             IPhysicalPropertiesVector diffOfProperties, IOptimizationContext context) {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.ORDER
                 || (op.getPhysicalOperator().getOperatorTag() != PhysicalOperatorTag.STABLE_SORT && op
                         .getPhysicalOperator().getOperatorTag() != PhysicalOperatorTag.IN_MEMORY_STABLE_SORT)
@@ -346,8 +349,8 @@
         AbstractStableSortPOperator sortOp = (AbstractStableSortPOperator) op.getPhysicalOperator();
         sortOp.computeLocalProperties(op);
         List<ILocalStructuralProperty> orderProps = sortOp.getOrderProperties();
-        return PropertiesUtil.matchLocalProperties(orderProps, delivered.getLocalProperties(), context
-                .getEquivalenceClassMap(op), context.getFDList(op));
+        return PropertiesUtil.matchLocalProperties(orderProps, delivered.getLocalProperties(),
+                context.getEquivalenceClassMap(op), context.getFDList(op));
     }
 
     private void addEnforcers(AbstractLogicalOperator op, int childIndex,
@@ -358,12 +361,12 @@
         IPartitioningProperty pp = diffPropertiesVector.getPartitioningProperty();
         if (pp == null || pp.getPartitioningType() == PartitioningType.UNPARTITIONED) {
             addLocalEnforcers(op, childIndex, diffPropertiesVector.getLocalProperties(), nestedPlan, context);
-            IPhysicalPropertiesVector deliveredByNewChild = ((AbstractLogicalOperator) op.getInputs().get(0)
-                    .getOperator()).getDeliveredPhysicalProperties();
+            IPhysicalPropertiesVector deliveredByNewChild = ((AbstractLogicalOperator) op.getInputs().get(0).getValue())
+                    .getDeliveredPhysicalProperties();
             addPartitioningEnforcers(op, childIndex, pp, required, deliveredByNewChild, domain, context);
         } else {
             addPartitioningEnforcers(op, childIndex, pp, required, deliveredByChild, domain, context);
-            AbstractLogicalOperator newChild = (AbstractLogicalOperator) op.getInputs().get(childIndex).getOperator();
+            AbstractLogicalOperator newChild = (AbstractLogicalOperator) op.getInputs().get(childIndex).getValue();
             IPhysicalPropertiesVector newDiff = newPropertiesDiff(newChild, required, true, context);
             AlgebricksConfig.ALGEBRICKS_LOGGER.finest(">>>> New properties diff: " + newDiff + "\n");
             if (newDiff != null) {
@@ -383,8 +386,8 @@
             return;
         }
 
-        LogicalOperatorReference topOp = new LogicalOperatorReference();
-        topOp.setOperator(op.getInputs().get(i).getOperator());
+        Mutable<ILogicalOperator> topOp = new MutableObject<ILogicalOperator>();
+        topOp.setValue(op.getInputs().get(i).getValue());
         LinkedList<LocalOrderProperty> oList = new LinkedList<LocalOrderProperty>();
 
         for (ILocalStructuralProperty prop : localProperties) {
@@ -414,17 +417,18 @@
         }
 
         op.getInputs().set(i, topOp);
-        OperatorPropertiesUtil.computeSchemaAndPropertiesRecIfNull((AbstractLogicalOperator) topOp.getOperator(), context);
-        printOp((AbstractLogicalOperator) topOp.getOperator());
+        OperatorPropertiesUtil.computeSchemaAndPropertiesRecIfNull((AbstractLogicalOperator) topOp.getValue(), context);
+        printOp((AbstractLogicalOperator) topOp.getValue());
     }
 
-    private LogicalOperatorReference enforceOrderProperties(List<LocalOrderProperty> oList,
-            LogicalOperatorReference topOp, boolean isMicroOp, IOptimizationContext context) throws AlgebricksException {
-        List<Pair<IOrder, LogicalExpressionReference>> oe = new LinkedList<Pair<IOrder, LogicalExpressionReference>>();
+    private Mutable<ILogicalOperator> enforceOrderProperties(List<LocalOrderProperty> oList,
+            Mutable<ILogicalOperator> topOp, boolean isMicroOp, IOptimizationContext context)
+            throws AlgebricksException {
+        List<Pair<IOrder, Mutable<ILogicalExpression>>> oe = new LinkedList<Pair<IOrder, Mutable<ILogicalExpression>>>();
         for (LocalOrderProperty o : oList) {
             IOrder ordType = (o.getOrder() == OrderKind.ASC) ? OrderOperator.ASC_ORDER : OrderOperator.DESC_ORDER;
-            Pair<IOrder, LogicalExpressionReference> pair = new Pair<IOrder, LogicalExpressionReference>(ordType,
-                    new LogicalExpressionReference(new VariableReferenceExpression(o.getColumn())));
+            Pair<IOrder, Mutable<ILogicalExpression>> pair = new Pair<IOrder, Mutable<ILogicalExpression>>(ordType,
+                    new MutableObject<ILogicalExpression>(new VariableReferenceExpression(o.getColumn())));
             oe.add(pair);
         }
         OrderOperator oo = new OrderOperator(oe);
@@ -439,7 +443,7 @@
         if (AlgebricksConfig.DEBUG) {
             AlgebricksConfig.ALGEBRICKS_LOGGER.fine(">>>> Added sort enforcer " + oo.getPhysicalOperator() + ".\n");
         }
-        return new LogicalOperatorReference(oo);
+        return new MutableObject<ILogicalOperator>(oo);
     }
 
     private void addPartitioningEnforcers(ILogicalOperator op, int i, IPartitioningProperty pp,
@@ -460,14 +464,14 @@
                     break;
                 }
                 case UNORDERED_PARTITIONED: {
-                    List<LogicalVariable> varList = new ArrayList<LogicalVariable>(((UnorderedPartitionedProperty) pp)
-                            .getColumnSet());
+                    List<LogicalVariable> varList = new ArrayList<LogicalVariable>(
+                            ((UnorderedPartitionedProperty) pp).getColumnSet());
                     List<ILocalStructuralProperty> cldLocals = deliveredByChild.getLocalProperties();
                     List<ILocalStructuralProperty> reqdLocals = required.getLocalProperties();
                     boolean propWasSet = false;
                     pop = null;
                     if (reqdLocals != null && cldLocals != null && allAreOrderProps(cldLocals)) {
-                        AbstractLogicalOperator c = (AbstractLogicalOperator) op.getInputs().get(i).getOperator();
+                        AbstractLogicalOperator c = (AbstractLogicalOperator) op.getInputs().get(i).getValue();
                         Map<LogicalVariable, EquivalenceClass> ecs = context.getEquivalenceClassMap(c);
                         List<FunctionalDependency> fds = context.getFDList(c);
                         if (PropertiesUtil.matchLocalProperties(reqdLocals, cldLocals, ecs, fds)) {
@@ -512,7 +516,7 @@
                             + " partitioning type has not been implemented.");
                 }
             }
-            LogicalOperatorReference ci = op.getInputs().get(i);
+            Mutable<ILogicalOperator> ci = op.getInputs().get(i);
             ExchangeOperator exchg = new ExchangeOperator();
             exchg.setPhysicalOperator(pop);
             setNewOp(ci, exchg, context);
@@ -562,11 +566,11 @@
 
     }
 
-    private void setNewOp(LogicalOperatorReference opRef, AbstractLogicalOperator newOp, IOptimizationContext context)
+    private void setNewOp(Mutable<ILogicalOperator> opRef, AbstractLogicalOperator newOp, IOptimizationContext context)
             throws AlgebricksException {
-        ILogicalOperator oldOp = opRef.getOperator();
-        opRef.setOperator(newOp);
-        newOp.getInputs().add(new LogicalOperatorReference(oldOp));
+        ILogicalOperator oldOp = opRef.getValue();
+        opRef.setValue(newOp);
+        newOp.getInputs().add(new MutableObject<ILogicalOperator>(oldOp));
         newOp.recomputeSchema();
         newOp.computeDeliveredPhysicalProperties(context);
         context.computeAndSetTypeEnvironmentForOperator(newOp);
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ExtractCommonOperatorsRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ExtractCommonOperatorsRule.java
index 11f94fe..3501467 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ExtractCommonOperatorsRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ExtractCommonOperatorsRule.java
@@ -20,19 +20,21 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ExchangeOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.IsomorphismUtilities;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.AssignPOperator;
@@ -44,25 +46,26 @@
 
 public class ExtractCommonOperatorsRule implements IAlgebraicRewriteRule {
 
-    private HashMap<LogicalOperatorReference, List<LogicalOperatorReference>> childrenToParents = new HashMap<LogicalOperatorReference, List<LogicalOperatorReference>>();
-    private List<LogicalOperatorReference> roots = new ArrayList<LogicalOperatorReference>();
-    private List<LogicalOperatorReference> joins = new ArrayList<LogicalOperatorReference>();
-    private List<List<LogicalOperatorReference>> equivalenceClasses = new ArrayList<List<LogicalOperatorReference>>();
+    private HashMap<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>> childrenToParents = new HashMap<Mutable<ILogicalOperator>, List<Mutable<ILogicalOperator>>>();
+    private List<Mutable<ILogicalOperator>> roots = new ArrayList<Mutable<ILogicalOperator>>();
+    private List<Mutable<ILogicalOperator>> joins = new ArrayList<Mutable<ILogicalOperator>>();
+    private List<List<Mutable<ILogicalOperator>>> equivalenceClasses = new ArrayList<List<Mutable<ILogicalOperator>>>();
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.WRITE && op.getOperatorTag() != LogicalOperatorTag.WRITE_RESULT) {
             return false;
         }
         if (!roots.contains(op))
-            roots.add(new LogicalOperatorReference(op));
+            roots.add(new MutableObject<ILogicalOperator>(op));
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.WRITE && op.getOperatorTag() != LogicalOperatorTag.WRITE_RESULT) {
             return false;
         }
@@ -91,12 +94,12 @@
     }
 
     private void removeTrivialShare() {
-        for (List<LogicalOperatorReference> candidates : equivalenceClasses) {
+        for (List<Mutable<ILogicalOperator>> candidates : equivalenceClasses) {
             for (int i = candidates.size() - 1; i >= 0; i--) {
-                LogicalOperatorReference opRef = candidates.get(i);
-                AbstractLogicalOperator aop = (AbstractLogicalOperator) opRef.getOperator();
+                Mutable<ILogicalOperator> opRef = candidates.get(i);
+                AbstractLogicalOperator aop = (AbstractLogicalOperator) opRef.getValue();
                 if (aop.getOperatorTag() == LogicalOperatorTag.EXCHANGE)
-                    aop = (AbstractLogicalOperator) aop.getInputs().get(0).getOperator();
+                    aop = (AbstractLogicalOperator) aop.getInputs().get(0).getValue();
                 if (aop.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE)
                     candidates.remove(i);
             }
@@ -107,11 +110,11 @@
     }
 
     private void removeNonJoinBuildBranchCandidates() {
-        for (List<LogicalOperatorReference> candidates : equivalenceClasses) {
+        for (List<Mutable<ILogicalOperator>> candidates : equivalenceClasses) {
             for (int i = candidates.size() - 1; i >= 0; i--) {
-                LogicalOperatorReference opRef = candidates.get(i);
+                Mutable<ILogicalOperator> opRef = candidates.get(i);
                 boolean reserve = false;
-                for (LogicalOperatorReference join : joins)
+                for (Mutable<ILogicalOperator> join : joins)
                     if (isInJoinBuildBranch(join, opRef)) {
                         reserve = true;
                     }
@@ -124,43 +127,43 @@
                 equivalenceClasses.remove(i);
     }
 
-    private boolean isInJoinBuildBranch(LogicalOperatorReference joinRef, LogicalOperatorReference opRef) {
-        LogicalOperatorReference buildBranch = joinRef.getOperator().getInputs().get(1);
+    private boolean isInJoinBuildBranch(Mutable<ILogicalOperator> joinRef, Mutable<ILogicalOperator> opRef) {
+        Mutable<ILogicalOperator> buildBranch = joinRef.getValue().getInputs().get(1);
         do {
             if (buildBranch.equals(opRef)) {
                 return true;
             } else {
-                AbstractLogicalOperator aop = (AbstractLogicalOperator) buildBranch.getOperator();
+                AbstractLogicalOperator aop = (AbstractLogicalOperator) buildBranch.getValue();
                 if (aop.getOperatorTag() == LogicalOperatorTag.INNERJOIN
                         || aop.getOperatorTag() == LogicalOperatorTag.LEFTOUTERJOIN
-                        || buildBranch.getOperator().getInputs().size() == 0)
+                        || buildBranch.getValue().getInputs().size() == 0)
                     return false;
                 else
-                    buildBranch = buildBranch.getOperator().getInputs().get(0);
+                    buildBranch = buildBranch.getValue().getInputs().get(0);
             }
         } while (true);
     }
 
     private boolean rewrite(IOptimizationContext context) throws AlgebricksException {
         boolean changed = false;
-        for (List<LogicalOperatorReference> members : equivalenceClasses) {
+        for (List<Mutable<ILogicalOperator>> members : equivalenceClasses) {
             if (rewriteForOneEquivalentClass(members, context))
                 changed = true;
         }
         return changed;
     }
 
-    private boolean rewriteForOneEquivalentClass(List<LogicalOperatorReference> members, IOptimizationContext context)
+    private boolean rewriteForOneEquivalentClass(List<Mutable<ILogicalOperator>> members, IOptimizationContext context)
             throws AlgebricksException {
-        List<LogicalOperatorReference> group = new ArrayList<LogicalOperatorReference>();
+        List<Mutable<ILogicalOperator>> group = new ArrayList<Mutable<ILogicalOperator>>();
         boolean rewritten = false;
         while (members.size() > 0) {
             group.clear();
-            LogicalOperatorReference candidate = members.remove(members.size() - 1);
+            Mutable<ILogicalOperator> candidate = members.remove(members.size() - 1);
             group.add(candidate);
             for (int i = members.size() - 1; i >= 0; i--) {
-                LogicalOperatorReference peer = members.get(i);
-                if (IsomorphismUtilities.isOperatorIsomorphic(candidate.getOperator(), peer.getOperator())) {
+                Mutable<ILogicalOperator> peer = members.get(i);
+                if (IsomorphismUtilities.isOperatorIsomorphic(candidate.getValue(), peer.getValue())) {
                     group.add(peer);
                     members.remove(i);
                 }
@@ -168,8 +171,8 @@
             AbstractLogicalOperator rop = new ReplicateOperator(group.size());
             rop.setPhysicalOperator(new ReplicatePOperator());
             rop.setExecutionMode(ExecutionMode.PARTITIONED);
-            LogicalOperatorReference ropRef = new LogicalOperatorReference(rop);
-            AbstractLogicalOperator aopCandidate = (AbstractLogicalOperator) candidate.getOperator();
+            Mutable<ILogicalOperator> ropRef = new MutableObject<ILogicalOperator>(rop);
+            AbstractLogicalOperator aopCandidate = (AbstractLogicalOperator) candidate.getValue();
 
             if (aopCandidate.getOperatorTag() == LogicalOperatorTag.EXCHANGE) {
                 rop.getInputs().add(candidate);
@@ -178,13 +181,13 @@
                 beforeExchange.setPhysicalOperator(new OneToOneExchangePOperator());
                 beforeExchange.getInputs().add(candidate);
                 context.computeAndSetTypeEnvironmentForOperator(beforeExchange);
-                rop.getInputs().add(new LogicalOperatorReference(beforeExchange));
+                rop.getInputs().add(new MutableObject<ILogicalOperator>(beforeExchange));
             }
             context.computeAndSetTypeEnvironmentForOperator(rop);
 
-            List<LogicalOperatorReference> parents = childrenToParents.get(candidate);
-            for (LogicalOperatorReference parentRef : parents) {
-                AbstractLogicalOperator parent = (AbstractLogicalOperator) parentRef.getOperator();
+            List<Mutable<ILogicalOperator>> parents = childrenToParents.get(candidate);
+            for (Mutable<ILogicalOperator> parentRef : parents) {
+                AbstractLogicalOperator parent = (AbstractLogicalOperator) parentRef.getValue();
                 int index = parent.getInputs().indexOf(candidate);
                 if (parent.getOperatorTag() == LogicalOperatorTag.EXCHANGE) {
                     parent.getInputs().set(index, ropRef);
@@ -193,24 +196,23 @@
                     exchange.setPhysicalOperator(new OneToOneExchangePOperator());
                     exchange.getInputs().add(ropRef);
                     context.computeAndSetTypeEnvironmentForOperator(exchange);
-                    // parent.getInputs().get(index).setOperator(exchange);
-                    parent.getInputs().set(index, new LogicalOperatorReference(exchange));
+                    // parent.getInputs().get(index).setValue(exchange);
+                    parent.getInputs().set(index, new MutableObject<ILogicalOperator>(exchange));
                     context.computeAndSetTypeEnvironmentForOperator(parent);
                 }
             }
 
             List<LogicalVariable> liveVarsNew = new ArrayList<LogicalVariable>();
-            VariableUtilities.getLiveVariables(candidate.getOperator(), liveVarsNew);
-            ArrayList<LogicalExpressionReference> assignExprs = new ArrayList<LogicalExpressionReference>();
+            VariableUtilities.getLiveVariables(candidate.getValue(), liveVarsNew);
+            ArrayList<Mutable<ILogicalExpression>> assignExprs = new ArrayList<Mutable<ILogicalExpression>>();
             for (LogicalVariable liveVar : liveVarsNew)
-                assignExprs.add(new LogicalExpressionReference(new VariableReferenceExpression(liveVar)));
-            for (LogicalOperatorReference ref : group) {
+                assignExprs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(liveVar)));
+            for (Mutable<ILogicalOperator> ref : group) {
                 if (ref.equals(candidate))
                     continue;
                 ArrayList<LogicalVariable> liveVars = new ArrayList<LogicalVariable>();
                 Map<LogicalVariable, LogicalVariable> variableMappingBack = new HashMap<LogicalVariable, LogicalVariable>();
-                IsomorphismUtilities.mapVariablesTopDown(ref.getOperator(), candidate.getOperator(),
-                        variableMappingBack);
+                IsomorphismUtilities.mapVariablesTopDown(ref.getValue(), candidate.getValue(), variableMappingBack);
                 for (int i = 0; i < liveVarsNew.size(); i++) {
                     liveVars.add(variableMappingBack.get(liveVarsNew.get(i)));
                 }
@@ -223,20 +225,20 @@
                 exchOp.setPhysicalOperator(new OneToOneExchangePOperator());
                 exchOp.getInputs().add(ropRef);
 
-                assignOperator.getInputs().add(new LogicalOperatorReference(exchOp));
-                projectOperator.getInputs().add(new LogicalOperatorReference(assignOperator));
+                assignOperator.getInputs().add(new MutableObject<ILogicalOperator>(exchOp));
+                projectOperator.getInputs().add(new MutableObject<ILogicalOperator>(assignOperator));
                 // set the types
                 context.computeAndSetTypeEnvironmentForOperator(exchOp);
                 context.computeAndSetTypeEnvironmentForOperator(assignOperator);
                 context.computeAndSetTypeEnvironmentForOperator(projectOperator);
 
-                List<LogicalOperatorReference> parentOpList = childrenToParents.get(ref);
-                for (LogicalOperatorReference parentOpRef : parentOpList) {
-                    AbstractLogicalOperator parentOp = (AbstractLogicalOperator) parentOpRef.getOperator();
+                List<Mutable<ILogicalOperator>> parentOpList = childrenToParents.get(ref);
+                for (Mutable<ILogicalOperator> parentOpRef : parentOpList) {
+                    AbstractLogicalOperator parentOp = (AbstractLogicalOperator) parentOpRef.getValue();
                     int index = parentOp.getInputs().indexOf(ref);
                     if (parentOp.getOperatorTag() == LogicalOperatorTag.EXCHANGE) {
                         AbstractLogicalOperator parentOpNext = (AbstractLogicalOperator) childrenToParents
-                                .get(parentOpRef).get(0).getOperator();
+                                .get(parentOpRef).get(0).getValue();
                         if (parentOpNext.isMap()) {
                             index = parentOpNext.getInputs().indexOf(parentOpRef);
                             parentOp = parentOpNext;
@@ -249,10 +251,10 @@
                     ILogicalOperator childOp = parentOp.getOperatorTag() == LogicalOperatorTag.PROJECT ? assignOperator
                             : projectOperator;
                     if (parentOp.isMap()) {
-                        parentOp.getInputs().set(index, new LogicalOperatorReference(childOp));
+                        parentOp.getInputs().set(index, new MutableObject<ILogicalOperator>(childOp));
                     } else {
-                        exchg.getInputs().add(new LogicalOperatorReference(childOp));
-                        parentOp.getInputs().set(index, new LogicalOperatorReference(exchg));
+                        exchg.getInputs().add(new MutableObject<ILogicalOperator>(childOp));
+                        parentOp.getInputs().set(index, new MutableObject<ILogicalOperator>(exchg));
                     }
                     context.computeAndSetTypeEnvironmentForOperator(exchg);
                 }
@@ -263,19 +265,19 @@
     }
 
     private void genCandidates(IOptimizationContext context) throws AlgebricksException {
-        List<List<LogicalOperatorReference>> previousEquivalenceClasses = new ArrayList<List<LogicalOperatorReference>>();
+        List<List<Mutable<ILogicalOperator>>> previousEquivalenceClasses = new ArrayList<List<Mutable<ILogicalOperator>>>();
         while (equivalenceClasses.size() > 0) {
             previousEquivalenceClasses.clear();
-            for (List<LogicalOperatorReference> candidates : equivalenceClasses) {
-                List<LogicalOperatorReference> candidatesCopy = new ArrayList<LogicalOperatorReference>();
+            for (List<Mutable<ILogicalOperator>> candidates : equivalenceClasses) {
+                List<Mutable<ILogicalOperator>> candidatesCopy = new ArrayList<Mutable<ILogicalOperator>>();
                 candidatesCopy.addAll(candidates);
                 previousEquivalenceClasses.add(candidatesCopy);
             }
-            List<LogicalOperatorReference> currentLevelOpRefs = new ArrayList<LogicalOperatorReference>();
-            for (List<LogicalOperatorReference> candidates : equivalenceClasses) {
+            List<Mutable<ILogicalOperator>> currentLevelOpRefs = new ArrayList<Mutable<ILogicalOperator>>();
+            for (List<Mutable<ILogicalOperator>> candidates : equivalenceClasses) {
                 if (candidates.size() > 0) {
-                    for (LogicalOperatorReference opRef : candidates) {
-                        List<LogicalOperatorReference> refs = childrenToParents.get(opRef);
+                    for (Mutable<ILogicalOperator> opRef : candidates) {
+                        List<Mutable<ILogicalOperator>> refs = childrenToParents.get(opRef);
                         if (refs != null)
                             currentLevelOpRefs.addAll(refs);
                     }
@@ -294,25 +296,25 @@
         }
     }
 
-    private void topDownMaterialization(List<LogicalOperatorReference> tops) {
-        List<LogicalOperatorReference> candidates = new ArrayList<LogicalOperatorReference>();
-        List<LogicalOperatorReference> nextLevel = new ArrayList<LogicalOperatorReference>();
-        for (LogicalOperatorReference op : tops) {
-            AbstractLogicalOperator aop = (AbstractLogicalOperator) op.getOperator();
+    private void topDownMaterialization(List<Mutable<ILogicalOperator>> tops) {
+        List<Mutable<ILogicalOperator>> candidates = new ArrayList<Mutable<ILogicalOperator>>();
+        List<Mutable<ILogicalOperator>> nextLevel = new ArrayList<Mutable<ILogicalOperator>>();
+        for (Mutable<ILogicalOperator> op : tops) {
+            AbstractLogicalOperator aop = (AbstractLogicalOperator) op.getValue();
             if ((aop.getOperatorTag() == LogicalOperatorTag.INNERJOIN || aop.getOperatorTag() == LogicalOperatorTag.LEFTOUTERJOIN)
                     && !joins.contains(op)) {
                 joins.add(op);
             }
-            for (LogicalOperatorReference opRef : op.getOperator().getInputs()) {
-                List<LogicalOperatorReference> opRefList = childrenToParents.get(opRef);
+            for (Mutable<ILogicalOperator> opRef : op.getValue().getInputs()) {
+                List<Mutable<ILogicalOperator>> opRefList = childrenToParents.get(opRef);
                 if (opRefList == null) {
-                    opRefList = new ArrayList<LogicalOperatorReference>();
+                    opRefList = new ArrayList<Mutable<ILogicalOperator>>();
                     childrenToParents.put(opRef, opRefList);
                     nextLevel.add(opRef);
                 }
                 opRefList.add(op);
             }
-            if (op.getOperator().getInputs().size() == 0)
+            if (op.getValue().getInputs().size() == 0)
                 candidates.add(op);
         }
         if (equivalenceClasses.size() > 0) {
@@ -325,17 +327,17 @@
         }
     }
 
-    private void candidatesGrow(List<LogicalOperatorReference> opList, List<LogicalOperatorReference> candidates) {
-        List<LogicalOperatorReference> previousCandidates = new ArrayList<LogicalOperatorReference>();
+    private void candidatesGrow(List<Mutable<ILogicalOperator>> opList, List<Mutable<ILogicalOperator>> candidates) {
+        List<Mutable<ILogicalOperator>> previousCandidates = new ArrayList<Mutable<ILogicalOperator>>();
         previousCandidates.addAll(candidates);
         candidates.clear();
         boolean validCandidate = false;
-        for (LogicalOperatorReference op : opList) {
-            for (LogicalOperatorReference inputRef : op.getOperator().getInputs()) {
+        for (Mutable<ILogicalOperator> op : opList) {
+            for (Mutable<ILogicalOperator> inputRef : op.getValue().getInputs()) {
                 validCandidate = false;
                 // if current input is in candidates
-                for (LogicalOperatorReference candidate : previousCandidates)
-                    if (inputRef.getOperator().equals(candidate.getOperator()))
+                for (Mutable<ILogicalOperator> candidate : previousCandidates)
+                    if (inputRef.getValue().equals(candidate.getValue()))
                         validCandidate = true;
                 // if one input is not in candidates
                 if (!validCandidate)
@@ -348,24 +350,24 @@
     }
 
     private void prune(IOptimizationContext context) throws AlgebricksException {
-        List<List<LogicalOperatorReference>> previousEquivalenceClasses = new ArrayList<List<LogicalOperatorReference>>();
-        for (List<LogicalOperatorReference> candidates : equivalenceClasses) {
-            List<LogicalOperatorReference> candidatesCopy = new ArrayList<LogicalOperatorReference>();
+        List<List<Mutable<ILogicalOperator>>> previousEquivalenceClasses = new ArrayList<List<Mutable<ILogicalOperator>>>();
+        for (List<Mutable<ILogicalOperator>> candidates : equivalenceClasses) {
+            List<Mutable<ILogicalOperator>> candidatesCopy = new ArrayList<Mutable<ILogicalOperator>>();
             candidatesCopy.addAll(candidates);
             previousEquivalenceClasses.add(candidatesCopy);
         }
         equivalenceClasses.clear();
-        for (List<LogicalOperatorReference> candidates : previousEquivalenceClasses) {
+        for (List<Mutable<ILogicalOperator>> candidates : previousEquivalenceClasses) {
             boolean[] reserved = new boolean[candidates.size()];
             for (int i = 0; i < reserved.length; i++)
                 reserved[i] = false;
             for (int i = candidates.size() - 1; i >= 0; i--) {
                 if (reserved[i] == false) {
-                    List<LogicalOperatorReference> equivalentClass = new ArrayList<LogicalOperatorReference>();
-                    ILogicalOperator candidate = candidates.get(i).getOperator();
+                    List<Mutable<ILogicalOperator>> equivalentClass = new ArrayList<Mutable<ILogicalOperator>>();
+                    ILogicalOperator candidate = candidates.get(i).getValue();
                     equivalentClass.add(candidates.get(i));
                     for (int j = i - 1; j >= 0; j--) {
-                        ILogicalOperator peer = candidates.get(j).getOperator();
+                        ILogicalOperator peer = candidates.get(j).getValue();
                         if (IsomorphismUtilities.isOperatorIsomorphic(candidate, peer)) {
                             reserved[i] = true;
                             reserved[j] = true;
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ExtractGbyExpressionsRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ExtractGbyExpressionsRule.java
index e9b895e..38032dd 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ExtractGbyExpressionsRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ExtractGbyExpressionsRule.java
@@ -14,11 +14,12 @@
  */
 package edu.uci.ics.hyracks.algebricks.rewriter.rules;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
@@ -34,13 +35,14 @@
 public class ExtractGbyExpressionsRule extends AbstractExtractExprRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
         if (op1.getOperatorTag() != LogicalOperatorTag.GROUP) {
             return false;
         }
@@ -63,12 +65,12 @@
         if (!gbyHasComplexExpr(g)) {
             return false;
         }
-        LogicalOperatorReference opRef2 = g.getInputs().get(0);
-        for (Pair<LogicalVariable, LogicalExpressionReference> gbyPair : g.getGroupByList()) {
-            ILogicalExpression expr = gbyPair.second.getExpression();
+        Mutable<ILogicalOperator> opRef2 = g.getInputs().get(0);
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> gbyPair : g.getGroupByList()) {
+            ILogicalExpression expr = gbyPair.second.getValue();
             if (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                 LogicalVariable v = extractExprIntoAssignOpRef(expr, opRef2, context);
-                gbyPair.second.setExpression(new VariableReferenceExpression(v));
+                gbyPair.second.setValue(new VariableReferenceExpression(v));
             }
         }
         return true;
@@ -78,20 +80,20 @@
         if (!decorHasComplexExpr(g)) {
             return false;
         }
-        LogicalOperatorReference opRef2 = g.getInputs().get(0);
-        for (Pair<LogicalVariable, LogicalExpressionReference> decorPair : g.getDecorList()) {
-            ILogicalExpression expr = decorPair.second.getExpression();
+        Mutable<ILogicalOperator> opRef2 = g.getInputs().get(0);
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> decorPair : g.getDecorList()) {
+            ILogicalExpression expr = decorPair.second.getValue();
             if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 LogicalVariable v = extractExprIntoAssignOpRef(expr, opRef2, context);
-                decorPair.second.setExpression(new VariableReferenceExpression(v));
+                decorPair.second.setValue(new VariableReferenceExpression(v));
             }
         }
         return true;
     }
 
     private boolean gbyHasComplexExpr(GroupByOperator g) {
-        for (Pair<LogicalVariable, LogicalExpressionReference> gbyPair : g.getGroupByList()) {
-            if (gbyPair.second.getExpression().getExpressionTag() != LogicalExpressionTag.VARIABLE) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> gbyPair : g.getGroupByList()) {
+            if (gbyPair.second.getValue().getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                 return true;
             }
         }
@@ -99,8 +101,8 @@
     }
 
     private boolean decorHasComplexExpr(GroupByOperator g) {
-        for (Pair<LogicalVariable, LogicalExpressionReference> gbyPair : g.getDecorList()) {
-            if (gbyPair.second.getExpression().getExpressionTag() != LogicalExpressionTag.VARIABLE) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> gbyPair : g.getDecorList()) {
+            if (gbyPair.second.getValue().getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                 return true;
             }
         }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/FactorRedundantGroupAndDecorVarsRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/FactorRedundantGroupAndDecorVarsRule.java
index 91ebde7..99ed003 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/FactorRedundantGroupAndDecorVarsRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/FactorRedundantGroupAndDecorVarsRule.java
@@ -19,11 +19,13 @@
 import java.util.ListIterator;
 import java.util.Map;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
@@ -37,13 +39,14 @@
 public class FactorRedundantGroupAndDecorVarsRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.GROUP) {
             return false;
         }
@@ -55,26 +58,26 @@
         return gvChanged || dvChanged;
     }
 
-    private boolean factorRedundantRhsVars(List<Pair<LogicalVariable, LogicalExpressionReference>> veList,
-            LogicalOperatorReference opRef, Map<LogicalVariable, LogicalVariable> varRhsToLhs,
+    private boolean factorRedundantRhsVars(List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> veList,
+            Mutable<ILogicalOperator> opRef, Map<LogicalVariable, LogicalVariable> varRhsToLhs,
             IOptimizationContext context) throws AlgebricksException {
         varRhsToLhs.clear();
-        ListIterator<Pair<LogicalVariable, LogicalExpressionReference>> iter = veList.listIterator();
+        ListIterator<Pair<LogicalVariable, Mutable<ILogicalExpression>>> iter = veList.listIterator();
         boolean changed = false;
         while (iter.hasNext()) {
-            Pair<LogicalVariable, LogicalExpressionReference> p = iter.next();
-            if (p.second.getExpression().getExpressionTag() != LogicalExpressionTag.VARIABLE) {
+            Pair<LogicalVariable, Mutable<ILogicalExpression>> p = iter.next();
+            if (p.second.getValue().getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                 continue;
             }
             LogicalVariable v = GroupByOperator.getDecorVariable(p);
             LogicalVariable lhs = varRhsToLhs.get(v);
             if (lhs != null) {
                 if (p.first != null) {
-                    AssignOperator assign = new AssignOperator(p.first, new LogicalExpressionReference(
+                    AssignOperator assign = new AssignOperator(p.first, new MutableObject<ILogicalExpression>(
                             new VariableReferenceExpression(lhs)));
-                    ILogicalOperator op = opRef.getOperator();
-                    assign.getInputs().add(new LogicalOperatorReference(op));
-                    opRef.setOperator(assign);
+                    ILogicalOperator op = opRef.getValue();
+                    assign.getInputs().add(new MutableObject<ILogicalOperator>(op));
+                    opRef.setValue(assign);
                     context.computeAndSetTypeEnvironmentForOperator(assign);
                 }
                 iter.remove();
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InferTypesRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InferTypesRule.java
index a69db2a..e1d5549 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InferTypesRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InferTypesRule.java
@@ -1,21 +1,23 @@
 package edu.uci.ics.hyracks.algebricks.rewriter.rules;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
 
 public class InferTypesRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        ILogicalOperator op = opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        ILogicalOperator op = opRef.getValue();
         if (context.getOutputTypeEnvironment(op) != null) {
             return false;
         }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java
index 3a093d7..0cc2b53 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java
@@ -19,13 +19,14 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.EquivalenceClass;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
@@ -46,7 +47,7 @@
 public class InlineVariablesRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
@@ -56,8 +57,8 @@
      * Does one big DFS sweep over the plan.
      * 
      */
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        if (context.checkIfInDontApplySet(this, opRef.getOperator())) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        if (context.checkIfInDontApplySet(this, opRef.getValue())) {
             return false;
         }
         VariableSubstitutionVisitor substVisitor = new VariableSubstitutionVisitor(false);
@@ -69,12 +70,12 @@
         return bb.first;
     }
 
-    private Pair<Boolean, Boolean> collectEqClassesAndRemoveRedundantOps(LogicalOperatorReference opRef,
+    private Pair<Boolean, Boolean> collectEqClassesAndRemoveRedundantOps(Mutable<ILogicalOperator> opRef,
             IOptimizationContext context, boolean first, List<EquivalenceClass> equivClasses,
             VariableSubstitutionVisitor substVisitor, VariableSubstitutionVisitor substVisitorForWrites)
             throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
-        // if (context.checkIfInDontApplySet(this, opRef.getOperator())) {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
+        // if (context.checkIfInDontApplySet(this, opRef.getValue())) {
         // return false;
         // }
         if (op.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
@@ -83,7 +84,7 @@
         boolean modified = false;
         boolean ecChange = false;
         int cnt = 0;
-        for (LogicalOperatorReference i : op.getInputs()) {
+        for (Mutable<ILogicalOperator> i : op.getInputs()) {
             boolean isOuterInputBranch = op.getOperatorTag() == LogicalOperatorTag.LEFTOUTERJOIN && cnt == 1;
             List<EquivalenceClass> eqc = isOuterInputBranch ? new LinkedList<EquivalenceClass>() : equivClasses;
 
@@ -120,7 +121,7 @@
                 eqc = equivClasses;
             }
             for (ILogicalPlan p : n.getNestedPlans()) {
-                for (LogicalOperatorReference r : p.getRoots()) {
+                for (Mutable<ILogicalOperator> r : p.getRoots()) {
                     Pair<Boolean, Boolean> bb = collectEqClassesAndRemoveRedundantOps(r, context, false, eqc,
                             substVisitor, substVisitorForWrites);
                     if (bb.first) {
@@ -135,7 +136,7 @@
         // we assume a variable is assigned a value only once
         if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
             AssignOperator a = (AssignOperator) op;
-            ILogicalExpression rhs = a.getExpressions().get(0).getExpression();
+            ILogicalExpression rhs = a.getExpressions().get(0).getValue();
             if (rhs.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 LogicalVariable varLeft = a.getVariables().get(0);
                 VariableReferenceExpression varRef = (VariableReferenceExpression) rhs;
@@ -185,18 +186,18 @@
                     modified = true;
                     if (op.getOperatorTag() == LogicalOperatorTag.GROUP) {
                         GroupByOperator group = (GroupByOperator) op;
-                        for (Pair<LogicalVariable, LogicalExpressionReference> gp : group.getGroupByList()) {
+                        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> gp : group.getGroupByList()) {
                             if (gp.first != null
-                                    && gp.second.getExpression().getExpressionTag() == LogicalExpressionTag.VARIABLE) {
-                                LogicalVariable gv = ((VariableReferenceExpression) gp.second.getExpression())
+                                    && gp.second.getValue().getExpressionTag() == LogicalExpressionTag.VARIABLE) {
+                                LogicalVariable gv = ((VariableReferenceExpression) gp.second.getValue())
                                         .getVariableReference();
-                                Iterator<Pair<LogicalVariable, LogicalExpressionReference>> iter = group.getDecorList()
-                                        .iterator();
+                                Iterator<Pair<LogicalVariable, Mutable<ILogicalExpression>>> iter = group
+                                        .getDecorList().iterator();
                                 while (iter.hasNext()) {
-                                    Pair<LogicalVariable, LogicalExpressionReference> dp = iter.next();
+                                    Pair<LogicalVariable, Mutable<ILogicalExpression>> dp = iter.next();
                                     if (dp.first == null
-                                            && dp.second.getExpression().getExpressionTag() == LogicalExpressionTag.VARIABLE) {
-                                        LogicalVariable dv = ((VariableReferenceExpression) dp.second.getExpression())
+                                            && dp.second.getValue().getExpressionTag() == LogicalExpressionTag.VARIABLE) {
+                                        LogicalVariable dv = ((VariableReferenceExpression) dp.second.getValue())
                                                 .getVariableReference();
                                         if (dv == gv) {
                                             // The decor variable is redundant,
@@ -227,12 +228,12 @@
         return new Pair<Boolean, Boolean>(modified, ecChange);
     }
 
-    private Pair<Boolean, Boolean> processVarExprPairs(List<Pair<LogicalVariable, LogicalExpressionReference>> vePairs,
-            List<EquivalenceClass> equivClasses) {
+    private Pair<Boolean, Boolean> processVarExprPairs(
+            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> vePairs, List<EquivalenceClass> equivClasses) {
         boolean ecFromGroup = false;
         boolean modified = false;
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : vePairs) {
-            ILogicalExpression expr = p.second.getExpression();
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : vePairs) {
+            ILogicalExpression expr = p.second.getValue();
             if (p.first != null && expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                 VariableReferenceExpression varRef = (VariableReferenceExpression) expr;
                 LogicalVariable rhsVar = varRef.getVariableReference();
@@ -294,8 +295,8 @@
         }
 
         @Override
-        public boolean transform(LogicalExpressionReference exprRef) {
-            ILogicalExpression e = exprRef.getExpression();
+        public boolean transform(Mutable<ILogicalExpression> exprRef) {
+            ILogicalExpression e = exprRef.getValue();
             switch (((AbstractLogicalExpression) e).getExpressionTag()) {
                 case VARIABLE: {
                     // look for a required substitution
@@ -311,12 +312,12 @@
                         if (doNotSubstWithConst) {
                             return false;
                         }
-                        exprRef.setExpression(ec.getConstRepresentative());
+                        exprRef.setValue(ec.getConstRepresentative());
                         return true;
                     } else {
                         LogicalVariable r = ec.getVariableRepresentative();
                         if (!r.equals(var)) {
-                            exprRef.setExpression(new VariableReferenceExpression(r));
+                            exprRef.setValue(new VariableReferenceExpression(r));
                             return true;
                         } else {
                             return false;
@@ -326,7 +327,7 @@
                 case FUNCTION_CALL: {
                     AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) e;
                     boolean m = false;
-                    for (LogicalExpressionReference arg : fce.getArguments()) {
+                    for (Mutable<ILogicalExpression> arg : fce.getArguments()) {
                         if (transform(arg)) {
                             m = true;
                         }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InsertOuterJoinRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InsertOuterJoinRule.java
index d15af57..25df119 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InsertOuterJoinRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InsertOuterJoinRule.java
@@ -16,9 +16,11 @@
 
 import java.util.Iterator;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
@@ -31,13 +33,13 @@
 public class InsertOuterJoinRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op0 = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op0 = (AbstractLogicalOperator) opRef.getValue();
         if (op0.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
             return false;
         }
@@ -54,47 +56,47 @@
         if (p.getRoots().size() != 1) {
             return false;
         }
-        LogicalOperatorReference subplanRoot = p.getRoots().get(0);
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) subplanRoot.getOperator();
-        LogicalOperatorReference opUnder = subplan.getInputs().get(0);
+        Mutable<ILogicalOperator> subplanRoot = p.getRoots().get(0);
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) subplanRoot.getValue();
+        Mutable<ILogicalOperator> opUnder = subplan.getInputs().get(0);
 
-        if (OperatorPropertiesUtil.isNullTest((AbstractLogicalOperator) opUnder.getOperator())) {
+        if (OperatorPropertiesUtil.isNullTest((AbstractLogicalOperator) opUnder.getValue())) {
             return false;
         }
 
         switch (op1.getOperatorTag()) {
             case INNERJOIN: {
                 InnerJoinOperator join = (InnerJoinOperator) op1;
-                LogicalOperatorReference leftRef = join.getInputs().get(0);
-                LogicalOperatorReference rightRef = join.getInputs().get(1);
-                LogicalOperatorReference ntsRef = getNtsAtEndOfPipeline(leftRef);
+                Mutable<ILogicalOperator> leftRef = join.getInputs().get(0);
+                Mutable<ILogicalOperator> rightRef = join.getInputs().get(1);
+                Mutable<ILogicalOperator> ntsRef = getNtsAtEndOfPipeline(leftRef);
                 if (ntsRef == null) {
                     ntsRef = getNtsAtEndOfPipeline(rightRef);
                     if (ntsRef == null) {
                         return false;
                     } else {
-                        LogicalOperatorReference t = leftRef;
+                        Mutable<ILogicalOperator> t = leftRef;
                         leftRef = rightRef;
                         rightRef = t;
                     }
                 }
-                ntsRef.setOperator(opUnder.getOperator());
+                ntsRef.setValue(opUnder.getValue());
                 LeftOuterJoinOperator loj = new LeftOuterJoinOperator(join.getCondition());
                 loj.getInputs().add(leftRef);
                 loj.getInputs().add(rightRef);
-                opRef.setOperator(loj);
+                opRef.setValue(loj);
                 context.computeAndSetTypeEnvironmentForOperator(loj);
                 return true;
             }
             case LEFTOUTERJOIN: {
                 LeftOuterJoinOperator join = (LeftOuterJoinOperator) op1;
-                LogicalOperatorReference leftRef = join.getInputs().get(0);
-                LogicalOperatorReference ntsRef = getNtsAtEndOfPipeline(leftRef);
+                Mutable<ILogicalOperator> leftRef = join.getInputs().get(0);
+                Mutable<ILogicalOperator> ntsRef = getNtsAtEndOfPipeline(leftRef);
                 if (ntsRef == null) {
                     return false;
                 }
-                ntsRef.setOperator(opUnder.getOperator());
-                opRef.setOperator(join);
+                ntsRef.setValue(opUnder.getValue());
+                opRef.setValue(join);
                 context.computeAndSetTypeEnvironmentForOperator(join);
                 return true;
             }
@@ -104,8 +106,8 @@
         }
     }
 
-    private LogicalOperatorReference getNtsAtEndOfPipeline(LogicalOperatorReference opRef) {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    private Mutable<ILogicalOperator> getNtsAtEndOfPipeline(Mutable<ILogicalOperator> opRef) {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
             return opRef;
         }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InsertProjectBeforeUnionRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InsertProjectBeforeUnionRule.java
index d87f00b..337117e 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InsertProjectBeforeUnionRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InsertProjectBeforeUnionRule.java
@@ -17,9 +17,11 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
@@ -34,7 +36,8 @@
 public class InsertProjectBeforeUnionRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
         return false;
     }
 
@@ -44,8 +47,8 @@
      * write order
      */
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.UNIONALL) {
             return false;
         }
@@ -60,10 +63,10 @@
         }
 
         ArrayList<LogicalVariable> inputSchemaOne = new ArrayList<LogicalVariable>();
-        VariableUtilities.getLiveVariables(opUnion.getInputs().get(0).getOperator(), inputSchemaOne);
+        VariableUtilities.getLiveVariables(opUnion.getInputs().get(0).getValue(), inputSchemaOne);
 
         ArrayList<LogicalVariable> inputSchemaTwo = new ArrayList<LogicalVariable>();
-        VariableUtilities.getLiveVariables(opUnion.getInputs().get(1).getOperator(), inputSchemaTwo);
+        VariableUtilities.getLiveVariables(opUnion.getInputs().get(1).getValue(), inputSchemaTwo);
 
         boolean rewritten = false;
         if (!isIdentical(usedVariablesFromOne, inputSchemaOne)) {
@@ -80,9 +83,9 @@
     private void insertProjectOperator(UnionAllOperator opUnion, int branch, ArrayList<LogicalVariable> usedVariables,
             IOptimizationContext context) throws AlgebricksException {
         ProjectOperator projectOp = new ProjectOperator(usedVariables);
-        ILogicalOperator parentOp = opUnion.getInputs().get(branch).getOperator();
-        projectOp.getInputs().add(new LogicalOperatorReference(parentOp));
-        opUnion.getInputs().get(branch).setOperator(projectOp);
+        ILogicalOperator parentOp = opUnion.getInputs().get(branch).getValue();
+        projectOp.getInputs().add(new MutableObject<ILogicalOperator>(parentOp));
+        opUnion.getInputs().get(branch).setValue(projectOp);
         projectOp.setPhysicalOperator(new StreamProjectPOperator());
         context.computeAndSetTypeEnvironmentForOperator(parentOp);
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroHashPartitionMergeExchange.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroHashPartitionMergeExchange.java
index 494a7ba..0e12bcc 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroHashPartitionMergeExchange.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroHashPartitionMergeExchange.java
@@ -3,8 +3,10 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.HashPartitionExchangePOperator;
@@ -17,18 +19,19 @@
 public class IntroHashPartitionMergeExchange implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
         if (op1.getPhysicalOperator() == null
                 || op1.getPhysicalOperator().getOperatorTag() != PhysicalOperatorTag.HASH_PARTITION_EXCHANGE) {
             return false;
         }
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
         if (op2.getPhysicalOperator() == null
                 || op2.getPhysicalOperator().getOperatorTag() != PhysicalOperatorTag.SORT_MERGE_EXCHANGE) {
             return false;
@@ -42,7 +45,7 @@
         HashPartitionMergeExchangePOperator hpme = new HashPartitionMergeExchangePOperator(ocList, hpe.getHashFields(),
                 hpe.getDomain());
         op1.setPhysicalOperator(hpme);
-        op1.getInputs().get(0).setOperator(op2.getInputs().get(0).getOperator());
+        op1.getInputs().get(0).setValue(op2.getInputs().get(0).getValue());
         return true;
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroJoinInsideSubplanRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroJoinInsideSubplanRule.java
index 31bb3b7..acff2de 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroJoinInsideSubplanRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroJoinInsideSubplanRule.java
@@ -18,10 +18,13 @@
 import java.util.ListIterator;
 import java.util.Set;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
@@ -36,15 +39,16 @@
 public class IntroJoinInsideSubplanRule extends AbstractDecorrelationRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op0 = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op0 = (AbstractLogicalOperator) opRef.getValue();
         if (op0.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
             return false;
         }
         SubplanOperator subplan = (SubplanOperator) op0;
 
-        LogicalOperatorReference leftRef = subplan.getInputs().get(0);
-        if (((AbstractLogicalOperator) leftRef.getOperator()).getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
+        Mutable<ILogicalOperator> leftRef = subplan.getInputs().get(0);
+        if (((AbstractLogicalOperator) leftRef.getValue()).getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE) {
             return false;
         }
 
@@ -59,16 +63,16 @@
         if (p.getRoots().size() != 1) {
             return false;
         }
-        LogicalOperatorReference opRef1 = p.getRoots().get(0);
+        Mutable<ILogicalOperator> opRef1 = p.getRoots().get(0);
 
         while (true) {
-            AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef1.getOperator();
+            AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef1.getValue();
             if (op1.getInputs().size() != 1) {
                 return false;
             }
             if (op1.getOperatorTag() == LogicalOperatorTag.SELECT) {
-                LogicalOperatorReference op2Ref = op1.getInputs().get(0);
-                AbstractLogicalOperator op2 = (AbstractLogicalOperator) op2Ref.getOperator();
+                Mutable<ILogicalOperator> op2Ref = op1.getInputs().get(0);
+                AbstractLogicalOperator op2 = (AbstractLogicalOperator) op2Ref.getValue();
                 if (op2.getOperatorTag() != LogicalOperatorTag.SELECT && descOrSelfIsScanOrJoin(op2)) {
                     Set<LogicalVariable> free2 = new HashSet<LogicalVariable>();
                     OperatorPropertiesUtil.getFreeVariablesInSelfOrDesc(op2, free2);
@@ -77,13 +81,13 @@
                         OperatorPropertiesUtil.getFreeVariablesInSelfOrDesc(op1, free1);
                         if (!free1.isEmpty()) {
                             OperatorManipulationUtil.ntsToEts(op2Ref, context);
-                            NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new LogicalOperatorReference(
-                                    subplan));
-                            LogicalOperatorReference ntsRef = new LogicalOperatorReference(nts);
-                            LogicalOperatorReference innerRef = new LogicalOperatorReference(op2);
-                            InnerJoinOperator join = new InnerJoinOperator(new LogicalExpressionReference(
+                            NestedTupleSourceOperator nts = new NestedTupleSourceOperator(
+                                    new MutableObject<ILogicalOperator>(subplan));
+                            Mutable<ILogicalOperator> ntsRef = new MutableObject<ILogicalOperator>(nts);
+                            Mutable<ILogicalOperator> innerRef = new MutableObject<ILogicalOperator>(op2);
+                            InnerJoinOperator join = new InnerJoinOperator(new MutableObject<ILogicalExpression>(
                                     ConstantExpression.TRUE), ntsRef, innerRef);
-                            op2Ref.setOperator(join);
+                            op2Ref.setValue(join);
                             context.computeAndSetTypeEnvironmentForOperator(nts);
                             context.computeAndSetTypeEnvironmentForOperator(join);
                             return true;
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceCombinerRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceCombinerRule.java
index d90504c..c05572b 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceCombinerRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceCombinerRule.java
@@ -9,12 +9,13 @@
 import java.util.Map.Entry;
 import java.util.Set;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.OperatorAnnotations;
@@ -23,11 +24,11 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
 import edu.uci.ics.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
 import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
@@ -38,13 +39,14 @@
 public class IntroduceCombinerRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (context.checkIfInDontApplySet(this, op)) {
             return false;
         }
@@ -70,17 +72,17 @@
         for (Map.Entry<AggregateFunctionCallExpression, SimilarAggregatesInfo> entry : toReplaceMap.entrySet()) {
             SimilarAggregatesInfo sai = entry.getValue();
             for (AggregateExprInfo aei : sai.simAggs) {
-                AbstractFunctionCallExpression afce = (AbstractFunctionCallExpression) aei.aggExprRef.getExpression();
+                AbstractFunctionCallExpression afce = (AbstractFunctionCallExpression) aei.aggExprRef.getValue();
                 afce.setFunctionInfo(aei.newFunInfo);
                 afce.getArguments().clear();
-                afce.getArguments().add(new LogicalExpressionReference(sai.stepOneResult));
+                afce.getArguments().add(new MutableObject<ILogicalExpression>(sai.stepOneResult));
             }
         }
 
-        for (Pair<LogicalVariable, LogicalExpressionReference> p : gbyOp.getDecorList()) {
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gbyOp.getDecorList()) {
             LogicalVariable newDecorVar = context.newVar();
-            newGbyOp.addDecorExpression(newDecorVar, p.second.getExpression());
-            p.second.setExpression(new VariableReferenceExpression(newDecorVar));
+            newGbyOp.addDecorExpression(newDecorVar, p.second.getValue());
+            p.second.setValue(new VariableReferenceExpression(newDecorVar));
         }
         newGbyOp.setExecutionMode(ExecutionMode.LOCAL);
         Object v = gbyOp.getAnnotations().get(OperatorAnnotations.USE_HASH_GROUP_BY);
@@ -99,13 +101,13 @@
             if (!propagatedVars.contains(var)) {
                 LogicalVariable newDecorVar = context.newVar();
                 newGbyOp.addDecorExpression(newDecorVar, new VariableReferenceExpression(var));
-                VariableUtilities.substituteVariables(gbyOp.getNestedPlans().get(0).getRoots().get(0).getOperator(),
-                        var, newDecorVar, context);
+                VariableUtilities.substituteVariables(gbyOp.getNestedPlans().get(0).getRoots().get(0).getValue(), var,
+                        newDecorVar, context);
             }
         }
 
-        LogicalOperatorReference opRef3 = gbyOp.getInputs().get(0);
-        opRef3.setOperator(newGbyOp);
+        Mutable<ILogicalOperator> opRef3 = gbyOp.getInputs().get(0);
+        opRef3.setValue(newGbyOp);
         typeGby(newGbyOp, context);
         typeGby(gbyOp, context);
         return true;
@@ -121,10 +123,10 @@
     private GroupByOperator opToPush(GroupByOperator gbyOp, BookkeepingInfo bi, IOptimizationContext context)
             throws AlgebricksException {
 
-        LogicalOperatorReference opRef3 = gbyOp.getInputs().get(0);
-        ILogicalOperator op3 = opRef3.getOperator();
+        Mutable<ILogicalOperator> opRef3 = gbyOp.getInputs().get(0);
+        ILogicalOperator op3 = opRef3.getValue();
         GroupByOperator newGbyOp = new GroupByOperator();
-        newGbyOp.getInputs().add(new LogicalOperatorReference(op3));
+        newGbyOp.getInputs().add(new MutableObject<ILogicalOperator>(op3));
         // copy annotations
         Map<String, Object> annotations = newGbyOp.getAnnotations();
         for (Entry<String, Object> a : gbyOp.getAnnotations().entrySet())
@@ -183,15 +185,15 @@
 
     private Pair<Boolean, ILogicalPlan> tryToPushSubplan(ILogicalPlan p, GroupByOperator oldGbyOp,
             GroupByOperator newGbyOp, BookkeepingInfo bi, List<LogicalVariable> gbyVars, IOptimizationContext context) {
-        List<LogicalOperatorReference> pushedRoots = new ArrayList<LogicalOperatorReference>();
-        List<LogicalOperatorReference> toPushR = new ArrayList<LogicalOperatorReference>();
-        for (LogicalOperatorReference r : p.getRoots()) {
+        List<Mutable<ILogicalOperator>> pushedRoots = new ArrayList<Mutable<ILogicalOperator>>();
+        List<Mutable<ILogicalOperator>> toPushR = new ArrayList<Mutable<ILogicalOperator>>();
+        for (Mutable<ILogicalOperator> r : p.getRoots()) {
             if (!tryToPushRoot(r, oldGbyOp, newGbyOp, bi, gbyVars, context, toPushR)) {
                 // for now, if we cannot push everything, give up
                 return new Pair<Boolean, ILogicalPlan>(false, null);
             }
         }
-        for (LogicalOperatorReference root : toPushR) {
+        for (Mutable<ILogicalOperator> root : toPushR) {
             pushedRoots.add(root);
         }
         if (pushedRoots.isEmpty()) {
@@ -201,21 +203,21 @@
         }
     }
 
-    private boolean tryToPushRoot(LogicalOperatorReference r, GroupByOperator oldGbyOp, GroupByOperator newGbyOp,
+    private boolean tryToPushRoot(Mutable<ILogicalOperator> r, GroupByOperator oldGbyOp, GroupByOperator newGbyOp,
             BookkeepingInfo bi, List<LogicalVariable> gbyVars, IOptimizationContext context,
-            List<LogicalOperatorReference> toPushAccumulate) {
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) r.getOperator();
+            List<Mutable<ILogicalOperator>> toPushAccumulate) {
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) r.getValue();
         if (op1.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
             return false;
         }
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
         if (op2.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
             AggregateOperator initAgg = (AggregateOperator) op1;
-            Pair<Boolean, LogicalOperatorReference> pOpRef = tryToPushAgg(initAgg, newGbyOp, bi.toReplaceMap, context);
+            Pair<Boolean, Mutable<ILogicalOperator>> pOpRef = tryToPushAgg(initAgg, newGbyOp, bi.toReplaceMap, context);
             if (!pOpRef.first) {
                 return false;
             }
-            LogicalOperatorReference opRef = pOpRef.second;
+            Mutable<ILogicalOperator> opRef = pOpRef.second;
             if (opRef != null) {
                 toPushAccumulate.add(opRef);
             }
@@ -223,7 +225,7 @@
             return true;
         } else {
             while (op2.getOperatorTag() != LogicalOperatorTag.GROUP && op2.getInputs().size() == 1) {
-                op2 = (AbstractLogicalOperator) op2.getInputs().get(0).getOperator();
+                op2 = (AbstractLogicalOperator) op2.getInputs().get(0).getValue();
             }
             if (op2.getOperatorTag() != LogicalOperatorTag.GROUP) {
                 return false;
@@ -233,7 +235,7 @@
             List<LogicalVariable> concatGbyVars = new ArrayList<LogicalVariable>(gbyVars);
             concatGbyVars.addAll(gbyVars2);
             for (ILogicalPlan p : nestedGby.getNestedPlans()) {
-                for (LogicalOperatorReference r2 : p.getRoots()) {
+                for (Mutable<ILogicalOperator> r2 : p.getRoots()) {
                     if (!tryToPushRoot(r2, nestedGby, newGbyOp, bi, concatGbyVars, context, toPushAccumulate)) {
                         return false;
                     }
@@ -243,34 +245,34 @@
         }
     }
 
-    private Pair<Boolean, LogicalOperatorReference> tryToPushAgg(AggregateOperator initAgg, GroupByOperator newGbyOp,
+    private Pair<Boolean, Mutable<ILogicalOperator>> tryToPushAgg(AggregateOperator initAgg, GroupByOperator newGbyOp,
             Map<AggregateFunctionCallExpression, SimilarAggregatesInfo> toReplaceMap, IOptimizationContext context) {
 
         ArrayList<LogicalVariable> pushedVars = new ArrayList<LogicalVariable>();
-        ArrayList<LogicalExpressionReference> pushedExprs = new ArrayList<LogicalExpressionReference>();
+        ArrayList<Mutable<ILogicalExpression>> pushedExprs = new ArrayList<Mutable<ILogicalExpression>>();
 
         List<LogicalVariable> initVars = initAgg.getVariables();
-        List<LogicalExpressionReference> initExprs = initAgg.getExpressions();
+        List<Mutable<ILogicalExpression>> initExprs = initAgg.getExpressions();
         int sz = initVars.size();
         for (int i = 0; i < sz; i++) {
-            AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) initExprs.get(i).getExpression();
+            AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) initExprs.get(i).getValue();
             if (!aggFun.isTwoStep()) {
-                return new Pair<Boolean, LogicalOperatorReference>(false, null);
+                return new Pair<Boolean, Mutable<ILogicalOperator>>(false, null);
             }
         }
 
         boolean haveAggToReplace = false;
         for (int i = 0; i < sz; i++) {
-            LogicalExpressionReference expRef = initExprs.get(i);
-            AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) expRef.getExpression();
+            Mutable<ILogicalExpression> expRef = initExprs.get(i);
+            AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) expRef.getValue();
             IFunctionInfo fi1 = aggFun.getStepOneAggregate();
-            List<LogicalExpressionReference> newArgs = new ArrayList<LogicalExpressionReference>(aggFun.getArguments()
-                    .size());
-            for (LogicalExpressionReference er : aggFun.getArguments()) {
-                newArgs.add(new LogicalExpressionReference(er.getExpression().cloneExpression()));
+            List<Mutable<ILogicalExpression>> newArgs = new ArrayList<Mutable<ILogicalExpression>>(aggFun
+                    .getArguments().size());
+            for (Mutable<ILogicalExpression> er : aggFun.getArguments()) {
+                newArgs.add(new MutableObject<ILogicalExpression>(er.getValue().cloneExpression()));
             }
-//            AggregateFunctionCallExpression aggLocal = new AggregateFunctionCallExpression(fi1, false, newArgs);
-//            pushedExprs.add(new LogicalExpressionReference(aggLocal));
+            //            AggregateFunctionCallExpression aggLocal = new AggregateFunctionCallExpression(fi1, false, newArgs);
+            //            pushedExprs.add(new Mutable<ILogicalExpression>(aggLocal));
 
             IFunctionInfo fi2 = aggFun.getStepTwoAggregate();
 
@@ -283,7 +285,7 @@
                 inf.simAggs = new ArrayList<AggregateExprInfo>();
                 toReplaceMap.put(aggFun, inf);
                 AggregateFunctionCallExpression aggLocal = new AggregateFunctionCallExpression(fi1, false, newArgs);
-                pushedExprs.add(new LogicalExpressionReference(aggLocal));
+                pushedExprs.add(new MutableObject<ILogicalExpression>(aggLocal));
             }
             AggregateExprInfo aei = new AggregateExprInfo();
             aei.aggExprRef = expRef;
@@ -295,12 +297,12 @@
         if (!pushedVars.isEmpty()) {
             AggregateOperator pushedAgg = new AggregateOperator(pushedVars, pushedExprs);
             pushedAgg.setExecutionMode(ExecutionMode.LOCAL);
-            NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new LogicalOperatorReference(newGbyOp));
+            NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(newGbyOp));
             nts.setExecutionMode(ExecutionMode.LOCAL);
-            pushedAgg.getInputs().add(new LogicalOperatorReference(nts));
-            return new Pair<Boolean, LogicalOperatorReference>(true, new LogicalOperatorReference(pushedAgg));
+            pushedAgg.getInputs().add(new MutableObject<ILogicalOperator>(nts));
+            return new Pair<Boolean, Mutable<ILogicalOperator>>(true, new MutableObject<ILogicalOperator>(pushedAgg));
         } else {
-            return new Pair<Boolean, LogicalOperatorReference>(haveAggToReplace, null);
+            return new Pair<Boolean, Mutable<ILogicalOperator>>(haveAggToReplace, null);
         }
     }
 
@@ -310,7 +312,7 @@
     }
 
     private class AggregateExprInfo {
-        LogicalExpressionReference aggExprRef;
+        Mutable<ILogicalExpression> aggExprRef;
         IFunctionInfo newFunInfo;
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceGroupByForStandaloneAggregRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceGroupByForStandaloneAggregRule.java
index eeaac23..34060c2 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceGroupByForStandaloneAggregRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceGroupByForStandaloneAggregRule.java
@@ -18,10 +18,13 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
@@ -46,18 +49,19 @@
 public class IntroduceGroupByForStandaloneAggregRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
             return false;
         }
-        LogicalOperatorReference opRef2 = op.getInputs().get(0);
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getOperator();
+        Mutable<ILogicalOperator> opRef2 = op.getInputs().get(0);
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
         if (op2.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
             return false;
         }
@@ -71,26 +75,26 @@
         List<LogicalVariable> used = new LinkedList<LogicalVariable>();
         VariableUtilities.getUsedVariables(assign, used);
         if (used.contains(aggVar)) {
-            LogicalOperatorReference opRef3 = op2.getInputs().get(0);
-            List<Pair<LogicalVariable, LogicalExpressionReference>> groupByList = new ArrayList<Pair<LogicalVariable, LogicalExpressionReference>>();
+            Mutable<ILogicalOperator> opRef3 = op2.getInputs().get(0);
+            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
             LogicalVariable gbyVar = context.newVar();
             // ILogicalExpression constOne = new ConstantExpression(new
             // IntegerLiteral(new Integer(1)));
-            groupByList.add(new Pair<LogicalVariable, LogicalExpressionReference>(gbyVar,
-                    new LogicalExpressionReference(ConstantExpression.TRUE)));
-            NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new LogicalOperatorReference());
-            List<LogicalOperatorReference> aggInpList = agg.getInputs();
+            groupByList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(gbyVar,
+                    new MutableObject<ILogicalExpression>(ConstantExpression.TRUE)));
+            NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>());
+            List<Mutable<ILogicalOperator>> aggInpList = agg.getInputs();
             aggInpList.clear();
-            aggInpList.add(new LogicalOperatorReference(nts));
+            aggInpList.add(new MutableObject<ILogicalOperator>(nts));
             ILogicalPlan np1 = new ALogicalPlanImpl(opRef2);
             ArrayList<ILogicalPlan> nestedPlans = new ArrayList<ILogicalPlan>();
             nestedPlans.add(np1);
             GroupByOperator gbyOp = new GroupByOperator(groupByList,
-                    new ArrayList<Pair<LogicalVariable, LogicalExpressionReference>>(), nestedPlans);
-            LogicalOperatorReference opRefGby = new LogicalOperatorReference(gbyOp);
-            nts.getDataSourceReference().setOperator(gbyOp);
+                    new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>(), nestedPlans);
+            Mutable<ILogicalOperator> opRefGby = new MutableObject<ILogicalOperator>(gbyOp);
+            nts.getDataSourceReference().setValue(gbyOp);
             gbyOp.getInputs().add(opRef3);
-            List<LogicalOperatorReference> asgnInpList = assign.getInputs();
+            List<Mutable<ILogicalOperator>> asgnInpList = assign.getInputs();
             context.computeAndSetTypeEnvironmentForOperator(nts);
             context.computeAndSetTypeEnvironmentForOperator(agg);
             context.computeAndSetTypeEnvironmentForOperator(gbyOp);
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceGroupByForSubplanRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceGroupByForSubplanRule.java
index 4f9b2ea..87297e7 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceGroupByForSubplanRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IntroduceGroupByForSubplanRule.java
@@ -23,11 +23,13 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
@@ -60,13 +62,14 @@
 public class IntroduceGroupByForSubplanRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op0 = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op0 = (AbstractLogicalOperator) opRef.getValue();
         if (op0.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
             return false;
         }
@@ -83,10 +86,10 @@
         if (p.getRoots().size() != 1) {
             return false;
         }
-        LogicalOperatorReference subplanRoot = p.getRoots().get(0);
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) subplanRoot.getOperator();
+        Mutable<ILogicalOperator> subplanRoot = p.getRoots().get(0);
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) subplanRoot.getValue();
 
-        LogicalOperatorReference botRef = subplanRoot;
+        Mutable<ILogicalOperator> botRef = subplanRoot;
         AbstractLogicalOperator op2;
         // Project is optional
         if (op1.getOperatorTag() != LogicalOperatorTag.PROJECT) {
@@ -94,7 +97,7 @@
         } else {
             ProjectOperator project = (ProjectOperator) op1;
             botRef = project.getInputs().get(0);
-            op2 = (AbstractLogicalOperator) botRef.getOperator();
+            op2 = (AbstractLogicalOperator) botRef.getValue();
         }
         if (op2.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
             return false;
@@ -104,8 +107,8 @@
         Set<LogicalVariable> free = new HashSet<LogicalVariable>();
         VariableUtilities.getUsedVariables(aggregate, free);
 
-        LogicalOperatorReference op3Ref = aggregate.getInputs().get(0);
-        AbstractLogicalOperator op3 = (AbstractLogicalOperator) op3Ref.getOperator();
+        Mutable<ILogicalOperator> op3Ref = aggregate.getInputs().get(0);
+        AbstractLogicalOperator op3 = (AbstractLogicalOperator) op3Ref.getValue();
 
         while (op3.getInputs().size() == 1) {
             Set<LogicalVariable> prod = new HashSet<LogicalVariable>();
@@ -114,7 +117,7 @@
             VariableUtilities.getUsedVariables(op3, free);
             botRef = op3Ref;
             op3Ref = op3.getInputs().get(0);
-            op3 = (AbstractLogicalOperator) op3Ref.getOperator();
+            op3 = (AbstractLogicalOperator) op3Ref.getValue();
         }
 
         if (op3.getOperatorTag() != LogicalOperatorTag.INNERJOIN
@@ -122,16 +125,16 @@
             return false;
         }
         AbstractBinaryJoinOperator join = (AbstractBinaryJoinOperator) op3;
-        if (join.getCondition().getExpression() == ConstantExpression.TRUE) {
+        if (join.getCondition().getValue() == ConstantExpression.TRUE) {
             return false;
         }
         VariableUtilities.getUsedVariables(join, free);
 
-        AbstractLogicalOperator b0 = (AbstractLogicalOperator) join.getInputs().get(0).getOperator();
+        AbstractLogicalOperator b0 = (AbstractLogicalOperator) join.getInputs().get(0).getValue();
         // see if there's an NTS at the end of the pipeline
         NestedTupleSourceOperator outerNts = getNts(b0);
         if (outerNts == null) {
-            AbstractLogicalOperator b1 = (AbstractLogicalOperator) join.getInputs().get(1).getOperator();
+            AbstractLogicalOperator b1 = (AbstractLogicalOperator) join.getInputs().get(1).getValue();
             outerNts = getNts(b1);
             if (outerNts == null) {
                 return false;
@@ -145,9 +148,9 @@
         }
         AlgebricksConfig.ALGEBRICKS_LOGGER.fine("Found FD for introducing group-by: " + pkVars);
 
-        LogicalOperatorReference rightRef = join.getInputs().get(1);
+        Mutable<ILogicalOperator> rightRef = join.getInputs().get(1);
         LogicalVariable testForNull = null;
-        AbstractLogicalOperator right = (AbstractLogicalOperator) rightRef.getOperator();
+        AbstractLogicalOperator right = (AbstractLogicalOperator) rightRef.getValue();
         switch (right.getOperatorTag()) {
             case UNNEST: {
                 UnnestOperator innerUnnest = (UnnestOperator) right;
@@ -166,43 +169,43 @@
         }
         if (testForNull == null) {
             testForNull = context.newVar();
-            AssignOperator tmpAsgn = new AssignOperator(testForNull, new LogicalExpressionReference(
+            AssignOperator tmpAsgn = new AssignOperator(testForNull, new MutableObject<ILogicalExpression>(
                     ConstantExpression.TRUE));
-            tmpAsgn.getInputs().add(new LogicalOperatorReference(rightRef.getOperator()));
-            rightRef.setOperator(tmpAsgn);
+            tmpAsgn.getInputs().add(new MutableObject<ILogicalOperator>(rightRef.getValue()));
+            rightRef.setValue(tmpAsgn);
             context.computeAndSetTypeEnvironmentForOperator(tmpAsgn);
         }
 
         IFunctionInfo finfoEq = AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.IS_NULL);
-        ILogicalExpression isNullTest = new ScalarFunctionCallExpression(finfoEq, new LogicalExpressionReference(
-                new VariableReferenceExpression(testForNull)));
+        ILogicalExpression isNullTest = new ScalarFunctionCallExpression(finfoEq,
+                new MutableObject<ILogicalExpression>(new VariableReferenceExpression(testForNull)));
         IFunctionInfo finfoNot = AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.NOT);
         ScalarFunctionCallExpression nonNullTest = new ScalarFunctionCallExpression(finfoNot,
-                new LogicalExpressionReference(isNullTest));
-        SelectOperator selectNonNull = new SelectOperator(new LogicalExpressionReference(nonNullTest));
+                new MutableObject<ILogicalExpression>(isNullTest));
+        SelectOperator selectNonNull = new SelectOperator(new MutableObject<ILogicalExpression>(nonNullTest));
         GroupByOperator g = new GroupByOperator();
-        LogicalOperatorReference newSubplanRef = new LogicalOperatorReference(subplan);
-        NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new LogicalOperatorReference(g));
-        opRef.setOperator(g);
-        selectNonNull.getInputs().add(new LogicalOperatorReference(nts));
+        Mutable<ILogicalOperator> newSubplanRef = new MutableObject<ILogicalOperator>(subplan);
+        NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(g));
+        opRef.setValue(g);
+        selectNonNull.getInputs().add(new MutableObject<ILogicalOperator>(nts));
 
-        List<LogicalOperatorReference> prodInpList = botRef.getOperator().getInputs();
+        List<Mutable<ILogicalOperator>> prodInpList = botRef.getValue().getInputs();
         prodInpList.clear();
-        prodInpList.add(new LogicalOperatorReference(selectNonNull));
+        prodInpList.add(new MutableObject<ILogicalOperator>(selectNonNull));
 
-        ILogicalPlan gPlan = new ALogicalPlanImpl(new LogicalOperatorReference(subplanRoot.getOperator()));
+        ILogicalPlan gPlan = new ALogicalPlanImpl(new MutableObject<ILogicalOperator>(subplanRoot.getValue()));
         g.getNestedPlans().add(gPlan);
-        subplanRoot.setOperator(op3Ref.getOperator());
+        subplanRoot.setValue(op3Ref.getValue());
         g.getInputs().add(newSubplanRef);
 
         HashSet<LogicalVariable> underVars = new HashSet<LogicalVariable>();
-        VariableUtilities.getLiveVariables(subplan.getInputs().get(0).getOperator(), underVars);
+        VariableUtilities.getLiveVariables(subplan.getInputs().get(0).getValue(), underVars);
         underVars.removeAll(pkVars);
         Map<LogicalVariable, LogicalVariable> mappedVars = buildVarExprList(pkVars, context, g, g.getGroupByList());
         context.updatePrimaryKeys(mappedVars);
         for (LogicalVariable uv : underVars) {
             g.getDecorList().add(
-                    new Pair<LogicalVariable, LogicalExpressionReference>(null, new LogicalExpressionReference(
+                    new Pair<LogicalVariable, Mutable<ILogicalExpression>>(null, new MutableObject<ILogicalExpression>(
                             new VariableReferenceExpression(uv))));
         }
         OperatorPropertiesUtil.typeOpRec(subplanRoot, context);
@@ -220,7 +223,7 @@
             if (alo.getInputs().size() != 1) {
                 return null;
             }
-            alo = (AbstractLogicalOperator) alo.getInputs().get(0).getOperator();
+            alo = (AbstractLogicalOperator) alo.getInputs().get(0).getValue();
         } while (true);
     }
 
@@ -245,20 +248,20 @@
 
     private Map<LogicalVariable, LogicalVariable> buildVarExprList(Collection<LogicalVariable> vars,
             IOptimizationContext context, GroupByOperator g,
-            List<Pair<LogicalVariable, LogicalExpressionReference>> outVeList) throws AlgebricksException {
+            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> outVeList) throws AlgebricksException {
         Map<LogicalVariable, LogicalVariable> m = new HashMap<LogicalVariable, LogicalVariable>();
         for (LogicalVariable ov : vars) {
             LogicalVariable newVar = context.newVar();
             ILogicalExpression varExpr = new VariableReferenceExpression(newVar);
-            outVeList.add(new Pair<LogicalVariable, LogicalExpressionReference>(ov, new LogicalExpressionReference(
-                    varExpr)));
+            outVeList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(ov,
+                    new MutableObject<ILogicalExpression>(varExpr)));
             for (ILogicalPlan p : g.getNestedPlans()) {
-                for (LogicalOperatorReference r : p.getRoots()) {
-                    OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getOperator(), ov, newVar,
-                            true, context);
+                for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                    OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getValue(), ov, newVar, true,
+                            context);
                 }
             }
-            AbstractLogicalOperator opUnder = (AbstractLogicalOperator) g.getInputs().get(0).getOperator();
+            AbstractLogicalOperator opUnder = (AbstractLogicalOperator) g.getInputs().get(0).getValue();
             OperatorManipulationUtil.substituteVarRec(opUnder, ov, newVar, true, context);
             m.put(ov, newVar);
         }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IsolateHyracksOperatorsRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IsolateHyracksOperatorsRule.java
index 40b5c85..194b818 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IsolateHyracksOperatorsRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/IsolateHyracksOperatorsRule.java
@@ -14,15 +14,17 @@
  */
 package edu.uci.ics.hyracks.algebricks.rewriter.rules;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IPhysicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ExchangeOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ExchangeOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.OneToOneExchangePOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -37,8 +39,9 @@
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         IPhysicalOperator pt = op.getPhysicalOperator();
 
         if (pt == null || op.getOperatorTag() == LogicalOperatorTag.EXCHANGE) {
@@ -52,17 +55,17 @@
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
-    private boolean testIfExchangeBelow(LogicalOperatorReference opRef, IOptimizationContext context)
+    private boolean testIfExchangeBelow(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
             throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         boolean exchInserted = false;
 
-        for (LogicalOperatorReference i : op.getInputs()) {
-            AbstractLogicalOperator c = (AbstractLogicalOperator) i.getOperator();
+        for (Mutable<ILogicalOperator> i : op.getInputs()) {
+            AbstractLogicalOperator c = (AbstractLogicalOperator) i.getValue();
             if (c.getOperatorTag() != LogicalOperatorTag.EXCHANGE) {
                 if (c.getPhysicalOperator() == null) {
                     return false;
@@ -73,8 +76,8 @@
         }
         IPhysicalOperator pt = op.getPhysicalOperator();
         if (pt.isJobGenDisabledBelowMe() || arrayContains(operatorsBelowWhichJobGenIsDisabled, pt.getOperatorTag())) {
-            for (LogicalOperatorReference i : op.getInputs()) {
-                disableJobGenRec(i.getOperator());
+            for (Mutable<ILogicalOperator> i : op.getInputs()) {
+                disableJobGenRec(i.getValue());
             }
         }
         return exchInserted;
@@ -83,20 +86,20 @@
     private void disableJobGenRec(ILogicalOperator operator) {
         AbstractLogicalOperator op = (AbstractLogicalOperator) operator;
         op.disableJobGen();
-        for (LogicalOperatorReference i : op.getInputs()) {
-            disableJobGenRec(i.getOperator());
+        for (Mutable<ILogicalOperator> i : op.getInputs()) {
+            disableJobGenRec(i.getValue());
         }
     }
 
-    private boolean testIfExchangeAbove(LogicalOperatorReference opRef, IOptimizationContext context)
+    private boolean testIfExchangeAbove(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
             throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() == LogicalOperatorTag.EXCHANGE) {
             return false;
         }
         boolean exchInserted = false;
-        for (LogicalOperatorReference i : op.getInputs()) {
-            AbstractLogicalOperator c = (AbstractLogicalOperator) i.getOperator();
+        for (Mutable<ILogicalOperator> i : op.getInputs()) {
+            AbstractLogicalOperator c = (AbstractLogicalOperator) i.getValue();
             IPhysicalOperator cpop = c.getPhysicalOperator();
             if (c.getOperatorTag() == LogicalOperatorTag.EXCHANGE || cpop == null) {
                 continue;
@@ -118,14 +121,14 @@
         return false;
     }
 
-    private final static void insertOneToOneExchange(LogicalOperatorReference i, IOptimizationContext context)
+    private final static void insertOneToOneExchange(Mutable<ILogicalOperator> i, IOptimizationContext context)
             throws AlgebricksException {
         ExchangeOperator e = new ExchangeOperator();
         e.setPhysicalOperator(new OneToOneExchangePOperator());
-        ILogicalOperator inOp = i.getOperator();
+        ILogicalOperator inOp = i.getValue();
 
-        e.getInputs().add(new LogicalOperatorReference(inOp));
-        i.setOperator(e);
+        e.getInputs().add(new MutableObject<ILogicalOperator>(inOp));
+        i.setValue(e);
         // e.recomputeSchema();
         OperatorPropertiesUtil.computeSchemaAndPropertiesRecIfNull(e, context);
         ExecutionMode em = ((AbstractLogicalOperator) inOp).getExecutionMode();
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PullSelectOutOfEqJoin.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PullSelectOutOfEqJoin.java
index 6755e59..7ee1f49 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PullSelectOutOfEqJoin.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PullSelectOutOfEqJoin.java
@@ -17,11 +17,13 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
@@ -36,17 +38,18 @@
 
 public class PullSelectOutOfEqJoin implements IAlgebraicRewriteRule {
 
-    private List<LogicalExpressionReference> eqVarVarComps = new ArrayList<LogicalExpressionReference>();
-    private List<LogicalExpressionReference> otherPredicates = new ArrayList<LogicalExpressionReference>();
+    private List<Mutable<ILogicalExpression>> eqVarVarComps = new ArrayList<Mutable<ILogicalExpression>>();
+    private List<Mutable<ILogicalExpression>> otherPredicates = new ArrayList<Mutable<ILogicalExpression>>();
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
 
         if (op.getOperatorTag() != LogicalOperatorTag.INNERJOIN
                 && op.getOperatorTag() != LogicalOperatorTag.LEFTOUTERJOIN) {
@@ -54,7 +57,7 @@
         }
         AbstractBinaryJoinOperator join = (AbstractBinaryJoinOperator) op;
 
-        ILogicalExpression expr = join.getCondition().getExpression();
+        ILogicalExpression expr = join.getCondition().getValue();
         if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
             return false;
         }
@@ -65,8 +68,8 @@
         }
         eqVarVarComps.clear();
         otherPredicates.clear();
-        for (LogicalExpressionReference arg : fexp.getArguments()) {
-            if (isEqVarVar(arg.getExpression())) {
+        for (Mutable<ILogicalExpression> arg : fexp.getArguments()) {
+            if (isEqVarVar(arg.getValue())) {
                 eqVarVarComps.add(arg);
             } else {
                 otherPredicates.add(arg);
@@ -77,21 +80,21 @@
         }
         // pull up
         ILogicalExpression pulledCond = makeCondition(otherPredicates);
-        SelectOperator select = new SelectOperator(new LogicalExpressionReference(pulledCond));
+        SelectOperator select = new SelectOperator(new MutableObject<ILogicalExpression>(pulledCond));
         ILogicalExpression newJoinCond = makeCondition(eqVarVarComps);
-        join.getCondition().setExpression(newJoinCond);
-        select.getInputs().add(new LogicalOperatorReference(join));
-        opRef.setOperator(select);
+        join.getCondition().setValue(newJoinCond);
+        select.getInputs().add(new MutableObject<ILogicalOperator>(join));
+        opRef.setValue(select);
         context.computeAndSetTypeEnvironmentForOperator(select);
         return true;
     }
 
-    private ILogicalExpression makeCondition(List<LogicalExpressionReference> predList) {
+    private ILogicalExpression makeCondition(List<Mutable<ILogicalExpression>> predList) {
         if (predList.size() > 1) {
             IFunctionInfo finfo = AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.AND);
             return new ScalarFunctionCallExpression(finfo, predList);
         } else {
-            return predList.get(0).getExpression();
+            return predList.get(0).getValue();
         }
     }
 
@@ -103,11 +106,11 @@
         if (f.getFunctionIdentifier() != AlgebricksBuiltinFunctions.EQ) {
             return false;
         }
-        ILogicalExpression e1 = f.getArguments().get(0).getExpression();
+        ILogicalExpression e1 = f.getArguments().get(0).getValue();
         if (e1.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
             return false;
         } else {
-            ILogicalExpression e2 = f.getArguments().get(1).getExpression();
+            ILogicalExpression e2 = f.getArguments().get(1).getValue();
             return e2.getExpressionTag() == LogicalExpressionTag.VARIABLE;
         }
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushAssignDownThroughProductRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushAssignDownThroughProductRule.java
index b7e650c..5eb7160 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushAssignDownThroughProductRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushAssignDownThroughProductRule.java
@@ -17,9 +17,10 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
@@ -32,49 +33,50 @@
 public class PushAssignDownThroughProductRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
         if (op1.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
             return false;
         }
-        LogicalOperatorReference op2Ref = op1.getInputs().get(0);
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op2Ref.getOperator();
+        Mutable<ILogicalOperator> op2Ref = op1.getInputs().get(0);
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op2Ref.getValue();
         if (op2.getOperatorTag() != LogicalOperatorTag.INNERJOIN) {
             return false;
         }
         AbstractBinaryJoinOperator join = (AbstractBinaryJoinOperator) op2;
-        if (join.getCondition().getExpression() != ConstantExpression.TRUE) {
+        if (join.getCondition().getValue() != ConstantExpression.TRUE) {
             return false;
         }
 
         List<LogicalVariable> used = new ArrayList<LogicalVariable>();
         VariableUtilities.getUsedVariables(op1, used);
 
-        LogicalOperatorReference b0Ref = op2.getInputs().get(0);
-        ILogicalOperator b0 = b0Ref.getOperator();
+        Mutable<ILogicalOperator> b0Ref = op2.getInputs().get(0);
+        ILogicalOperator b0 = b0Ref.getValue();
         List<LogicalVariable> b0Scm = new ArrayList<LogicalVariable>();
         VariableUtilities.getLiveVariables(b0, b0Scm);
         if (b0Scm.containsAll(used)) {
             // push assign on left branch
-            op2Ref.setOperator(b0);
-            b0Ref.setOperator(op1);
-            opRef.setOperator(op2);
+            op2Ref.setValue(b0);
+            b0Ref.setValue(op1);
+            opRef.setValue(op2);
             return true;
         } else {
-            LogicalOperatorReference b1Ref = op2.getInputs().get(1);
-            ILogicalOperator b1 = b1Ref.getOperator();
+            Mutable<ILogicalOperator> b1Ref = op2.getInputs().get(1);
+            ILogicalOperator b1 = b1Ref.getValue();
             List<LogicalVariable> b1Scm = new ArrayList<LogicalVariable>();
             VariableUtilities.getLiveVariables(b1, b1Scm);
             if (b1Scm.containsAll(used)) {
                 // push assign on right branch
-                op2Ref.setOperator(b1);
-                b1Ref.setOperator(op1);
-                opRef.setOperator(op2);
+                op2Ref.setValue(b1);
+                b1Ref.setValue(op1);
+                opRef.setValue(op2);
                 return true;
             } else {
                 return false;
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushDieUpRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushDieUpRule.java
index 2a71c1b..ef7822f 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushDieUpRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushDieUpRule.java
@@ -1,7 +1,10 @@
 package edu.uci.ics.hyracks.algebricks.rewriter.rules;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -10,16 +13,17 @@
 public class PushDieUpRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op0 = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op0 = (AbstractLogicalOperator) opRef.getValue();
         if (op0.getInputs().size() == 0)
             return false;
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) op0.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) op0.getInputs().get(0).getValue();
 
         if (op1.getInputs().size() == 0)
             return false;
@@ -28,15 +32,15 @@
                 || tag == LogicalOperatorTag.INSERT_DELETE || tag == LogicalOperatorTag.WRITE_RESULT)
             return false;
 
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
         if (op2.getOperatorTag() == LogicalOperatorTag.DIE) {
-            op0.getInputs().get(0).setOperator(op2);
+            op0.getInputs().get(0).setValue(op2);
             op1.getInputs().clear();
-            for (LogicalOperatorReference ref : op2.getInputs())
+            for (Mutable<ILogicalOperator> ref : op2.getInputs())
                 op1.getInputs().add(ref);
             op2.getInputs().clear();
-            op2.getInputs().add(new LogicalOperatorReference(op1));
-            
+            op2.getInputs().add(new MutableObject<ILogicalOperator>(op1));
+
             context.computeAndSetTypeEnvironmentForOperator(op0);
             context.computeAndSetTypeEnvironmentForOperator(op1);
             context.computeAndSetTypeEnvironmentForOperator(op2);
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushLimitDownRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushLimitDownRule.java
index 467e8cb..1b096ea 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushLimitDownRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushLimitDownRule.java
@@ -16,8 +16,11 @@
 
 import java.util.LinkedList;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
@@ -35,7 +38,7 @@
 public class PushLimitDownRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
@@ -46,8 +49,8 @@
      */
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.LIMIT) {
             return false;
         }
@@ -56,8 +59,8 @@
             return false;
         }
 
-        LogicalOperatorReference opRef2 = opLim.getInputs().get(0);
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getOperator();
+        Mutable<ILogicalOperator> opRef2 = opLim.getInputs().get(0);
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
 
         if (context.checkAndAddToAlreadyCompared(op, op2)) {
             return false;
@@ -90,25 +93,25 @@
             }
             // we assume pipelineable ops. have only one input
             opRef2 = op2.getInputs().get(0);
-            op2 = (AbstractLogicalOperator) opRef2.getOperator();
+            op2 = (AbstractLogicalOperator) opRef2.getValue();
         } while (true);
 
         LimitOperator clone2 = null;
-        if (opLim.getOffset().getExpression() == null) {
-            clone2 = new LimitOperator(opLim.getMaxObjects().getExpression(), false);
+        if (opLim.getOffset().getValue() == null) {
+            clone2 = new LimitOperator(opLim.getMaxObjects().getValue(), false);
         } else {
             // push limit (max+offset)
             IFunctionInfo finfoAdd = AlgebricksBuiltinFunctions
                     .getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.NUMERIC_ADD);
-            ScalarFunctionCallExpression maxPlusOffset = new ScalarFunctionCallExpression(finfoAdd, opLim
-                    .getMaxObjects(), opLim.getOffset());
+            ScalarFunctionCallExpression maxPlusOffset = new ScalarFunctionCallExpression(finfoAdd,
+                    opLim.getMaxObjects(), opLim.getOffset());
             clone2 = new LimitOperator(maxPlusOffset, false);
         }
         clone2.setPhysicalOperator(new StreamLimitPOperator(false));
-        clone2.getInputs().add(new LogicalOperatorReference(op2));
+        clone2.getInputs().add(new MutableObject<ILogicalOperator>(op2));
         clone2.setExecutionMode(op2.getExecutionMode());
         clone2.recomputeSchema();
-        opRef2.setOperator(clone2);
+        opRef2.setValue(clone2);
         context.computeAndSetTypeEnvironmentForOperator(clone2);
         return true;
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushNestedOrderByUnderPreSortedGroupByRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushNestedOrderByUnderPreSortedGroupByRule.java
index 72bef8d..b925cfe 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushNestedOrderByUnderPreSortedGroupByRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushNestedOrderByUnderPreSortedGroupByRule.java
@@ -17,11 +17,12 @@
 import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
@@ -40,13 +41,14 @@
 public class PushNestedOrderByUnderPreSortedGroupByRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.GROUP) {
             return false;
         }
@@ -59,12 +61,12 @@
         }
         GroupByOperator gby = (GroupByOperator) op;
         ILogicalPlan plan = gby.getNestedPlans().get(0);
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) plan.getRoots().get(0).getOperator();
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) plan.getRoots().get(0).getValue();
         if (op1.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
             return false;
         }
-        LogicalOperatorReference opRef2 = op1.getInputs().get(0);
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getOperator();
+        Mutable<ILogicalOperator> opRef2 = op1.getInputs().get(0);
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
         if (op2.getOperatorTag() != LogicalOperatorTag.ORDER) {
             return false;
         }
@@ -78,7 +80,7 @@
             return false;
         }
         // StableSortPOperator sort1 = (StableSortPOperator) pOrder1;
-        AbstractLogicalOperator op3 = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator op3 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         if (op3.getOperatorTag() != LogicalOperatorTag.ORDER) {
             return false;
         }
@@ -93,7 +95,7 @@
         // OrderColumn[] sortColumns = new OrderColumn[n2 + n1];
         // System.arraycopy(sort2.getSortColumns(), 0, sortColumns, 0, n2);
         // int k = 0;
-        for (Pair<IOrder, LogicalExpressionReference> oe : order1.getOrderExpressions()) {
+        for (Pair<IOrder, Mutable<ILogicalExpression>> oe : order1.getOrderExpressions()) {
             order2.getOrderExpressions().add(oe);
             // sortColumns[n2 + k] = sort1.getSortColumns()[k];
             // ++k;
@@ -101,8 +103,8 @@
         // sort2.setSortColumns(sortColumns);
         sort2.computeDeliveredProperties(order2, null);
         // remove order1
-        ILogicalOperator underOrder1 = order1.getInputs().get(0).getOperator();
-        opRef2.setOperator(underOrder1);
+        ILogicalOperator underOrder1 = order1.getInputs().get(0).getValue();
+        opRef2.setValue(underOrder1);
         return true;
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushProjectDownRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushProjectDownRule.java
index f393739..b70d88d 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushProjectDownRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushProjectDownRule.java
@@ -20,11 +20,13 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
@@ -47,18 +49,18 @@
 public class PushProjectDownRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.PROJECT) {
             return false;
         }
         ProjectOperator pi = (ProjectOperator) op;
-        LogicalOperatorReference opRef2 = pi.getInputs().get(0);
+        Mutable<ILogicalOperator> opRef2 = pi.getInputs().get(0);
 
         HashSet<LogicalVariable> toPush = new HashSet<LogicalVariable>();
         toPush.addAll(pi.getVariables());
@@ -66,7 +68,7 @@
         Pair<Boolean, Boolean> p = pushThroughOp(toPush, opRef2, op, context);
         boolean smthWasPushed = p.first;
         if (p.second) { // the original projection is redundant
-            opRef.setOperator(op.getInputs().get(0).getOperator());
+            opRef.setValue(op.getInputs().get(0).getValue());
             smthWasPushed = true;
         }
 
@@ -74,10 +76,10 @@
     }
 
     private static Pair<Boolean, Boolean> pushThroughOp(HashSet<LogicalVariable> toPush,
-            LogicalOperatorReference opRef2, ILogicalOperator initialOp, IOptimizationContext context)
+            Mutable<ILogicalOperator> opRef2, ILogicalOperator initialOp, IOptimizationContext context)
             throws AlgebricksException {
         List<LogicalVariable> initProjectList = new ArrayList<LogicalVariable>(toPush);
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
         do {
             if (op2.getOperatorTag() == LogicalOperatorTag.EMPTYTUPLESOURCE
                     || op2.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE
@@ -96,7 +98,7 @@
             toPush.removeAll(producedVars);
             // we assume pipelineable ops. have only one input
             opRef2 = op2.getInputs().get(0);
-            op2 = (AbstractLogicalOperator) opRef2.getOperator();
+            op2 = (AbstractLogicalOperator) opRef2.getValue();
         } while (true);
 
         LinkedList<LogicalVariable> produced2 = new LinkedList<LogicalVariable>();
@@ -112,8 +114,8 @@
         if (!canCommuteProjection && op2.getOperatorTag() == LogicalOperatorTag.GROUP) {
             boolean gbyChanged = false;
             GroupByOperator gby = (GroupByOperator) op2;
-            List<Pair<LogicalVariable, LogicalExpressionReference>> newDecorList = new ArrayList<Pair<LogicalVariable, LogicalExpressionReference>>();
-            for (Pair<LogicalVariable, LogicalExpressionReference> p : gby.getDecorList()) {
+            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> newDecorList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
+            for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getDecorList()) {
                 LogicalVariable decorVar = GroupByOperator.getDecorVariable(p);
                 if (!toPush.contains(decorVar)) {
                     used2.remove(decorVar);
@@ -139,7 +141,7 @@
         }
 
         boolean smthWasPushed = false;
-        for (LogicalOperatorReference c : op2.getInputs()) {
+        for (Mutable<ILogicalOperator> c : op2.getInputs()) {
             if (pushNeededProjections(toPush, c, context, initialOp)) {
                 smthWasPushed = true;
             }
@@ -147,7 +149,7 @@
         if (op2.hasNestedPlans()) {
             AbstractOperatorWithNestedPlans n = (AbstractOperatorWithNestedPlans) op2;
             for (ILogicalPlan p : n.getNestedPlans()) {
-                for (LogicalOperatorReference r : p.getRoots()) {
+                for (Mutable<ILogicalOperator> r : p.getRoots()) {
                     if (pushNeededProjections(toPush, r, context, initialOp)) {
                         smthWasPushed = true;
                     }
@@ -158,10 +160,10 @@
     }
 
     // It does not try to push above another Projection.
-    private static boolean pushNeededProjections(HashSet<LogicalVariable> toPush, LogicalOperatorReference opRef,
+    private static boolean pushNeededProjections(HashSet<LogicalVariable> toPush, Mutable<ILogicalOperator> opRef,
             IOptimizationContext context, ILogicalOperator initialOp) throws AlgebricksException {
         HashSet<LogicalVariable> allP = new HashSet<LogicalVariable>();
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         VariableUtilities.getLiveVariables(op, allP);
 
         HashSet<LogicalVariable> toProject = new HashSet<LogicalVariable>();
@@ -185,12 +187,12 @@
 
     // It does not try to push above another Projection.
     private static boolean pushAllProjectionsOnTopOf(Collection<LogicalVariable> toPush,
-            LogicalOperatorReference opRef, IOptimizationContext context, ILogicalOperator initialOp)
+            Mutable<ILogicalOperator> opRef, IOptimizationContext context, ILogicalOperator initialOp)
             throws AlgebricksException {
         if (toPush.isEmpty()) {
             return false;
         }
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
 
         if (context.checkAndAddToAlreadyCompared(initialOp, op)) {
             return false;
@@ -198,8 +200,8 @@
 
         switch (op.getOperatorTag()) {
             case EXCHANGE: {
-                opRef = opRef.getOperator().getInputs().get(0);
-                op = (AbstractLogicalOperator) opRef.getOperator();
+                opRef = opRef.getValue().getInputs().get(0);
+                op = (AbstractLogicalOperator) opRef.getValue();
                 break;
             }
             case PROJECT: {
@@ -208,8 +210,8 @@
         }
 
         ProjectOperator pi2 = new ProjectOperator(new ArrayList<LogicalVariable>(toPush));
-        pi2.getInputs().add(new LogicalOperatorReference(op));
-        opRef.setOperator(pi2);
+        pi2.getInputs().add(new MutableObject<ILogicalOperator>(op));
+        opRef.setValue(pi2);
         pi2.setExecutionMode(op.getExecutionMode());
         context.computeAndSetTypeEnvironmentForOperator(pi2);
         return true;
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushProjectIntoDataSourceScanRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushProjectIntoDataSourceScanRule.java
index 6358a7d..4e14f9a 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushProjectIntoDataSourceScanRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushProjectIntoDataSourceScanRule.java
@@ -1,7 +1,9 @@
 package edu.uci.ics.hyracks.algebricks.rewriter.rules;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
@@ -12,22 +14,23 @@
 public class PushProjectIntoDataSourceScanRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getInputs().size() <= 0)
             return false;
-        AbstractLogicalOperator project = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
+        AbstractLogicalOperator project = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
         if (project.getOperatorTag() != LogicalOperatorTag.PROJECT)
             return false;
-        AbstractLogicalOperator exchange = (AbstractLogicalOperator) project.getInputs().get(0).getOperator();
+        AbstractLogicalOperator exchange = (AbstractLogicalOperator) project.getInputs().get(0).getValue();
         if (exchange.getOperatorTag() != LogicalOperatorTag.EXCHANGE)
             return false;
-        AbstractLogicalOperator inputOp = (AbstractLogicalOperator) exchange.getInputs().get(0).getOperator();
+        AbstractLogicalOperator inputOp = (AbstractLogicalOperator) exchange.getInputs().get(0).getValue();
         if (inputOp.getOperatorTag() != LogicalOperatorTag.DATASOURCESCAN)
             return false;
         DataSourceScanOperator scanOp = (DataSourceScanOperator) inputOp;
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSelectDownRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSelectDownRule.java
index 972d257..fedcad9 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSelectDownRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSelectDownRule.java
@@ -17,8 +17,10 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
@@ -31,19 +33,19 @@
 public class PushSelectDownRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.SELECT) {
             return false;
         }
 
-        LogicalOperatorReference opRef2 = op.getInputs().get(0);
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getOperator();
+        Mutable<ILogicalOperator> opRef2 = op.getInputs().get(0);
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
 
         if (context.checkAndAddToAlreadyCompared(op, op2)) {
             return false;
@@ -63,27 +65,27 @@
         }
     }
 
-    private static boolean propagateSelectionRec(LogicalOperatorReference sigmaRef, LogicalOperatorReference opRef2)
+    private static boolean propagateSelectionRec(Mutable<ILogicalOperator> sigmaRef, Mutable<ILogicalOperator> opRef2)
             throws AlgebricksException {
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getOperator();
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
         if (op2.getInputs().size() != 1 || op2.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
             return false;
         }
 
-        SelectOperator sigma = (SelectOperator) sigmaRef.getOperator();
+        SelectOperator sigma = (SelectOperator) sigmaRef.getValue();
         LinkedList<LogicalVariable> usedInSigma = new LinkedList<LogicalVariable>();
-        sigma.getCondition().getExpression().getUsedVariables(usedInSigma);
+        sigma.getCondition().getValue().getUsedVariables(usedInSigma);
 
         LinkedList<LogicalVariable> produced2 = new LinkedList<LogicalVariable>();
         VariableUtilities.getProducedVariables(op2, produced2);
         if (OperatorPropertiesUtil.disjoint(produced2, usedInSigma)) {
             // just swap
-            opRef2.setOperator(sigma);
-            sigmaRef.setOperator(op2);
-            List<LogicalOperatorReference> sigmaInpList = sigma.getInputs();
+            opRef2.setValue(sigma);
+            sigmaRef.setValue(op2);
+            List<Mutable<ILogicalOperator>> sigmaInpList = sigma.getInputs();
             sigmaInpList.clear();
             sigmaInpList.addAll(op2.getInputs());
-            List<LogicalOperatorReference> op2InpList = op2.getInputs();
+            List<Mutable<ILogicalOperator>> op2InpList = op2.getInputs();
             op2InpList.clear();
             op2InpList.add(opRef2);
             propagateSelectionRec(opRef2, sigma.getInputs().get(0));
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSelectIntoJoinRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSelectIntoJoinRule.java
index eea4978..315abdb 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSelectIntoJoinRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSelectIntoJoinRule.java
@@ -22,12 +22,13 @@
 import java.util.List;
 import java.util.ListIterator;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
@@ -44,12 +45,13 @@
 public class PushSelectIntoJoinRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
         Collection<LogicalVariable> joinLiveVarsLeft = new HashSet<LogicalVariable>();
         Collection<LogicalVariable> joinLiveVarsRight = new HashSet<LogicalVariable>();
         Collection<LogicalVariable> liveInOpsToPushLeft = new HashSet<LogicalVariable>();
@@ -61,19 +63,19 @@
         Collection<LogicalVariable> usedVars = new HashSet<LogicalVariable>();
         Collection<LogicalVariable> producedVars = new HashSet<LogicalVariable>();
 
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.SELECT) {
             return false;
         }
         SelectOperator select = (SelectOperator) op;
-        LogicalOperatorReference opRef2 = op.getInputs().get(0);
-        AbstractLogicalOperator son = (AbstractLogicalOperator) opRef2.getOperator();
+        Mutable<ILogicalOperator> opRef2 = op.getInputs().get(0);
+        AbstractLogicalOperator son = (AbstractLogicalOperator) opRef2.getValue();
         AbstractLogicalOperator op2 = son;
         boolean needToPushOps = false;
         while (son.isMap()) {
             needToPushOps = true;
-            LogicalOperatorReference opRefLink = son.getInputs().get(0);
-            son = (AbstractLogicalOperator) opRefLink.getOperator();
+            Mutable<ILogicalOperator> opRefLink = son.getInputs().get(0);
+            son = (AbstractLogicalOperator) opRefLink.getValue();
         }
 
         if (son.getOperatorTag() != LogicalOperatorTag.INNERJOIN
@@ -83,15 +85,15 @@
         boolean isLoj = son.getOperatorTag() == LogicalOperatorTag.LEFTOUTERJOIN;
         AbstractBinaryJoinOperator join = (AbstractBinaryJoinOperator) son;
 
-        LogicalOperatorReference joinBranchLeftRef = join.getInputs().get(0);
-        LogicalOperatorReference joinBranchRightRef = join.getInputs().get(1);
+        Mutable<ILogicalOperator> joinBranchLeftRef = join.getInputs().get(0);
+        Mutable<ILogicalOperator> joinBranchRightRef = join.getInputs().get(1);
 
         if (needToPushOps) {
-            ILogicalOperator joinBranchLeft = joinBranchLeftRef.getOperator();
-            ILogicalOperator joinBranchRight = joinBranchRightRef.getOperator();
+            ILogicalOperator joinBranchLeft = joinBranchLeftRef.getValue();
+            ILogicalOperator joinBranchRight = joinBranchRightRef.getValue();
             VariableUtilities.getLiveVariables(joinBranchLeft, joinLiveVarsLeft);
             VariableUtilities.getLiveVariables(joinBranchRight, joinLiveVarsRight);
-            LogicalOperatorReference opIterRef = opRef2;
+            Mutable<ILogicalOperator> opIterRef = opRef2;
             ILogicalOperator opIter = op2;
             while (opIter != join) {
                 LogicalOperatorTag tag = ((AbstractLogicalOperator) opIter).getOperatorTag();
@@ -111,7 +113,7 @@
                     }
                 }
                 opIterRef = opIter.getInputs().get(0);
-                opIter = opIterRef.getOperator();
+                opIter = opIterRef.getValue();
             }
             if (isLoj && pushedOnLeft.isEmpty()) {
                 return false;
@@ -121,11 +123,11 @@
         boolean intersectsAllBranches = true;
         boolean[] intersectsBranch = new boolean[join.getInputs().size()];
         LinkedList<LogicalVariable> selectVars = new LinkedList<LogicalVariable>();
-        select.getCondition().getExpression().getUsedVariables(selectVars);
+        select.getCondition().getValue().getUsedVariables(selectVars);
         int i = 0;
-        for (LogicalOperatorReference branch : join.getInputs()) {
+        for (Mutable<ILogicalOperator> branch : join.getInputs()) {
             LinkedList<LogicalVariable> branchVars = new LinkedList<LogicalVariable>();
-            VariableUtilities.getLiveVariables(branch.getOperator(), branchVars);
+            VariableUtilities.getLiveVariables(branch.getValue(), branchVars);
             if (i == 0) {
                 branchVars.addAll(liveInOpsToPushLeft);
             } else {
@@ -148,10 +150,10 @@
             }
             addCondToJoin(select, join);
         } else { // push down
-            Iterator<LogicalOperatorReference> branchIter = join.getInputs().iterator();
+            Iterator<Mutable<ILogicalOperator>> branchIter = join.getInputs().iterator();
 
             for (int j = 0; j < intersectsBranch.length; j++) {
-                LogicalOperatorReference branch = branchIter.next();
+                Mutable<ILogicalOperator> branch = branchIter.next();
                 boolean inter = intersectsBranch[j];
                 if (inter) {
                     if (needToPushOps) {
@@ -174,36 +176,36 @@
         }
         ILogicalOperator top = join;
         for (ILogicalOperator npOp : notPushedStack) {
-            List<LogicalOperatorReference> npInpList = npOp.getInputs();
+            List<Mutable<ILogicalOperator>> npInpList = npOp.getInputs();
             npInpList.clear();
-            npInpList.add(new LogicalOperatorReference(top));
+            npInpList.add(new MutableObject<ILogicalOperator>(top));
             context.computeAndSetTypeEnvironmentForOperator(npOp);
             top = npOp;
         }
-        opRef.setOperator(top);
+        opRef.setValue(top);
         return true;
 
     }
 
-    private void pushOps(List<ILogicalOperator> opList, LogicalOperatorReference joinBranch,
+    private void pushOps(List<ILogicalOperator> opList, Mutable<ILogicalOperator> joinBranch,
             IOptimizationContext context) throws AlgebricksException {
-        ILogicalOperator topOp = joinBranch.getOperator();
+        ILogicalOperator topOp = joinBranch.getValue();
         ListIterator<ILogicalOperator> iter = opList.listIterator(opList.size());
         while (iter.hasPrevious()) {
             ILogicalOperator op = iter.previous();
-            List<LogicalOperatorReference> opInpList = op.getInputs();
+            List<Mutable<ILogicalOperator>> opInpList = op.getInputs();
             opInpList.clear();
-            opInpList.add(new LogicalOperatorReference(topOp));
+            opInpList.add(new MutableObject<ILogicalOperator>(topOp));
             topOp = op;
             context.computeAndSetTypeEnvironmentForOperator(op);
         }
-        joinBranch.setOperator(topOp);
+        joinBranch.setValue(topOp);
     }
 
     private static void addCondToJoin(SelectOperator select, AbstractBinaryJoinOperator join) {
-        ILogicalExpression cond = join.getCondition().getExpression();
+        ILogicalExpression cond = join.getCondition().getValue();
         if (OperatorPropertiesUtil.isAlwaysTrueCond(cond)) { // the join was a product
-            join.getCondition().setExpression(select.getCondition().getExpression());
+            join.getCondition().setValue(select.getCondition().getValue());
         } else {
             boolean bAddedToConj = false;
             if (cond.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
@@ -213,25 +215,25 @@
                             AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.AND));
                     newCond.getArguments().add(select.getCondition());
                     newCond.getArguments().addAll(fcond.getArguments());
-                    join.getCondition().setExpression(newCond);
+                    join.getCondition().setValue(newCond);
                     bAddedToConj = true;
                 }
             }
             if (!bAddedToConj) {
-                AbstractFunctionCallExpression newCond = new ScalarFunctionCallExpression(AlgebricksBuiltinFunctions
-                        .getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.AND), select.getCondition(),
-                        new LogicalExpressionReference(join.getCondition().getExpression()));
-                join.getCondition().setExpression(newCond);
+                AbstractFunctionCallExpression newCond = new ScalarFunctionCallExpression(
+                        AlgebricksBuiltinFunctions.getBuiltinFunctionInfo(AlgebricksBuiltinFunctions.AND),
+                        select.getCondition(), new MutableObject<ILogicalExpression>(join.getCondition().getValue()));
+                join.getCondition().setValue(newCond);
             }
         }
     }
 
-    private static void copySelectToBranch(SelectOperator select, LogicalOperatorReference branch,
+    private static void copySelectToBranch(SelectOperator select, Mutable<ILogicalOperator> branch,
             IOptimizationContext context) throws AlgebricksException {
         ILogicalOperator newSelect = new SelectOperator(select.getCondition());
-        LogicalOperatorReference newRef = new LogicalOperatorReference(branch.getOperator());
+        Mutable<ILogicalOperator> newRef = new MutableObject<ILogicalOperator>(branch.getValue());
         newSelect.getInputs().add(newRef);
-        branch.setOperator(newSelect);
+        branch.setValue(newSelect);
         context.computeAndSetTypeEnvironmentForOperator(newSelect);
     }
 }
\ No newline at end of file
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSubplanWithAggregateDownThroughProductRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSubplanWithAggregateDownThroughProductRule.java
index 32ff5c5..25855e5 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSubplanWithAggregateDownThroughProductRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/PushSubplanWithAggregateDownThroughProductRule.java
@@ -19,10 +19,11 @@
 import java.util.List;
 import java.util.Set;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
@@ -36,13 +37,14 @@
 public class PushSubplanWithAggregateDownThroughProductRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
         if (op1.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
             return false;
         }
@@ -54,44 +56,44 @@
         if (p.getRoots().size() != 1) {
             return false;
         }
-        LogicalOperatorReference r = p.getRoots().get(0);
-        if (((AbstractLogicalOperator) r.getOperator()).getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
+        Mutable<ILogicalOperator> r = p.getRoots().get(0);
+        if (((AbstractLogicalOperator) r.getValue()).getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
             return false;
         }
 
         Set<LogicalVariable> free = new HashSet<LogicalVariable>();
         OperatorPropertiesUtil.getFreeVariablesInSubplans(subplan, free);
 
-        LogicalOperatorReference op2Ref = op1.getInputs().get(0);
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op2Ref.getOperator();
+        Mutable<ILogicalOperator> op2Ref = op1.getInputs().get(0);
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) op2Ref.getValue();
         if (op2.getOperatorTag() != LogicalOperatorTag.INNERJOIN) {
             return false;
         }
         AbstractBinaryJoinOperator join = (AbstractBinaryJoinOperator) op2;
-        if (!OperatorPropertiesUtil.isAlwaysTrueCond(join.getCondition().getExpression())) {
+        if (!OperatorPropertiesUtil.isAlwaysTrueCond(join.getCondition().getValue())) {
             return false;
         }
 
-        LogicalOperatorReference b0Ref = op2.getInputs().get(0);
-        ILogicalOperator b0 = b0Ref.getOperator();
+        Mutable<ILogicalOperator> b0Ref = op2.getInputs().get(0);
+        ILogicalOperator b0 = b0Ref.getValue();
         List<LogicalVariable> b0Scm = new ArrayList<LogicalVariable>();
         VariableUtilities.getLiveVariables(b0, b0Scm);
         if (b0Scm.containsAll(free)) {
             // push subplan on left branch
-            op2Ref.setOperator(b0);
-            b0Ref.setOperator(op1);
-            opRef.setOperator(op2);
+            op2Ref.setValue(b0);
+            b0Ref.setValue(op1);
+            opRef.setValue(op2);
             return true;
         } else {
-            LogicalOperatorReference b1Ref = op2.getInputs().get(1);
-            ILogicalOperator b1 = b1Ref.getOperator();
+            Mutable<ILogicalOperator> b1Ref = op2.getInputs().get(1);
+            ILogicalOperator b1 = b1Ref.getValue();
             List<LogicalVariable> b1Scm = new ArrayList<LogicalVariable>();
             VariableUtilities.getLiveVariables(b1, b1Scm);
             if (b1Scm.containsAll(free)) {
                 // push subplan on right branch
-                op2Ref.setOperator(b1);
-                b1Ref.setOperator(op1);
-                opRef.setOperator(op2);
+                op2Ref.setValue(b1);
+                b1Ref.setValue(op1);
+                opRef.setValue(op2);
                 return true;
             } else {
                 return false;
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ReinferAllTypesRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ReinferAllTypesRule.java
index 55e83ae..f06a2ac 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ReinferAllTypesRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/ReinferAllTypesRule.java
@@ -1,8 +1,10 @@
 package edu.uci.ics.hyracks.algebricks.rewriter.rules;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
@@ -11,13 +13,14 @@
 public class ReinferAllTypesRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        if (context.checkIfInDontApplySet(this, opRef.getOperator())) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        if (context.checkIfInDontApplySet(this, opRef.getValue())) {
             return false;
         }
         typeOpRec(opRef, context);
@@ -25,14 +28,14 @@
     }
 
     private void typePlan(ILogicalPlan p, IOptimizationContext context) throws AlgebricksException {
-        for (LogicalOperatorReference r : p.getRoots()) {
+        for (Mutable<ILogicalOperator> r : p.getRoots()) {
             typeOpRec(r, context);
         }
     }
 
-    private void typeOpRec(LogicalOperatorReference r, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) r.getOperator();
-        for (LogicalOperatorReference i : op.getInputs()) {
+    private void typeOpRec(Mutable<ILogicalOperator> r, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) r.getValue();
+        for (Mutable<ILogicalOperator> i : op.getInputs()) {
             typeOpRec(i, context);
         }
         if (op.hasNestedPlans()) {
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/RemoveRedundantProjectionRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/RemoveRedundantProjectionRule.java
index e11def8..cdc6086 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/RemoveRedundantProjectionRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/RemoveRedundantProjectionRule.java
@@ -17,8 +17,10 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
@@ -42,33 +44,33 @@
 public class RemoveRedundantProjectionRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
         if (op1.getOperatorTag() == LogicalOperatorTag.PROJECT) {
-            LogicalOperatorReference opRef2 = op1.getInputs().get(0);
-            AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getOperator();
+            Mutable<ILogicalOperator> opRef2 = op1.getInputs().get(0);
+            AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
             if (op2.getOperatorTag() != LogicalOperatorTag.PROJECT) {
                 return false;
             }
             ProjectOperator pi2 = (ProjectOperator) op2;
-            opRef2.setOperator(pi2.getInputs().get(0).getOperator());
+            opRef2.setValue(pi2.getInputs().get(0).getValue());
         } else {
             if (op1.getInputs().size() <= 0)
                 return false;
-            LogicalOperatorReference opRef2 = op1.getInputs().get(0);
-            AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getOperator();
+            Mutable<ILogicalOperator> opRef2 = op1.getInputs().get(0);
+            AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
             if (op2.getOperatorTag() != LogicalOperatorTag.PROJECT) {
                 return false;
             }
             if (op2.getInputs().size() <= 0)
                 return false;
-            LogicalOperatorReference opRef3 = op2.getInputs().get(0);
-            AbstractLogicalOperator op3 = (AbstractLogicalOperator) opRef3.getOperator();
+            Mutable<ILogicalOperator> opRef3 = op2.getInputs().get(0);
+            AbstractLogicalOperator op3 = (AbstractLogicalOperator) opRef3.getValue();
 
             List<LogicalVariable> liveVars2 = new ArrayList<LogicalVariable>();
             List<LogicalVariable> liveVars3 = new ArrayList<LogicalVariable>();
@@ -78,7 +80,7 @@
 
             if (!VariableUtilities.varListEqualUnordered(liveVars2, liveVars3))
                 return false;
-            opRef2.setOperator(op3);
+            opRef2.setValue(op3);
         }
 
         return true;
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/RemoveUnusedAssignAndAggregateRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/RemoveUnusedAssignAndAggregateRule.java
index 6d6bc70..ff1a102 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/RemoveUnusedAssignAndAggregateRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/RemoveUnusedAssignAndAggregateRule.java
@@ -20,10 +20,12 @@
 import java.util.List;
 import java.util.Set;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
@@ -37,17 +39,17 @@
 public class RemoveUnusedAssignAndAggregateRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        if (context.checkIfInDontApplySet(this, opRef.getOperator())) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        if (context.checkIfInDontApplySet(this, opRef.getValue())) {
             return false;
         }
         Set<LogicalVariable> toRemove = new HashSet<LogicalVariable>();
-        collectUnusedAssignedVars((AbstractLogicalOperator) opRef.getOperator(), toRemove, true, context);
+        collectUnusedAssignedVars((AbstractLogicalOperator) opRef.getValue(), toRemove, true, context);
         boolean smthToRemove = !toRemove.isEmpty();
         if (smthToRemove) {
             removeUnusedAssigns(opRef, toRemove, context);
@@ -55,19 +57,19 @@
         return smthToRemove;
     }
 
-    private void removeUnusedAssigns(LogicalOperatorReference opRef, Set<LogicalVariable> toRemove,
+    private void removeUnusedAssigns(Mutable<ILogicalOperator> opRef, Set<LogicalVariable> toRemove,
             IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         while (removeFromAssigns(op, toRemove, context) == 0) {
             if (op.getOperatorTag() == LogicalOperatorTag.AGGREGATE) {
                 break;
             }
-            op = (AbstractLogicalOperator) op.getInputs().get(0).getOperator();
-            opRef.setOperator(op);
+            op = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
+            opRef.setValue(op);
         }
-        Iterator<LogicalOperatorReference> childIter = op.getInputs().iterator();
+        Iterator<Mutable<ILogicalOperator>> childIter = op.getInputs().iterator();
         while (childIter.hasNext()) {
-            LogicalOperatorReference cRef = childIter.next();
+            Mutable<ILogicalOperator> cRef = childIter.next();
             removeUnusedAssigns(cRef, toRemove, context);
         }
         if (op.hasNestedPlans()) {
@@ -75,7 +77,7 @@
             Iterator<ILogicalPlan> planIter = opWithNest.getNestedPlans().iterator();
             while (planIter.hasNext()) {
                 ILogicalPlan p = planIter.next();
-                for (LogicalOperatorReference r : p.getRoots()) {
+                for (Mutable<ILogicalOperator> r : p.getRoots()) {
                     removeUnusedAssigns(r, toRemove, context);
                 }
             }
@@ -101,10 +103,10 @@
     }
 
     private boolean removeUnusedVarsAndExprs(Set<LogicalVariable> toRemove, List<LogicalVariable> varList,
-            List<LogicalExpressionReference> exprList) {
+            List<Mutable<ILogicalExpression>> exprList) {
         boolean changed = false;
         Iterator<LogicalVariable> varIter = varList.iterator();
-        Iterator<LogicalExpressionReference> exprIter = exprList.iterator();
+        Iterator<Mutable<ILogicalExpression>> exprIter = exprList.iterator();
         while (varIter.hasNext()) {
             LogicalVariable v = varIter.next();
             exprIter.next();
@@ -122,14 +124,14 @@
         if (!first) {
             context.addToDontApplySet(this, op);
         }
-        for (LogicalOperatorReference c : op.getInputs()) {
-            collectUnusedAssignedVars((AbstractLogicalOperator) c.getOperator(), toRemove, false, context);
+        for (Mutable<ILogicalOperator> c : op.getInputs()) {
+            collectUnusedAssignedVars((AbstractLogicalOperator) c.getValue(), toRemove, false, context);
         }
         if (op.hasNestedPlans()) {
             AbstractOperatorWithNestedPlans opWithNested = (AbstractOperatorWithNestedPlans) op;
             for (ILogicalPlan plan : opWithNested.getNestedPlans()) {
-                for (LogicalOperatorReference r : plan.getRoots()) {
-                    collectUnusedAssignedVars((AbstractLogicalOperator) r.getOperator(), toRemove, false, context);
+                for (Mutable<ILogicalOperator> r : plan.getRoots()) {
+                    collectUnusedAssignedVars((AbstractLogicalOperator) r.getValue(), toRemove, false, context);
                 }
             }
         }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SetAlgebricksPhysicalOperatorsRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SetAlgebricksPhysicalOperatorsRule.java
index 23d607f..f1f3533 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SetAlgebricksPhysicalOperatorsRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SetAlgebricksPhysicalOperatorsRule.java
@@ -3,12 +3,14 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.OperatorAnnotations;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IMergeAggregationExpressionFactory;
@@ -16,6 +18,7 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IDataSource;
 import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
@@ -27,9 +30,8 @@
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteResultOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteResultOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.AggregatePOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.AssignPOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.DataSourceScanPOperator;
@@ -66,13 +68,14 @@
 public class SetAlgebricksPhysicalOperatorsRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         // if (context.checkIfInDontApplySet(this, op)) {
         // return false;
         // }
@@ -87,8 +90,8 @@
 
     private static void setPhysicalOperators(ILogicalPlan plan, boolean topLevelOp, IOptimizationContext context)
             throws AlgebricksException {
-        for (LogicalOperatorReference root : plan.getRoots()) {
-            computeDefaultPhysicalOp((AbstractLogicalOperator) root.getOperator(), topLevelOp, context);
+        for (Mutable<ILogicalOperator> root : plan.getRoots()) {
+            computeDefaultPhysicalOp((AbstractLogicalOperator) root.getValue(), topLevelOp, context);
         }
     }
 
@@ -144,10 +147,10 @@
                         }
                     }
 
-                    List<Pair<LogicalVariable, LogicalExpressionReference>> gbyList = gby.getGroupByList();
+                    List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> gbyList = gby.getGroupByList();
                     List<LogicalVariable> columnList = new ArrayList<LogicalVariable>(gbyList.size());
-                    for (Pair<LogicalVariable, LogicalExpressionReference> p : gbyList) {
-                        ILogicalExpression expr = p.second.getExpression();
+                    for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gbyList) {
+                        ILogicalExpression expr = p.second.getValue();
                         if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                             VariableReferenceExpression varRef = (VariableReferenceExpression) expr;
                             columnList.add(varRef.getVariableReference());
@@ -180,8 +183,8 @@
                 }
                 case ORDER: {
                     OrderOperator oo = (OrderOperator) op;
-                    for (Pair<IOrder, LogicalExpressionReference> p : oo.getOrderExpressions()) {
-                        ILogicalExpression e = p.second.getExpression();
+                    for (Pair<IOrder, Mutable<ILogicalExpression>> p : oo.getOrderExpressions()) {
+                        ILogicalExpression e = p.second.getValue();
                         if (e.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                             throw new AlgebricksException("Order expression " + e + " has not been normalized.");
                         }
@@ -284,14 +287,14 @@
                 setPhysicalOperators(p, false, context);
             }
         }
-        for (LogicalOperatorReference opRef : op.getInputs()) {
-            computeDefaultPhysicalOp((AbstractLogicalOperator) opRef.getOperator(), topLevelOp, context);
+        for (Mutable<ILogicalOperator> opRef : op.getInputs()) {
+            computeDefaultPhysicalOp((AbstractLogicalOperator) opRef.getValue(), topLevelOp, context);
         }
     }
 
-    private static void getKeys(List<LogicalExpressionReference> keyExpressions, List<LogicalVariable> keys) {
-        for (LogicalExpressionReference kExpr : keyExpressions) {
-            ILogicalExpression e = kExpr.getExpression();
+    private static void getKeys(List<Mutable<ILogicalExpression>> keyExpressions, List<LogicalVariable> keys) {
+        for (Mutable<ILogicalExpression> kExpr : keyExpressions) {
+            ILogicalExpression e = kExpr.getValue();
             if (e.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                 throw new NotImplementedException();
             }
@@ -299,16 +302,16 @@
         }
     }
 
-    private static LogicalVariable getKeysAndLoad(LogicalExpressionReference payloadExpr,
-            List<LogicalExpressionReference> keyExpressions, List<LogicalVariable> keys) {
+    private static LogicalVariable getKeysAndLoad(Mutable<ILogicalExpression> payloadExpr,
+            List<Mutable<ILogicalExpression>> keyExpressions, List<LogicalVariable> keys) {
         LogicalVariable payload;
-        if (payloadExpr.getExpression().getExpressionTag() != LogicalExpressionTag.VARIABLE) {
+        if (payloadExpr.getValue().getExpressionTag() != LogicalExpressionTag.VARIABLE) {
             throw new NotImplementedException();
         }
-        payload = ((VariableReferenceExpression) payloadExpr.getExpression()).getVariableReference();
+        payload = ((VariableReferenceExpression) payloadExpr.getValue()).getVariableReference();
 
-        for (LogicalExpressionReference kExpr : keyExpressions) {
-            ILogicalExpression e = kExpr.getExpression();
+        for (Mutable<ILogicalExpression> kExpr : keyExpressions) {
+            ILogicalExpression e = kExpr.getValue();
             if (e.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                 throw new NotImplementedException();
             }
@@ -332,15 +335,15 @@
         }
         IMergeAggregationExpressionFactory mergeAggregationExpressionFactory = context
                 .getMergeAggregationExpressionFactory();
-        LogicalOperatorReference r0 = p0.getRoots().get(0);
-        AggregateOperator aggOp = (AggregateOperator) r0.getOperator();
-        List<LogicalExpressionReference> aggFuncRefs = aggOp.getExpressions();
+        Mutable<ILogicalOperator> r0 = p0.getRoots().get(0);
+        AggregateOperator aggOp = (AggregateOperator) r0.getValue();
+        List<Mutable<ILogicalExpression>> aggFuncRefs = aggOp.getExpressions();
         int n = aggOp.getExpressions().size();
-        List<LogicalExpressionReference> mergeExpressionRefs = new ArrayList<LogicalExpressionReference>();
+        List<Mutable<ILogicalExpression>> mergeExpressionRefs = new ArrayList<Mutable<ILogicalExpression>>();
         for (int i = 0; i < n; i++) {
             ILogicalExpression mergeExpr = mergeAggregationExpressionFactory.createMergeAggregation(aggFuncRefs.get(i)
-                    .getExpression(), context);
-            mergeExpressionRefs.add(new LogicalExpressionReference(mergeExpr));
+                    .getValue(), context);
+            mergeExpressionRefs.add(new MutableObject<ILogicalExpression>(mergeExpr));
         }
         aggOp.setMergeExpressions(mergeExpressionRefs);
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SetExecutionModeRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SetExecutionModeRule.java
index 5ecd14e..bdd56b6 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SetExecutionModeRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SetExecutionModeRule.java
@@ -14,8 +14,10 @@
  */
 package edu.uci.ics.hyracks.algebricks.rewriter.rules;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.NotImplementedException;
@@ -35,23 +37,23 @@
 public class SetExecutionModeRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         boolean changed = OperatorManipulationUtil.setOperatorMode(op);
         if (op.getExecutionMode() == AbstractLogicalOperator.ExecutionMode.UNPARTITIONED
                 || op.getExecutionMode() == AbstractLogicalOperator.ExecutionMode.LOCAL) {
             return changed;
         }
         switch (op.getOperatorTag()) {
-            // case DISTINCT:
-            // case AGGREGATE:
-            // case GROUP:
-            // case ORDER:
-            // case INNERJOIN:
-            // case LEFTOUTERJOIN: {
-            // op.setExecutionMode(ExecutionMode.GLOBAL);
-            // return true;
-            // }
+        // case DISTINCT:
+        // case AGGREGATE:
+        // case GROUP:
+        // case ORDER:
+        // case INNERJOIN:
+        // case LEFTOUTERJOIN: {
+        // op.setExecutionMode(ExecutionMode.GLOBAL);
+        // return true;
+        // }
 
             case PARTITIONINGSPLIT: {
                 throw new NotImplementedException();
@@ -64,7 +66,7 @@
     }
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SimpleUnnestToProductRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SimpleUnnestToProductRule.java
index 25f21a9..fb7a49f 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SimpleUnnestToProductRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SimpleUnnestToProductRule.java
@@ -16,9 +16,12 @@
 
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
@@ -31,34 +34,36 @@
 public class SimpleUnnestToProductRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         if (op.getOperatorTag() != LogicalOperatorTag.DATASOURCESCAN) {
             return false;
         }
 
-        LogicalOperatorReference opRef2 = op.getInputs().get(0);
-        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getOperator();
+        Mutable<ILogicalOperator> opRef2 = op.getInputs().get(0);
+        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
 
         if (!(op2 instanceof AbstractScanOperator) && !descOrSelfIsSourceScan(op2)) {
             return false;
         }
-        InnerJoinOperator product = new InnerJoinOperator(new LogicalExpressionReference(ConstantExpression.TRUE));
+        InnerJoinOperator product = new InnerJoinOperator(
+                new MutableObject<ILogicalExpression>(ConstantExpression.TRUE));
 
         EmptyTupleSourceOperator ets = new EmptyTupleSourceOperator();
         context.computeAndSetTypeEnvironmentForOperator(ets);
-        LogicalOperatorReference emptySrc = new LogicalOperatorReference(ets);
-        List<LogicalOperatorReference> opInpList = op.getInputs();
+        Mutable<ILogicalOperator> emptySrc = new MutableObject<ILogicalOperator>(ets);
+        List<Mutable<ILogicalOperator>> opInpList = op.getInputs();
         opInpList.clear();
         opInpList.add(emptySrc);
         product.getInputs().add(opRef2); // outer branch
-        product.getInputs().add(new LogicalOperatorReference(op));
-        opRef.setOperator(product); // plug the product in the plan
+        product.getInputs().add(new MutableObject<ILogicalOperator>(op));
+        opRef.setValue(product); // plug the product in the plan
         context.computeAndSetTypeEnvironmentForOperator(product);
         return true;
     }
@@ -67,8 +72,8 @@
         if (op2.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
             return true;
         }
-        for (LogicalOperatorReference cRef : op2.getInputs()) {
-            AbstractLogicalOperator alo = (AbstractLogicalOperator) cRef.getOperator();
+        for (Mutable<ILogicalOperator> cRef : op2.getInputs()) {
+            AbstractLogicalOperator alo = (AbstractLogicalOperator) cRef.getValue();
             if (descOrSelfIsSourceScan(alo)) {
                 return true;
             }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SubplanOutOfGroupRule.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SubplanOutOfGroupRule.java
index bc86d53..7c31fb9 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SubplanOutOfGroupRule.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/SubplanOutOfGroupRule.java
@@ -18,10 +18,12 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
@@ -54,13 +56,14 @@
 public class SubplanOutOfGroupRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePre(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
+    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
         return false;
     }
 
     @Override
-    public boolean rewritePost(LogicalOperatorReference opRef, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator op0 = (AbstractLogicalOperator) opRef.getOperator();
+    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+            throws AlgebricksException {
+        AbstractLogicalOperator op0 = (AbstractLogicalOperator) opRef.getValue();
         if (op0.getOperatorTag() != LogicalOperatorTag.GROUP) {
             return false;
         }
@@ -77,18 +80,18 @@
         if (p.getRoots().size() != 1) {
             return false;
         }
-        LogicalOperatorReference op1Ref = p.getRoots().get(0);
-        AbstractLogicalOperator op1 = (AbstractLogicalOperator) op1Ref.getOperator();
+        Mutable<ILogicalOperator> op1Ref = p.getRoots().get(0);
+        AbstractLogicalOperator op1 = (AbstractLogicalOperator) op1Ref.getValue();
         boolean found = false;
         while (op1.getInputs().size() == 1) {
             if (op1.getOperatorTag() == LogicalOperatorTag.SUBPLAN) {
                 SubplanOperator subplan = (SubplanOperator) op1;
-                AbstractLogicalOperator op2 = (AbstractLogicalOperator) subplan.getInputs().get(0).getOperator();
+                AbstractLogicalOperator op2 = (AbstractLogicalOperator) subplan.getInputs().get(0).getValue();
                 if (OperatorPropertiesUtil.isNullTest(op2)) {
                     if (subplan.getNestedPlans().size() == 1) {
                         ILogicalPlan p1 = subplan.getNestedPlans().get(0);
                         if (p1.getRoots().size() == 1) {
-                            AbstractLogicalOperator r1 = (AbstractLogicalOperator) p1.getRoots().get(0).getOperator();
+                            AbstractLogicalOperator r1 = (AbstractLogicalOperator) p1.getRoots().get(0).getValue();
                             if (r1.getOperatorTag() == LogicalOperatorTag.INNERJOIN
                                     || r1.getOperatorTag() == LogicalOperatorTag.LEFTOUTERJOIN) {
                                 // now, check that it propagates all variables,
@@ -107,20 +110,20 @@
                 }
             }
             op1Ref = op1.getInputs().get(0);
-            op1 = (AbstractLogicalOperator) op1Ref.getOperator();
+            op1 = (AbstractLogicalOperator) op1Ref.getValue();
         }
         if (!found) {
             return false;
         }
 
         ILogicalOperator subplan = op1;
-        ILogicalOperator op2 = op1.getInputs().get(0).getOperator();
-        op1Ref.setOperator(op2);
-        LogicalOperatorReference opUnderRef = gby.getInputs().get(0);
-        ILogicalOperator opUnder = opUnderRef.getOperator();
+        ILogicalOperator op2 = op1.getInputs().get(0).getValue();
+        op1Ref.setValue(op2);
+        Mutable<ILogicalOperator> opUnderRef = gby.getInputs().get(0);
+        ILogicalOperator opUnder = opUnderRef.getValue();
         subplan.getInputs().clear();
-        subplan.getInputs().add(new LogicalOperatorReference(opUnder));
-        opUnderRef.setOperator(subplan);
+        subplan.getInputs().add(new MutableObject<ILogicalOperator>(opUnder));
+        opUnderRef.setValue(subplan);
 
         return true;
     }
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/util/JoinUtils.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/util/JoinUtils.java
index 711e859..1714a24 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/util/JoinUtils.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/util/JoinUtils.java
@@ -19,27 +19,27 @@
 import java.util.LinkedList;
 import java.util.List;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation.BroadcastSide;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
 import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
-import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation.BroadcastSide;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import edu.uci.ics.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions.ComparisonKind;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.LogicalPropertiesVisitor;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.AbstractJoinPOperator.JoinPartitioningType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.HybridHashJoinPOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.InMemoryHashJoinPOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.NLJoinPOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.AbstractJoinPOperator.JoinPartitioningType;
 import edu.uci.ics.hyracks.algebricks.core.algebra.properties.ILogicalPropertiesVector;
 import edu.uci.ics.hyracks.algebricks.core.api.exceptions.AlgebricksException;
 import edu.uci.ics.hyracks.algebricks.core.config.AlgebricksConfig;
@@ -58,10 +58,10 @@
             throws AlgebricksException {
         List<LogicalVariable> sideLeft = new LinkedList<LogicalVariable>();
         List<LogicalVariable> sideRight = new LinkedList<LogicalVariable>();
-        List<LogicalVariable> varsLeft = op.getInputs().get(0).getOperator().getSchema();
-        List<LogicalVariable> varsRight = op.getInputs().get(1).getOperator().getSchema();
-        if (isHashJoinCondition(op.getCondition().getExpression(), varsLeft, varsRight, sideLeft, sideRight)) {
-            BroadcastSide side = getBroadcastJoinSide(op.getCondition().getExpression(), varsLeft, varsRight);
+        List<LogicalVariable> varsLeft = op.getInputs().get(0).getValue().getSchema();
+        List<LogicalVariable> varsRight = op.getInputs().get(1).getValue().getSchema();
+        if (isHashJoinCondition(op.getCondition().getValue(), varsLeft, varsRight, sideLeft, sideRight)) {
+            BroadcastSide side = getBroadcastJoinSide(op.getCondition().getValue(), varsLeft, varsRight);
             if (side == null) {
                 setHashJoinOp(op, JoinPartitioningType.PAIRWISE, sideLeft, sideRight, context);
             } else {
@@ -70,11 +70,11 @@
                         setHashJoinOp(op, JoinPartitioningType.BROADCAST, sideLeft, sideRight, context);
                         break;
                     case LEFT:
-                        LogicalOperatorReference opRef0 = op.getInputs().get(0);
-                        LogicalOperatorReference opRef1 = op.getInputs().get(1);
-                        ILogicalOperator tmp = opRef0.getOperator();
-                        opRef0.setOperator(opRef1.getOperator());
-                        opRef1.setOperator(tmp);
+                        Mutable<ILogicalOperator> opRef0 = op.getInputs().get(0);
+                        Mutable<ILogicalOperator> opRef1 = op.getInputs().get(1);
+                        ILogicalOperator tmp = opRef0.getValue();
+                        opRef0.setValue(opRef1.getValue());
+                        opRef1.setValue(tmp);
                         setHashJoinOp(op, JoinPartitioningType.BROADCAST, sideRight, sideLeft, context);
                         break;
                     default:
@@ -108,7 +108,7 @@
 
     private static void hybridToInMemHashJoin(AbstractBinaryJoinOperator op, IOptimizationContext context)
             throws AlgebricksException {
-        ILogicalOperator opBuild = op.getInputs().get(1).getOperator();
+        ILogicalOperator opBuild = op.getInputs().get(1).getValue();
         LogicalPropertiesVisitor.computeLogicalPropertiesDFS(opBuild, context);
         ILogicalPropertiesVector v = context.getLogicalPropertiesVector(opBuild);
         AlgebricksConfig.ALGEBRICKS_LOGGER.fine("// HybridHashJoin inner branch -- Logical properties for " + opBuild
@@ -135,8 +135,8 @@
                 AbstractFunctionCallExpression fexp = (AbstractFunctionCallExpression) e;
                 FunctionIdentifier fi = fexp.getFunctionIdentifier();
                 if (fi == AlgebricksBuiltinFunctions.AND) {
-                    for (LogicalExpressionReference a : fexp.getArguments()) {
-                        if (!isHashJoinCondition(a.getExpression(), inLeftAll, inRightAll, outLeftFields,
+                    for (Mutable<ILogicalExpression> a : fexp.getArguments()) {
+                        if (!isHashJoinCondition(a.getValue(), inLeftAll, inRightAll, outLeftFields,
                                 outRightFields)) {
                             return false;
                         }
@@ -147,8 +147,8 @@
                     if (ck != ComparisonKind.EQ) {
                         return false;
                     }
-                    ILogicalExpression opLeft = fexp.getArguments().get(0).getExpression();
-                    ILogicalExpression opRight = fexp.getArguments().get(1).getExpression();
+                    ILogicalExpression opLeft = fexp.getArguments().get(0).getValue();
+                    ILogicalExpression opRight = fexp.getArguments().get(1).getValue();
                     if (opLeft.getExpressionTag() != LogicalExpressionTag.VARIABLE
                             || opRight.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                         return false;
@@ -204,7 +204,7 @@
                 return null;
         }
         ArrayList<LogicalVariable> vars = new ArrayList<LogicalVariable>();
-        fexp.getArguments().get(i).getExpression().getUsedVariables(vars);
+        fexp.getArguments().get(i).getValue().getUsedVariables(vars);
         if (varsLeft.containsAll(vars)) {
             return BroadcastSide.LEFT;
         } else if (varsRight.containsAll(vars)) {
diff --git a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/util/PhysicalOptimizationsUtil.java b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/util/PhysicalOptimizationsUtil.java
index 2af9fe4..795c767 100644
--- a/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/util/PhysicalOptimizationsUtil.java
+++ b/hyracks-algebricks/hyracks-algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/util/PhysicalOptimizationsUtil.java
@@ -3,10 +3,11 @@
 import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.commons.lang3.mutable.Mutable;
+
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorReference;
 import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
@@ -27,20 +28,20 @@
     private static void computeFDsAndEqClassesWithVisitorRec(AbstractLogicalOperator op, IOptimizationContext ctx,
             FDsAndEquivClassesVisitor visitor, Set<ILogicalOperator> visitSet) throws AlgebricksException {
         visitSet.add(op);
-        for (LogicalOperatorReference i : op.getInputs()) {
-            computeFDsAndEqClassesWithVisitorRec((AbstractLogicalOperator) i.getOperator(), ctx, visitor, visitSet);
+        for (Mutable<ILogicalOperator> i : op.getInputs()) {
+            computeFDsAndEqClassesWithVisitorRec((AbstractLogicalOperator) i.getValue(), ctx, visitor, visitSet);
         }
         if (op.hasNestedPlans()) {
             for (ILogicalPlan p : ((AbstractOperatorWithNestedPlans) op).getNestedPlans()) {
-                for (LogicalOperatorReference r : p.getRoots()) {
-                    AbstractLogicalOperator rootOp = (AbstractLogicalOperator) r.getOperator();
+                for (Mutable<ILogicalOperator> r : p.getRoots()) {
+                    AbstractLogicalOperator rootOp = (AbstractLogicalOperator) r.getValue();
                     computeFDsAndEqClassesWithVisitorRec(rootOp, ctx, visitor, visitSet);
                 }
             }
         }
         if (op.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
             NestedTupleSourceOperator nts = (NestedTupleSourceOperator) op;
-            ILogicalOperator source = nts.getDataSourceReference().getOperator().getInputs().get(0).getOperator();
+            ILogicalOperator source = nts.getDataSourceReference().getValue().getInputs().get(0).getValue();
             if (!visitSet.contains(source)) {
                 computeFDsAndEqClassesWithVisitorRec((AbstractLogicalOperator) source, ctx, visitor, visitSet);
             }