Merged hyracks master back into VXQuery branch.
diff --git a/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablePolicy.java b/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablePolicy.java
new file mode 100644
index 0000000..efcc7a8
--- /dev/null
+++ b/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablePolicy.java
@@ -0,0 +1,60 @@
+/*
+ * 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.rewriter.rules;
+
+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.LogicalExpressionTag;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+
+/**
+ * Where assign operators only assign a new variable ID for a reference expression,
+ * all references are updated to the first variable ID.
+ */
+public class InlineVariablePolicy implements InlineVariablesRule.IInlineVariablePolicy {
+
+    @Override
+    public boolean isCandidateForInlining(ILogicalExpression expr) {
+        if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public List<Mutable<ILogicalOperator>> descendIntoNextOperator(AbstractLogicalOperator op) {
+        List<Mutable<ILogicalOperator>> descendOp = new ArrayList<Mutable<ILogicalOperator>>();
+        // Descend into children removing projects on the way.
+        for (Mutable<ILogicalOperator> inputOpRef : op.getInputs()) {
+            descendOp.add(inputOpRef);
+        }
+        return descendOp;
+    }
+
+    @Override
+    public boolean isCanidateInlineTarget(AbstractLogicalOperator op) {
+        // Only inline variables in operators that can deal with arbitrary expressions.
+        if (!op.requiresVariableReferenceExpressions()) {
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java b/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java
index 40b049b..aae74d8 100644
--- a/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java
+++ b/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java
@@ -47,19 +47,19 @@
  * (e.g., a select may be pushed into a join to enable an efficient physical join operator).
  * 
  * Preconditions/Assumptions:
- * Assumes no projects are in the plan. Only inlines variables whose assigned expression is a function call 
- * (i.e., this rule ignores right-hand side constants and other variable references expressions  
+ * Assumes no projects are in the plan. Only inlines variables whose assigned expression is a function call
+ * (i.e., this rule ignores right-hand side constants and other variable references expressions
  * 
  * Postconditions/Examples:
  * All qualifying variables have been inlined.
- * 
+ *
  * Example (simplified):
- * 
+ *
  * Before plan:
  * select <- [$$1 < $$2 + $$0]
  *   assign [$$2] <- [funcZ() + $$0]
  *     assign [$$0, $$1] <- [funcX(), funcY()]
- * 
+ *
  * After plan:
  * select <- [funcY() < funcZ() + funcX() + funcX()]
  *   assign [$$2] <- [funcZ() + funcX()]
@@ -73,12 +73,22 @@
 
     // Visitor for replacing variable reference expressions with their originating expression.
     protected InlineVariablesVisitor inlineVisitor = new InlineVariablesVisitor(varAssignRhs);
-    
+
     // Set of FunctionIdentifiers that we should not inline.
     protected Set<FunctionIdentifier> doNotInlineFuncs = new HashSet<FunctionIdentifier>();
-    
+
     protected boolean hasRun = false;
-    
+
+    protected IInlineVariablePolicy policy;
+
+    public InlineVariablesRule() {
+        policy = new InlineVariablePolicy();
+    }
+
+    public InlineVariablesRule(IInlineVariablePolicy policy) {
+        this.policy = policy;
+    }
+
     @Override
     public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
         return false;
@@ -100,15 +110,14 @@
         hasRun = true;
         return modified;
     }
-    
+
     protected void prepare(IOptimizationContext context) {
         varAssignRhs.clear();
         inlineVisitor.setContext(context);
     }
-    
+
     protected boolean performBottomUpAction(AbstractLogicalOperator op) throws AlgebricksException {
-        // Only inline variables in operators that can deal with arbitrary expressions.
-        if (!op.requiresVariableReferenceExpressions()) {
+        if (policy.isCanidateInlineTarget(op)) {
             inlineVisitor.setOperator(op);
             return op.acceptExpressionTransform(inlineVisitor);
         }
@@ -118,41 +127,43 @@
     protected boolean performFinalAction() throws AlgebricksException {
         return false;
     }
-    
+
     protected boolean inlineVariables(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
             throws AlgebricksException {
         AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
-        
+
         // Update mapping from variables to expressions during top-down traversal.
         if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
             AssignOperator assignOp = (AssignOperator) op;
             List<LogicalVariable> vars = assignOp.getVariables();
-            List<Mutable<ILogicalExpression>> exprs = assignOp.getExpressions();            
+            List<Mutable<ILogicalExpression>> exprs = assignOp.getExpressions();
             for (int i = 0; i < vars.size(); i++) {
                 ILogicalExpression expr = exprs.get(i).getValue();
-                // Ignore functions that are in the doNotInline set.                
-                if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
-                    AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
-                    if (doNotInlineFuncs.contains(funcExpr.getFunctionIdentifier())) {
-                        continue;
+                if (policy.isCandidateForInlining(expr)) {
+                    // Ignore functions that are in the doNotInline set.
+                    if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+                        AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
+                        if (doNotInlineFuncs.contains(funcExpr.getFunctionIdentifier())) {
+                            continue;
+                        }
                     }
+                    varAssignRhs.put(vars.get(i), exprs.get(i).getValue());
                 }
-                varAssignRhs.put(vars.get(i), exprs.get(i).getValue());
             }
         }
 
-        // Descend into children removing projects on the way.
         boolean modified = false;
-        for (Mutable<ILogicalOperator> inputOpRef : op.getInputs()) {
+        // Follow all operators from this operator.
+        for (Mutable<ILogicalOperator> inputOpRef : policy.descendIntoNextOperator(op)) {
             if (inlineVariables(inputOpRef, context)) {
                 modified = true;
-            }            
+            }
         }
 
         if (performBottomUpAction(op)) {
             modified = true;
         }
-        
+
         if (modified) {
             context.computeAndSetTypeEnvironmentForOperator(op);
             context.addToDontApplySet(this, op);
@@ -164,23 +175,23 @@
     }
 
     protected class InlineVariablesVisitor implements ILogicalExpressionReferenceTransform {
-        
+
         private final Map<LogicalVariable, ILogicalExpression> varAssignRhs;
         private final Set<LogicalVariable> liveVars = new HashSet<LogicalVariable>();
-        private final List<LogicalVariable> rhsUsedVars = new ArrayList<LogicalVariable>();        
+        private final List<LogicalVariable> rhsUsedVars = new ArrayList<LogicalVariable>();
         private ILogicalOperator op;
         private IOptimizationContext context;
         // If set, only replace this variable reference.
         private LogicalVariable targetVar;
-        
+
         public InlineVariablesVisitor(Map<LogicalVariable, ILogicalExpression> varAssignRhs) {
             this.varAssignRhs = varAssignRhs;
         }
-        
+
         public void setTargetVariable(LogicalVariable targetVar) {
             this.targetVar = targetVar;
         }
-        
+
         public void setContext(IOptimizationContext context) {
             this.context = context;
         }
@@ -189,9 +200,9 @@
             this.op = op;
             liveVars.clear();
         }
-        
+
         @Override
-        public boolean transform(Mutable<ILogicalExpression> exprRef) throws AlgebricksException {            
+        public boolean transform(Mutable<ILogicalExpression> exprRef) throws AlgebricksException {
             ILogicalExpression e = exprRef.getValue();
             switch (((AbstractLogicalExpression) e).getExpressionTag()) {
                 case VARIABLE: {
@@ -209,7 +220,7 @@
                         // Variable was not produced by an assign.
                         return false;
                     }
-                    
+
                     // Make sure used variables from rhs are live.
                     if (liveVars.isEmpty()) {
                         VariableUtilities.getLiveVariables(op, liveVars);
@@ -221,7 +232,7 @@
                             return false;
                         }
                     }
-                    
+
                     // Replace variable reference with a clone of the rhs expr.
                     exprRef.setValue(rhs.cloneExpression());
                     return true;
@@ -242,4 +253,15 @@
             }
         }
     }
+
+    public static interface IInlineVariablePolicy {
+
+        public boolean isCandidateForInlining(ILogicalExpression expr);
+
+        public List<Mutable<ILogicalOperator>> descendIntoNextOperator(AbstractLogicalOperator op);
+
+        public boolean isCanidateInlineTarget(AbstractLogicalOperator op);
+
+    }
+
 }
diff --git a/hyracks/hyracks-control/hyracks-control-common/src/main/java/edu/uci/ics/hyracks/control/common/application/ApplicationContext.java b/hyracks/hyracks-control/hyracks-control-common/src/main/java/edu/uci/ics/hyracks/control/common/application/ApplicationContext.java
index 2ca7ccf..828f2fb 100644
--- a/hyracks/hyracks-control/hyracks-control-common/src/main/java/edu/uci/ics/hyracks/control/common/application/ApplicationContext.java
+++ b/hyracks/hyracks-control/hyracks-control-common/src/main/java/edu/uci/ics/hyracks/control/common/application/ApplicationContext.java
@@ -31,7 +31,9 @@
     protected IJobSerializerDeserializerContainer jobSerDeContainer = new JobSerializerDeserializerContainer();
     protected ThreadFactory threadFactory = new ThreadFactory() {
         public Thread newThread(Runnable r) {
-            return new Thread(r);
+            Thread t = new Thread(r);
+            t.setDaemon(true);
+            return t;
         }
     };