diff --git a/src/GLES2/compiler/Intermediate.cpp b/src/GLES2/compiler/Intermediate.cpp
new file mode 100644
index 0000000..5ef2789
--- /dev/null
+++ b/src/GLES2/compiler/Intermediate.cpp
@@ -0,0 +1,1452 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+//
+// Build the intermediate representation.
+//
+
+#include <float.h>
+#include <limits.h>
+#include <algorithm>
+
+#include "compiler/localintermediate.h"
+#include "compiler/QualifierAlive.h"
+#include "compiler/RemoveTree.h"
+
+bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray);
+
+static TPrecision GetHigherPrecision( TPrecision left, TPrecision right ){
+    return left > right ? left : right;
+}
+
+const char* getOperatorString(TOperator op) {
+    switch (op) {
+      case EOpInitialize: return "=";
+      case EOpAssign: return "=";
+      case EOpAddAssign: return "+=";
+      case EOpSubAssign: return "-=";
+      case EOpDivAssign: return "/=";
+
+      // Fall-through.
+      case EOpMulAssign: 
+      case EOpVectorTimesMatrixAssign:
+      case EOpVectorTimesScalarAssign:
+      case EOpMatrixTimesScalarAssign:
+      case EOpMatrixTimesMatrixAssign: return "*=";
+
+      // Fall-through.
+      case EOpIndexDirect:
+      case EOpIndexIndirect: return "[]";
+
+      case EOpIndexDirectStruct: return ".";
+      case EOpVectorSwizzle: return ".";
+      case EOpAdd: return "+";
+      case EOpSub: return "-";
+      case EOpMul: return "*";
+      case EOpDiv: return "/";
+      case EOpMod: UNIMPLEMENTED(); break;
+      case EOpEqual: return "==";
+      case EOpNotEqual: return "!=";
+      case EOpLessThan: return "<";
+      case EOpGreaterThan: return ">";
+      case EOpLessThanEqual: return "<=";
+      case EOpGreaterThanEqual: return ">=";
+
+      // Fall-through.
+      case EOpVectorTimesScalar:
+      case EOpVectorTimesMatrix:
+      case EOpMatrixTimesVector:
+      case EOpMatrixTimesScalar:
+      case EOpMatrixTimesMatrix: return "*";
+
+      case EOpLogicalOr: return "||";
+      case EOpLogicalXor: return "^^";
+      case EOpLogicalAnd: return "&&";
+      case EOpNegative: return "-";
+      case EOpVectorLogicalNot: return "not";
+      case EOpLogicalNot: return "!";
+      case EOpPostIncrement: return "++";
+      case EOpPostDecrement: return "--";
+      case EOpPreIncrement: return "++";
+      case EOpPreDecrement: return "--";
+
+      // Fall-through.
+      case EOpConvIntToBool:
+      case EOpConvFloatToBool: return "bool";
+ 
+      // Fall-through.
+      case EOpConvBoolToFloat:
+      case EOpConvIntToFloat: return "float";
+ 
+      // Fall-through.
+      case EOpConvFloatToInt:
+      case EOpConvBoolToInt: return "int";
+
+      case EOpRadians: return "radians";
+      case EOpDegrees: return "degrees";
+      case EOpSin: return "sin";
+      case EOpCos: return "cos";
+      case EOpTan: return "tan";
+      case EOpAsin: return "asin";
+      case EOpAcos: return "acos";
+      case EOpAtan: return "atan";
+      case EOpExp: return "exp";
+      case EOpLog: return "log";
+      case EOpExp2: return "exp2";
+      case EOpLog2: return "log2";
+      case EOpSqrt: return "sqrt";
+      case EOpInverseSqrt: return "inversesqrt";
+      case EOpAbs: return "abs";
+      case EOpSign: return "sign";
+      case EOpFloor: return "floor";
+      case EOpCeil: return "ceil";
+      case EOpFract: return "fract";
+      case EOpLength: return "length";
+      case EOpNormalize: return "normalize";
+      case EOpDFdx: return "dFdx";
+      case EOpDFdy: return "dFdy";
+      case EOpFwidth: return "fwidth";
+      case EOpAny: return "any";
+      case EOpAll: return "all";
+
+      default: break;
+    }
+    return "";
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// First set of functions are to help build the intermediate representation.
+// These functions are not member functions of the nodes.
+// They are called from parser productions.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+//
+// Add a terminal node for an identifier in an expression.
+//
+// Returns the added node.
+//
+TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc line)
+{
+    TIntermSymbol* node = new TIntermSymbol(id, name, type);
+    node->setLine(line);
+
+    return node;
+}
+
+//
+// Connect two nodes with a new parent that does a binary operation on the nodes.
+//
+// Returns the added node.
+//
+TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable)
+{
+    switch (op) {
+        case EOpEqual:
+        case EOpNotEqual:
+            if (left->isArray())
+                return 0;
+            break;
+        case EOpLessThan:
+        case EOpGreaterThan:
+        case EOpLessThanEqual:
+        case EOpGreaterThanEqual:
+            if (left->isMatrix() || left->isArray() || left->isVector() || left->getBasicType() == EbtStruct) {
+                return 0;
+            }
+            break;
+        case EOpLogicalOr:
+        case EOpLogicalXor:
+        case EOpLogicalAnd:
+            if (left->getBasicType() != EbtBool || left->isMatrix() || left->isArray() || left->isVector()) {
+                return 0;
+            }
+            break;
+        case EOpAdd:
+        case EOpSub:
+        case EOpDiv:
+        case EOpMul:
+            if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
+                return 0;
+        default: break;
+    }
+
+    //
+    // First try converting the children to compatible types.
+    //
+    if (left->getType().getStruct() && right->getType().getStruct()) {
+        if (left->getType() != right->getType())
+            return 0;
+    } else {
+        TIntermTyped* child = addConversion(op, left->getType(), right);
+        if (child)
+            right = child;
+        else {
+            child = addConversion(op, right->getType(), left);
+            if (child)
+                left = child;
+            else
+                return 0;
+        }
+    }
+
+    //
+    // Need a new node holding things together then.  Make
+    // one and promote it to the right type.
+    //
+    TIntermBinary* node = new TIntermBinary(op);
+    if (line == 0)
+        line = right->getLine();
+    node->setLine(line);
+
+    node->setLeft(left);
+    node->setRight(right);
+    if (!node->promote(infoSink))
+        return 0;
+
+    //
+    // See if we can fold constants.
+    //
+    TIntermTyped* typedReturnNode = 0;
+    TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
+    TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
+    if (leftTempConstant && rightTempConstant) {
+        typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
+
+        if (typedReturnNode)
+            return typedReturnNode;
+    }
+
+    return node;
+}
+
+//
+// Connect two nodes through an assignment.
+//
+// Returns the added node.
+//
+TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
+{
+    //
+    // Like adding binary math, except the conversion can only go
+    // from right to left.
+    //
+    TIntermBinary* node = new TIntermBinary(op);
+    if (line == 0)
+        line = left->getLine();
+    node->setLine(line);
+
+    TIntermTyped* child = addConversion(op, left->getType(), right);
+    if (child == 0)
+        return 0;
+
+    node->setLeft(left);
+    node->setRight(child);
+    if (! node->promote(infoSink))
+        return 0;
+
+    return node;
+}
+
+//
+// Connect two nodes through an index operator, where the left node is the base
+// of an array or struct, and the right node is a direct or indirect offset.
+//
+// Returns the added node.
+// The caller should set the type of the returned node.
+//
+TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc line)
+{
+    TIntermBinary* node = new TIntermBinary(op);
+    if (line == 0)
+        line = index->getLine();
+    node->setLine(line);
+    node->setLeft(base);
+    node->setRight(index);
+
+    // caller should set the type
+
+    return node;
+}
+
+//
+// Add one node as the parent of another that it operates on.
+//
+// Returns the added node.
+//
+TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line, TSymbolTable& symbolTable)
+{
+    TIntermUnary* node;
+    TIntermTyped* child = childNode->getAsTyped();
+
+    if (child == 0) {
+        infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
+        return 0;
+    }
+
+    switch (op) {
+        case EOpLogicalNot:
+            if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
+                return 0;
+            }
+            break;
+
+        case EOpPostIncrement:
+        case EOpPreIncrement:
+        case EOpPostDecrement:
+        case EOpPreDecrement:
+        case EOpNegative:
+            if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
+                return 0;
+        default: break;
+    }
+
+    //
+    // Do we need to promote the operand?
+    //
+    // Note: Implicit promotions were removed from the language.
+    //
+    TBasicType newType = EbtVoid;
+    switch (op) {
+        case EOpConstructInt:   newType = EbtInt;   break;
+        case EOpConstructBool:  newType = EbtBool;  break;
+        case EOpConstructFloat: newType = EbtFloat; break;
+        default: break;
+    }
+
+    if (newType != EbtVoid) {
+        child = addConversion(op, TType(newType, child->getPrecision(), EvqTemporary,
+            child->getNominalSize(),
+            child->isMatrix(),
+            child->isArray()),
+            child);
+        if (child == 0)
+            return 0;
+    }
+
+    //
+    // For constructors, we are now done, it's all in the conversion.
+    //
+    switch (op) {
+        case EOpConstructInt:
+        case EOpConstructBool:
+        case EOpConstructFloat:
+            return child;
+        default: break;
+    }
+
+    TIntermConstantUnion *childTempConstant = 0;
+    if (child->getAsConstantUnion())
+        childTempConstant = child->getAsConstantUnion();
+
+    //
+    // Make a new node for the operator.
+    //
+    node = new TIntermUnary(op);
+    if (line == 0)
+        line = child->getLine();
+    node->setLine(line);
+    node->setOperand(child);
+
+    if (! node->promote(infoSink))
+        return 0;
+
+    if (childTempConstant)  {
+        TIntermTyped* newChild = childTempConstant->fold(op, 0, infoSink);
+
+        if (newChild)
+            return newChild;
+    }
+
+    return node;
+}
+
+//
+// This is the safe way to change the operator on an aggregate, as it
+// does lots of error checking and fixing.  Especially for establishing
+// a function call's operation on it's set of parameters.  Sequences
+// of instructions are also aggregates, but they just direnctly set
+// their operator to EOpSequence.
+//
+// Returns an aggregate node, which could be the one passed in if
+// it was already an aggregate but no operator was set.
+//
+TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, TSourceLoc line)
+{
+    TIntermAggregate* aggNode;
+
+    //
+    // Make sure we have an aggregate.  If not turn it into one.
+    //
+    if (node) {
+        aggNode = node->getAsAggregate();
+        if (aggNode == 0 || aggNode->getOp() != EOpNull) {
+            //
+            // Make an aggregate containing this node.
+            //
+            aggNode = new TIntermAggregate();
+            aggNode->getSequence().push_back(node);
+            if (line == 0)
+                line = node->getLine();
+        }
+    } else
+        aggNode = new TIntermAggregate();
+
+    //
+    // Set the operator.
+    //
+    aggNode->setOp(op);
+    if (line != 0)
+        aggNode->setLine(line);
+
+    return aggNode;
+}
+
+//
+// Convert one type to another.
+//
+// Returns the node representing the conversion, which could be the same
+// node passed in if no conversion was needed.
+//
+// Return 0 if a conversion can't be done.
+//
+TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node)
+{
+    //
+    // Does the base type allow operation?
+    //
+    switch (node->getBasicType()) {
+        case EbtVoid:
+        case EbtSampler2D:
+        case EbtSamplerCube:
+            return 0;
+        default: break;
+    }
+
+    //
+    // Otherwise, if types are identical, no problem
+    //
+    if (type == node->getType())
+        return node;
+
+    //
+    // If one's a structure, then no conversions.
+    //
+    if (type.getStruct() || node->getType().getStruct())
+        return 0;
+
+    //
+    // If one's an array, then no conversions.
+    //
+    if (type.isArray() || node->getType().isArray())
+        return 0;
+
+    TBasicType promoteTo;
+
+    switch (op) {
+        //
+        // Explicit conversions
+        //
+        case EOpConstructBool:
+            promoteTo = EbtBool;
+            break;
+        case EOpConstructFloat:
+            promoteTo = EbtFloat;
+            break;
+        case EOpConstructInt:
+            promoteTo = EbtInt;
+            break;
+        default:
+            //
+            // implicit conversions were removed from the language.
+            //
+            if (type.getBasicType() != node->getType().getBasicType())
+                return 0;
+            //
+            // Size and structure could still differ, but that's
+            // handled by operator promotion.
+            //
+            return node;
+    }
+
+    if (node->getAsConstantUnion()) {
+
+        return (promoteConstantUnion(promoteTo, node->getAsConstantUnion()));
+    } else {
+
+        //
+        // Add a new newNode for the conversion.
+        //
+        TIntermUnary* newNode = 0;
+
+        TOperator newOp = EOpNull;
+        switch (promoteTo) {
+            case EbtFloat:
+                switch (node->getBasicType()) {
+                    case EbtInt:   newOp = EOpConvIntToFloat;  break;
+                    case EbtBool:  newOp = EOpConvBoolToFloat; break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                        return 0;
+                }
+                break;
+            case EbtBool:
+                switch (node->getBasicType()) {
+                    case EbtInt:   newOp = EOpConvIntToBool;   break;
+                    case EbtFloat: newOp = EOpConvFloatToBool; break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                        return 0;
+                }
+                break;
+            case EbtInt:
+                switch (node->getBasicType()) {
+                    case EbtBool:   newOp = EOpConvBoolToInt;  break;
+                    case EbtFloat:  newOp = EOpConvFloatToInt; break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
+                        return 0;
+                }
+                break;
+            default:
+                infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine());
+                return 0;
+        }
+
+        TType type(promoteTo, node->getPrecision(), EvqTemporary, node->getNominalSize(), node->isMatrix(), node->isArray());
+        newNode = new TIntermUnary(newOp, type);
+        newNode->setLine(node->getLine());
+        newNode->setOperand(node);
+
+        return newNode;
+    }
+}
+
+//
+// Safe way to combine two nodes into an aggregate.  Works with null pointers,
+// a node that's not a aggregate yet, etc.
+//
+// Returns the resulting aggregate, unless 0 was passed in for
+// both existing nodes.
+//
+TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc line)
+{
+    if (left == 0 && right == 0)
+        return 0;
+
+    TIntermAggregate* aggNode = 0;
+    if (left)
+        aggNode = left->getAsAggregate();
+    if (!aggNode || aggNode->getOp() != EOpNull) {
+        aggNode = new TIntermAggregate;
+        if (left)
+            aggNode->getSequence().push_back(left);
+    }
+
+    if (right)
+        aggNode->getSequence().push_back(right);
+
+    if (line != 0)
+        aggNode->setLine(line);
+
+    return aggNode;
+}
+
+//
+// Turn an existing node into an aggregate.
+//
+// Returns an aggregate, unless 0 was passed in for the existing node.
+//
+TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc line)
+{
+    if (node == 0)
+        return 0;
+
+    TIntermAggregate* aggNode = new TIntermAggregate;
+    aggNode->getSequence().push_back(node);
+
+    if (line != 0)
+        aggNode->setLine(line);
+    else
+        aggNode->setLine(node->getLine());
+
+    return aggNode;
+}
+
+//
+// For "if" test nodes.  There are three children; a condition,
+// a true path, and a false path.  The two paths are in the
+// nodePair.
+//
+// Returns the selection node created.
+//
+TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line)
+{
+    //
+    // For compile time constant selections, prune the code and
+    // test now.
+    //
+
+    if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) {
+        if (cond->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getBConst() == true)
+            return nodePair.node1 ? setAggregateOperator(nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL;
+        else
+            return nodePair.node2 ? setAggregateOperator(nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL;
+    }
+
+    TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
+    node->setLine(line);
+
+    return node;
+}
+
+
+TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
+{
+    if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) {
+        return right;
+    } else {
+        TIntermTyped *commaAggregate = growAggregate(left, right, line);
+        commaAggregate->getAsAggregate()->setOp(EOpComma);
+        commaAggregate->setType(right->getType());
+        commaAggregate->getTypePointer()->setQualifier(EvqTemporary);
+        return commaAggregate;
+    }
+}
+
+//
+// For "?:" test nodes.  There are three children; a condition,
+// a true path, and a false path.  The two paths are specified
+// as separate parameters.
+//
+// Returns the selection node created, or 0 if one could not be.
+//
+TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line)
+{
+    //
+    // Get compatible types.
+    //
+    TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock);
+    if (child)
+        falseBlock = child;
+    else {
+        child = addConversion(EOpSequence, falseBlock->getType(), trueBlock);
+        if (child)
+            trueBlock = child;
+        else
+            return 0;
+    }
+
+    //
+    // See if all the operands are constant, then fold it otherwise not.
+    //
+
+    if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
+        if (cond->getAsConstantUnion()->getUnionArrayPointer()->getBConst())
+            return trueBlock;
+        else
+            return falseBlock;
+    }
+
+    //
+    // Make a selection node.
+    //
+    TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
+    node->getTypePointer()->setQualifier(EvqTemporary);
+    node->setLine(line);
+
+    return node;
+}
+
+//
+// Constant terminal nodes.  Has a union that contains bool, float or int constants
+//
+// Returns the constant union node created.
+//
+
+TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayPointer, const TType& t, TSourceLoc line)
+{
+    TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
+    node->setLine(line);
+
+    return node;
+}
+
+TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
+{
+
+    TIntermAggregate* node = new TIntermAggregate(EOpSequence);
+
+    node->setLine(line);
+    TIntermConstantUnion* constIntNode;
+    TIntermSequence &sequenceVector = node->getSequence();
+    ConstantUnion* unionArray;
+
+    for (int i = 0; i < fields.num; i++) {
+        unionArray = new ConstantUnion[1];
+        unionArray->setIConst(fields.offsets[i]);
+        constIntNode = addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), line);
+        sequenceVector.push_back(constIntNode);
+    }
+
+    return node;
+}
+
+//
+// Create loop nodes.
+//
+TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, TSourceLoc line)
+{
+    TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
+    node->setLine(line);
+
+    return node;
+}
+
+//
+// Add branches.
+//
+TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line)
+{
+    return addBranch(branchOp, 0, line);
+}
+
+TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc line)
+{
+    TIntermBranch* node = new TIntermBranch(branchOp, expression);
+    node->setLine(line);
+
+    return node;
+}
+
+//
+// This is to be executed once the final root is put on top by the parsing
+// process.
+//
+bool TIntermediate::postProcess(TIntermNode* root)
+{
+    if (root == 0)
+        return true;
+
+    //
+    // First, finish off the top level sequence, if any
+    //
+    TIntermAggregate* aggRoot = root->getAsAggregate();
+    if (aggRoot && aggRoot->getOp() == EOpNull)
+        aggRoot->setOp(EOpSequence);
+
+    return true;
+}
+
+//
+// This deletes the tree.
+//
+void TIntermediate::remove(TIntermNode* root)
+{
+    if (root)
+        RemoveAllTreeNodes(root);
+}
+
+////////////////////////////////////////////////////////////////
+//
+// Member functions of the nodes used for building the tree.
+//
+////////////////////////////////////////////////////////////////
+
+//
+// Say whether or not an operation node changes the value of a variable.
+//
+// Returns true if state is modified.
+//
+bool TIntermOperator::modifiesState() const
+{
+    switch (op) {
+        case EOpPostIncrement:
+        case EOpPostDecrement:
+        case EOpPreIncrement:
+        case EOpPreDecrement:
+        case EOpAssign:
+        case EOpAddAssign:
+        case EOpSubAssign:
+        case EOpMulAssign:
+        case EOpVectorTimesMatrixAssign:
+        case EOpVectorTimesScalarAssign:
+        case EOpMatrixTimesScalarAssign:
+        case EOpMatrixTimesMatrixAssign:
+        case EOpDivAssign:
+            return true;
+        default:
+            return false;
+    }
+}
+
+//
+// returns true if the operator is for one of the constructors
+//
+bool TIntermOperator::isConstructor() const
+{
+    switch (op) {
+        case EOpConstructVec2:
+        case EOpConstructVec3:
+        case EOpConstructVec4:
+        case EOpConstructMat2:
+        case EOpConstructMat3:
+        case EOpConstructMat4:
+        case EOpConstructFloat:
+        case EOpConstructIVec2:
+        case EOpConstructIVec3:
+        case EOpConstructIVec4:
+        case EOpConstructInt:
+        case EOpConstructBVec2:
+        case EOpConstructBVec3:
+        case EOpConstructBVec4:
+        case EOpConstructBool:
+        case EOpConstructStruct:
+            return true;
+        default:
+            return false;
+    }
+}
+//
+// Make sure the type of a unary operator is appropriate for its
+// combination of operation and operand type.
+//
+// Returns false in nothing makes sense.
+//
+bool TIntermUnary::promote(TInfoSink&)
+{
+    switch (op) {
+        case EOpLogicalNot:
+            if (operand->getBasicType() != EbtBool)
+                return false;
+            break;
+        case EOpNegative:
+        case EOpPostIncrement:
+        case EOpPostDecrement:
+        case EOpPreIncrement:
+        case EOpPreDecrement:
+            if (operand->getBasicType() == EbtBool)
+                return false;
+            break;
+
+            // operators for built-ins are already type checked against their prototype
+        case EOpAny:
+        case EOpAll:
+        case EOpVectorLogicalNot:
+            return true;
+
+        default:
+            if (operand->getBasicType() != EbtFloat)
+                return false;
+    }
+
+    setType(operand->getType());
+
+	// Unary operations results in temporary variables unless const.
+    if (operand->getQualifier() != EvqConst) {
+        getTypePointer()->setQualifier(EvqTemporary);
+    }
+
+    return true;
+}
+
+//
+// Establishes the type of the resultant operation, as well as
+// makes the operator the correct one for the operands.
+//
+// Returns false if operator can't work on operands.
+//
+bool TIntermBinary::promote(TInfoSink& infoSink)
+{
+    // This function only handles scalars, vectors, and matrices.
+    if (left->isArray() || right->isArray()) {
+        infoSink.info.message(EPrefixInternalError, "Invalid operation for arrays", getLine());
+        return false;
+    }
+
+    // GLSL ES 2.0 does not support implicit type casting.
+    // So the basic type should always match.
+    if (left->getBasicType() != right->getBasicType())
+        return false;
+
+    //
+    // Base assumption:  just make the type the same as the left
+    // operand.  Then only deviations from this need be coded.
+    //
+    setType(left->getType());
+
+    // The result gets promoted to the highest precision.
+    TPrecision higherPrecision = GetHigherPrecision(left->getPrecision(), right->getPrecision());
+    getTypePointer()->setPrecision(higherPrecision);
+
+    // Binary operations results in temporary variables unless both
+    // operands are const.
+    if (left->getQualifier() != EvqConst || right->getQualifier() != EvqConst) {
+        getTypePointer()->setQualifier(EvqTemporary);
+    }
+
+    int size = std::max(left->getNominalSize(), right->getNominalSize());
+
+    //
+    // All scalars. Code after this test assumes this case is removed!
+    //
+    if (size == 1) {
+        switch (op) {
+            //
+            // Promote to conditional
+            //
+            case EOpEqual:
+            case EOpNotEqual:
+            case EOpLessThan:
+            case EOpGreaterThan:
+            case EOpLessThanEqual:
+            case EOpGreaterThanEqual:
+                setType(TType(EbtBool, EbpUndefined));
+                break;
+
+            //
+            // And and Or operate on conditionals
+            //
+            case EOpLogicalAnd:
+            case EOpLogicalOr:
+                // Both operands must be of type bool.
+                if (left->getBasicType() != EbtBool || right->getBasicType() != EbtBool)
+                    return false;
+                setType(TType(EbtBool, EbpUndefined));
+                break;
+
+            default:
+                break;
+        }
+        return true;
+    }
+
+    // If we reach here, at least one of the operands is vector or matrix.
+    // The other operand could be a scalar, vector, or matrix.
+    // Are the sizes compatible?
+    //
+    if (left->getNominalSize() != right->getNominalSize()) {
+        // If the nominal size of operands do not match:
+        // One of them must be scalar.
+        if (left->getNominalSize() != 1 && right->getNominalSize() != 1)
+            return false;
+        // Operator cannot be of type pure assignment.
+        if (op == EOpAssign || op == EOpInitialize)
+            return false;
+    }
+
+    //
+    // Can these two operands be combined?
+    //
+    TBasicType basicType = left->getBasicType();
+    switch (op) {
+        case EOpMul:
+            if (!left->isMatrix() && right->isMatrix()) {
+                if (left->isVector())
+                    op = EOpVectorTimesMatrix;
+                else {
+                    op = EOpMatrixTimesScalar;
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, true));
+                }
+            } else if (left->isMatrix() && !right->isMatrix()) {
+                if (right->isVector()) {
+                    op = EOpMatrixTimesVector;
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
+                } else {
+                    op = EOpMatrixTimesScalar;
+                }
+            } else if (left->isMatrix() && right->isMatrix()) {
+                op = EOpMatrixTimesMatrix;
+            } else if (!left->isMatrix() && !right->isMatrix()) {
+                if (left->isVector() && right->isVector()) {
+                    // leave as component product
+                } else if (left->isVector() || right->isVector()) {
+                    op = EOpVectorTimesScalar;
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
+                }
+            } else {
+                infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+                return false;
+            }
+            break;
+        case EOpMulAssign:
+            if (!left->isMatrix() && right->isMatrix()) {
+                if (left->isVector())
+                    op = EOpVectorTimesMatrixAssign;
+                else {
+                    return false;
+                }
+            } else if (left->isMatrix() && !right->isMatrix()) {
+                if (right->isVector()) {
+                    return false;
+                } else {
+                    op = EOpMatrixTimesScalarAssign;
+                }
+            } else if (left->isMatrix() && right->isMatrix()) {
+                op = EOpMatrixTimesMatrixAssign;
+            } else if (!left->isMatrix() && !right->isMatrix()) {
+                if (left->isVector() && right->isVector()) {
+                    // leave as component product
+                } else if (left->isVector() || right->isVector()) {
+                    if (! left->isVector())
+                        return false;
+                    op = EOpVectorTimesScalarAssign;
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
+                }
+            } else {
+                infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
+                return false;
+            }
+            break;
+
+        case EOpAssign:
+        case EOpInitialize:
+        case EOpAdd:
+        case EOpSub:
+        case EOpDiv:
+        case EOpAddAssign:
+        case EOpSubAssign:
+        case EOpDivAssign:
+            if ((left->isMatrix() && right->isVector()) ||
+                (left->isVector() && right->isMatrix()))
+                return false;
+            setType(TType(basicType, higherPrecision, EvqTemporary, size, left->isMatrix() || right->isMatrix()));
+            break;
+
+        case EOpEqual:
+        case EOpNotEqual:
+        case EOpLessThan:
+        case EOpGreaterThan:
+        case EOpLessThanEqual:
+        case EOpGreaterThanEqual:
+            if ((left->isMatrix() && right->isVector()) ||
+                (left->isVector() && right->isMatrix()))
+                return false;
+            setType(TType(EbtBool, EbpUndefined));
+            break;
+
+        default:
+            return false;
+    }
+    
+    return true;
+}
+
+bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
+{
+    const TTypeList* fields = leftNodeType.getStruct();
+
+    size_t structSize = fields->size();
+    int index = 0;
+
+    for (size_t j = 0; j < structSize; j++) {
+        int size = (*fields)[j].type->getObjectSize();
+        for (int i = 0; i < size; i++) {
+            if ((*fields)[j].type->getBasicType() == EbtStruct) {
+                if (!CompareStructure(*(*fields)[j].type, &rightUnionArray[index], &leftUnionArray[index]))
+                    return false;
+            } else {
+                if (leftUnionArray[index] != rightUnionArray[index])
+                    return false;
+                index++;
+            }
+
+        }
+    }
+    return true;
+}
+
+bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
+{
+    if (leftNodeType.isArray()) {
+        TType typeWithoutArrayness = leftNodeType;
+        typeWithoutArrayness.clearArrayness();
+
+        int arraySize = leftNodeType.getArraySize();
+
+        for (int i = 0; i < arraySize; ++i) {
+            int offset = typeWithoutArrayness.getObjectSize() * i;
+            if (!CompareStruct(typeWithoutArrayness, &rightUnionArray[offset], &leftUnionArray[offset]))
+                return false;
+        }
+    } else
+        return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray);
+
+    return true;
+}
+
+//
+// The fold functions see if an operation on a constant can be done in place,
+// without generating run-time code.
+//
+// Returns the node to keep using, which may or may not be the node passed in.
+//
+
+TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink)
+{
+    ConstantUnion *unionArray = getUnionArrayPointer();
+    int objectSize = getType().getObjectSize();
+
+    if (constantNode) {  // binary operations
+        TIntermConstantUnion *node = constantNode->getAsConstantUnion();
+        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
+        TType returnType = getType();
+
+        // for a case like float f = 1.2 + vec4(2,3,4,5);
+        if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) {
+            rightUnionArray = new ConstantUnion[objectSize];
+            for (int i = 0; i < objectSize; ++i)
+                rightUnionArray[i] = *node->getUnionArrayPointer();
+            returnType = getType();
+        } else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1) {
+            // for a case like float f = vec4(2,3,4,5) + 1.2;
+            unionArray = new ConstantUnion[constantNode->getType().getObjectSize()];
+            for (int i = 0; i < constantNode->getType().getObjectSize(); ++i)
+                unionArray[i] = *getUnionArrayPointer();
+            returnType = node->getType();
+            objectSize = constantNode->getType().getObjectSize();
+        }
+
+        ConstantUnion* tempConstArray = 0;
+        TIntermConstantUnion *tempNode;
+
+        bool boolNodeFlag = false;
+        switch(op) {
+            case EOpAdd:
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (int i = 0; i < objectSize; i++)
+                        tempConstArray[i] = unionArray[i] + rightUnionArray[i];
+                }
+                break;
+            case EOpSub:
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (int i = 0; i < objectSize; i++)
+                        tempConstArray[i] = unionArray[i] - rightUnionArray[i];
+                }
+                break;
+
+            case EOpMul:
+            case EOpVectorTimesScalar:
+            case EOpMatrixTimesScalar:
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (int i = 0; i < objectSize; i++)
+                        tempConstArray[i] = unionArray[i] * rightUnionArray[i];
+                }
+                break;
+            case EOpMatrixTimesMatrix:
+                if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) {
+                    infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine());
+                    return 0;
+                }
+                {// support MSVC++6.0
+                    int size = getNominalSize();
+                    tempConstArray = new ConstantUnion[size*size];
+                    for (int row = 0; row < size; row++) {
+                        for (int column = 0; column < size; column++) {
+                            tempConstArray[size * column + row].setFConst(0.0f);
+                            for (int i = 0; i < size; i++) {
+                                tempConstArray[size * column + row].setFConst(tempConstArray[size * column + row].getFConst() + unionArray[i * size + row].getFConst() * (rightUnionArray[column * size + i].getFConst()));
+                            }
+                        }
+                    }
+                }
+                break;
+            case EOpDiv:
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (int i = 0; i < objectSize; i++) {
+                        switch (getType().getBasicType()) {
+            case EbtFloat:
+                if (rightUnionArray[i] == 0.0f) {
+                    infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
+                    tempConstArray[i].setFConst(FLT_MAX);
+                } else
+                    tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
+                break;
+
+            case EbtInt:
+                if (rightUnionArray[i] == 0) {
+                    infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
+                    tempConstArray[i].setIConst(INT_MAX);
+                } else
+                    tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
+                break;
+            default:
+                infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
+                return 0;
+                        }
+                    }
+                }
+                break;
+
+            case EOpMatrixTimesVector:
+                if (node->getBasicType() != EbtFloat) {
+                    infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", getLine());
+                    return 0;
+                }
+                tempConstArray = new ConstantUnion[getNominalSize()];
+
+                {// support MSVC++6.0
+                    for (int size = getNominalSize(), i = 0; i < size; i++) {
+                        tempConstArray[i].setFConst(0.0f);
+                        for (int j = 0; j < size; j++) {
+                            tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j*size + i].getFConst()) * rightUnionArray[j].getFConst()));
+                        }
+                    }
+                }
+
+                tempNode = new TIntermConstantUnion(tempConstArray, node->getType());
+                tempNode->setLine(getLine());
+
+                return tempNode;
+
+            case EOpVectorTimesMatrix:
+                if (getType().getBasicType() != EbtFloat) {
+                    infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", getLine());
+                    return 0;
+                }
+
+                tempConstArray = new ConstantUnion[getNominalSize()];
+                {// support MSVC++6.0
+                    for (int size = getNominalSize(), i = 0; i < size; i++) {
+                        tempConstArray[i].setFConst(0.0f);
+                        for (int j = 0; j < size; j++) {
+                            tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j].getFConst()) * rightUnionArray[i*size + j].getFConst()));
+                        }
+                    }
+                }
+                break;
+
+            case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (int i = 0; i < objectSize; i++)
+                        tempConstArray[i] = unionArray[i] && rightUnionArray[i];
+                }
+                break;
+
+            case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (int i = 0; i < objectSize; i++)
+                        tempConstArray[i] = unionArray[i] || rightUnionArray[i];
+                }
+                break;
+
+            case EOpLogicalXor:
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (int i = 0; i < objectSize; i++)
+                        switch (getType().getBasicType()) {
+            case EbtBool: tempConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
+            default: assert(false && "Default missing");
+                    }
+                }
+                break;
+
+            case EOpLessThan:
+                assert(objectSize == 1);
+                tempConstArray = new ConstantUnion[1];
+                tempConstArray->setBConst(*unionArray < *rightUnionArray);
+                returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                break;
+            case EOpGreaterThan:
+                assert(objectSize == 1);
+                tempConstArray = new ConstantUnion[1];
+                tempConstArray->setBConst(*unionArray > *rightUnionArray);
+                returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                break;
+            case EOpLessThanEqual:
+                {
+                    assert(objectSize == 1);
+                    ConstantUnion constant;
+                    constant.setBConst(*unionArray > *rightUnionArray);
+                    tempConstArray = new ConstantUnion[1];
+                    tempConstArray->setBConst(!constant.getBConst());
+                    returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                    break;
+                }
+            case EOpGreaterThanEqual:
+                {
+                    assert(objectSize == 1);
+                    ConstantUnion constant;
+                    constant.setBConst(*unionArray < *rightUnionArray);
+                    tempConstArray = new ConstantUnion[1];
+                    tempConstArray->setBConst(!constant.getBConst());
+                    returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                    break;
+                }
+
+            case EOpEqual:
+                if (getType().getBasicType() == EbtStruct) {
+                    if (!CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray))
+                        boolNodeFlag = true;
+                } else {
+                    for (int i = 0; i < objectSize; i++) {
+                        if (unionArray[i] != rightUnionArray[i]) {
+                            boolNodeFlag = true;
+                            break;  // break out of for loop
+                        }
+                    }
+                }
+
+                tempConstArray = new ConstantUnion[1];
+                if (!boolNodeFlag) {
+                    tempConstArray->setBConst(true);
+                }
+                else {
+                    tempConstArray->setBConst(false);
+                }
+
+                tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
+                tempNode->setLine(getLine());
+
+                return tempNode;
+
+            case EOpNotEqual:
+                if (getType().getBasicType() == EbtStruct) {
+                    if (CompareStructure(node->getType(), node->getUnionArrayPointer(), unionArray))
+                        boolNodeFlag = true;
+                } else {
+                    for (int i = 0; i < objectSize; i++) {
+                        if (unionArray[i] == rightUnionArray[i]) {
+                            boolNodeFlag = true;
+                            break;  // break out of for loop
+                        }
+                    }
+                }
+
+                tempConstArray = new ConstantUnion[1];
+                if (!boolNodeFlag) {
+                    tempConstArray->setBConst(true);
+                }
+                else {
+                    tempConstArray->setBConst(false);
+                }
+
+                tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
+                tempNode->setLine(getLine());
+
+                return tempNode;
+
+            default:
+                infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLine());
+                return 0;
+        }
+        tempNode = new TIntermConstantUnion(tempConstArray, returnType);
+        tempNode->setLine(getLine());
+
+        return tempNode;
+    } else {
+        //
+        // Do unary operations
+        //
+        TIntermConstantUnion *newNode = 0;
+        ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
+        for (int i = 0; i < objectSize; i++) {
+            switch(op) {
+                case EOpNegative:
+                    switch (getType().getBasicType()) {
+                        case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break;
+                        case EbtInt:   tempConstArray[i].setIConst(-unionArray[i].getIConst()); break;
+                        default:
+                            infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+                            return 0;
+                    }
+                    break;
+                case EOpLogicalNot: // this code is written for possible future use, will not get executed currently
+                    switch (getType().getBasicType()) {
+                        case EbtBool:  tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
+                        default:
+                            infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+                            return 0;
+                    }
+                    break;
+                default:
+                    return 0;
+            }
+        }
+        newNode = new TIntermConstantUnion(tempConstArray, getType());
+        newNode->setLine(getLine());
+        return newNode;
+    }
+}
+
+TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
+{
+    ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
+    int size = node->getType().getObjectSize();
+
+    ConstantUnion *leftUnionArray = new ConstantUnion[size];
+
+    for (int i=0; i < size; i++) {
+
+        switch (promoteTo) {
+            case EbtFloat:
+                switch (node->getType().getBasicType()) {
+                    case EbtInt:
+                        leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getIConst()));
+                        break;
+                    case EbtBool:
+                        leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getBConst()));
+                        break;
+                    case EbtFloat:
+                        leftUnionArray[i] = rightUnionArray[i];
+                        break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                        return 0;
+                }
+                break;
+            case EbtInt:
+                switch (node->getType().getBasicType()) {
+                    case EbtInt:
+                        leftUnionArray[i] = rightUnionArray[i];
+                        break;
+                    case EbtBool:
+                        leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getBConst()));
+                        break;
+                    case EbtFloat:
+                        leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getFConst()));
+                        break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                        return 0;
+                }
+                break;
+            case EbtBool:
+                switch (node->getType().getBasicType()) {
+                    case EbtInt:
+                        leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0);
+                        break;
+                    case EbtBool:
+                        leftUnionArray[i] = rightUnionArray[i];
+                        break;
+                    case EbtFloat:
+                        leftUnionArray[i].setBConst(rightUnionArray[i].getFConst() != 0.0f);
+                        break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
+                        return 0;
+                }
+
+                break;
+            default:
+                infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
+                return 0;
+        }
+
+    }
+
+    const TType& t = node->getType();
+
+    return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine());
+}
+
