diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/internal/writer/BlockWriter.java b/com.amd.aparapi/src/java/com/amd/aparapi/internal/writer/BlockWriter.java
index 090c14542a9faad28a257043c40edee46834ef37..82031e2ece48d09dbd583d1e1cdbe00770029732 100644
--- a/com.amd.aparapi/src/java/com/amd/aparapi/internal/writer/BlockWriter.java
+++ b/com.amd.aparapi/src/java/com/amd/aparapi/internal/writer/BlockWriter.java
@@ -1,803 +1,805 @@
-/*
-Copyright (c) 2010-2011, Advanced Micro Devices, Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
-following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this list of conditions and the following
-disclaimer. 
-
-Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
-disclaimer in the documentation and/or other materials provided with the distribution. 
-
-Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
-derived from this software without specific prior written permission. 
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-If you use the software (in whole or in part), you shall adhere to all applicable U.S., European, and other export
-laws, including but not limited to the U.S. Export Administration Regulations ("EAR"), (15 C.F.R. Sections 730 through
-774), and E.U. Council Regulation (EC) No 1334/2000 of 22 June 2000.  Further, pursuant to Section 740.6 of the EAR,
-you hereby certify that, except pursuant to a license granted by the United States Department of Commerce Bureau of 
-Industry and Security or as otherwise permitted pursuant to a License Exception under the U.S. Export Administration 
-Regulations ("EAR"), you will not (1) export, re-export or release to a national of a country in Country Groups D:1,
-E:1 or E:2 any restricted technology, software, or source code you receive hereunder, or (2) export to Country Groups
-D:1, E:1 or E:2 the direct product of such technology or software, if such foreign produced direct product is subject
-to national security controls as identified on the Commerce Control List (currently found in Supplement 1 to Part 774
-of EAR).  For the most current Country Group listings, or for additional information about the EAR or your obligations
-under those regulations, please refer to the U.S. Bureau of Industry and Security's website at http://www.bis.doc.gov/. 
-
-*/
-package com.amd.aparapi.internal.writer;
-
-import com.amd.aparapi.*;
-import com.amd.aparapi.internal.exception.*;
-import com.amd.aparapi.internal.instruction.*;
-import com.amd.aparapi.internal.instruction.BranchSet.LogicalExpressionNode;
-import com.amd.aparapi.internal.instruction.InstructionSet.AccessInstanceField;
-import com.amd.aparapi.internal.instruction.BranchSet.*;
-import com.amd.aparapi.internal.instruction.InstructionSet.*;
-import com.amd.aparapi.internal.model.ClassModel.ConstantPool.*;
-import com.amd.aparapi.internal.model.ClassModel.*;
-import com.amd.aparapi.internal.model.*;
-import com.amd.aparapi.internal.model.ClassModel.ConstantPool.NameAndTypeEntry;
-
-import java.util.*;
-
-/**
- * Base abstract class for converting <code>Aparapi</code> IR to text.<br/>
- * 
- *   
- * @author gfrost
- *
- */
-
-public abstract class BlockWriter{
-
-   public final static String arrayLengthMangleSuffix = "__javaArrayLength";
-
-   public final static String arrayDimMangleSuffix = "__javaArrayDimension";
-
-   public abstract void write(String _string);
-
-   public void writeln(String _string) {
-      write(_string);
-      newLine();
-   }
-
-   public int indent = 0;
-
-   public void in() {
-      indent++;
-   }
-
-   public void out() {
-      indent--;
-   }
-
-   public void newLine() {
-      write("\n");
-      for (int i = 0; i < indent; i++) {
-         write("   ");
-      }
-   }
-
-   public void writeConditionalBranch16(ConditionalBranch16 _branch16, boolean _invert) throws CodeGenException {
-
-      if (_branch16 instanceof If) {
-         final If iff = (If) _branch16;
-
-         writeInstruction(iff.getLhs());
-         write(_branch16.getOperator().getText(_invert));
-         writeInstruction(iff.getRhs());
-      } else if (_branch16 instanceof I_IFNULL) {
-         final I_IFNULL iff = (I_IFNULL) _branch16;
-         writeInstruction(iff.getFirstChild());
-
-         if (_invert) {
-            write(" != NULL");
-         } else {
-            write(" == NULL");
-         }
-
-      } else if (_branch16 instanceof I_IFNONNULL) {
-         final I_IFNONNULL iff = (I_IFNONNULL) _branch16;
-         writeInstruction(iff.getFirstChild());
-
-         if (_invert) {
-            write(" == NULL");
-         } else {
-            write(" != NULL");
-         }
-      } else if (_branch16 instanceof IfUnary) {
-         final IfUnary branch16 = (IfUnary) _branch16;
-         final Instruction comparison = branch16.getUnary();
-         final ByteCode comparisonByteCode = comparison.getByteCode();
-         final String comparisonOperator = _branch16.getOperator().getText(_invert);
-
-         switch (comparisonByteCode) {
-            case FCMPG:
-            case DCMPG:
-            case FCMPL:
-            case DCMPL:
-               if (Config.verboseComparitor) {
-                  write("/* bytecode=" + comparisonByteCode.getName() + " invert=" + _invert + "*/");
-               }
-               writeInstruction(comparison.getFirstChild());
-               write(comparisonOperator);
-               writeInstruction(comparison.getLastChild());
-               break;
-            default:
-               if (Config.verboseComparitor) {
-                  write("/* default bytecode=" + comparisonByteCode.getName() + " invert=" + _invert + "*/");
-               }
-               writeInstruction(comparison);
-               write(comparisonOperator);
-               write("0");
-         }
-      }
-   }
-
-   public void writeComposite(CompositeInstruction instruction) throws CodeGenException {
-      if (instruction instanceof CompositeArbitraryScopeInstruction) {
-         newLine();
-
-         writeBlock(instruction.getFirstChild(), null);
-      } else if (instruction instanceof CompositeIfInstruction) {
-         newLine();
-         write("if (");
-         final Instruction blockStart = writeConditional(instruction.getBranchSet());
-
-         write(")");
-         writeBlock(blockStart, null);
-      } else if (instruction instanceof CompositeIfElseInstruction) {
-         newLine();
-         write("if (");
-         final Instruction blockStart = writeConditional(instruction.getBranchSet());
-         write(")");
-         Instruction elseGoto = blockStart;
-         while (!(elseGoto.isBranch() && elseGoto.asBranch().isUnconditional())) {
-            elseGoto = elseGoto.getNextExpr();
-         }
-         writeBlock(blockStart, elseGoto);
-         write(" else ");
-         writeBlock(elseGoto.getNextExpr(), null);
-      } else if (instruction instanceof CompositeForSunInstruction) {
-         newLine();
-         write("for (");
-         Instruction topBranch = instruction.getFirstChild();
-         if (topBranch instanceof AssignToLocalVariable) {
-            writeInstruction(topBranch);
-            topBranch = topBranch.getNextExpr();
-         }
-         write("; ");
-         final BranchSet branchSet = instruction.getBranchSet();
-         final Instruction blockStart = writeConditional(branchSet);
-
-         final Instruction lastGoto = instruction.getLastChild();
-
-         if (branchSet.getFallThrough() == lastGoto) {
-            // empty body no delta!
-            write(";){}");
-         } else {
-            final Instruction delta = lastGoto.getPrevExpr();
-            write("; ");
-            if (!(delta instanceof CompositeInstruction)) {
-               writeInstruction(delta);
-               write(")");
-               writeBlock(blockStart, delta);
-            } else {
-               write("){");
-               in();
-               writeSequence(blockStart, delta);
-
-               newLine();
-               writeSequence(delta, delta.getNextExpr());
-               out();
-               newLine();
-               write("}");
-
-            }
-         }
-
-      } else if (instruction instanceof CompositeWhileInstruction) {
-         newLine();
-         write("while (");
-         final BranchSet branchSet = instruction.getBranchSet();
-         final Instruction blockStart = writeConditional(branchSet);
-         write(")");
-         final Instruction lastGoto = instruction.getLastChild();
-         writeBlock(blockStart, lastGoto);
-
-      } else if (instruction instanceof CompositeEmptyLoopInstruction) {
-         newLine();
-         write("for (");
-         Instruction topBranch = instruction.getFirstChild();
-         if (topBranch instanceof AssignToLocalVariable) {
-            writeInstruction(topBranch);
-            topBranch = topBranch.getNextExpr();
-         }
-         write("; ");
-         writeConditional(instruction.getBranchSet());
-         write(";){}");
-
-      } else if (instruction instanceof CompositeForEclipseInstruction) {
-         newLine();
-         write("for (");
-         Instruction topGoto = instruction.getFirstChild();
-         if (topGoto instanceof AssignToLocalVariable) {
-            writeInstruction(topGoto);
-            topGoto = topGoto.getNextExpr();
-         }
-         write("; ");
-         Instruction last = instruction.getLastChild();
-         while (last.getPrevExpr().isBranch()) {
-            last = last.getPrevExpr();
-         }
-         writeConditional(instruction.getBranchSet(), true);
-         write("; ");
-         final Instruction delta = last.getPrevExpr();
-         if (!(delta instanceof CompositeInstruction)) {
-            writeInstruction(delta);
-            write(")");
-            writeBlock(topGoto.getNextExpr(), delta);
-         } else {
-            write("){");
-            in();
-            writeSequence(topGoto.getNextExpr(), delta);
-
-            newLine();
-            writeSequence(delta, delta.getNextExpr());
-            out();
-            newLine();
-            write("}");
-
-         }
-
-      } else if (instruction instanceof CompositeDoWhileInstruction) {
-         newLine();
-         write("do");
-         Instruction blockStart = instruction.getFirstChild();
-         Instruction blockEnd = instruction.getLastChild();
-         writeBlock(blockStart, blockEnd);
-         write("while(");
-         writeConditional(((CompositeInstruction) instruction).getBranchSet(), true);
-         write(");");
-         newLine();
-      }
-   }
-
-   public void writeSequence(Instruction _first, Instruction _last) throws CodeGenException {
-
-      for (Instruction instruction = _first; instruction != _last; instruction = instruction.getNextExpr()) {
-         if (instruction instanceof CompositeInstruction) {
-            writeComposite((CompositeInstruction) instruction);
-         } else if (!instruction.getByteCode().equals(ByteCode.NONE)) {
-            newLine();
-            writeInstruction(instruction);
-            write(";");
-
-         }
-      }
-
-   }
-
-   protected void writeGetterBlock(FieldEntry accessorVariableFieldEntry) {
-      write("{");
-      in();
-      newLine();
-      write("return this->");
-      write(accessorVariableFieldEntry.getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
-      write(";");
-      out();
-      newLine();
-
-      write("}");
-   }
-
-   public void writeBlock(Instruction _first, Instruction _last) throws CodeGenException {
-      write("{");
-      in();
-      writeSequence(_first, _last);
-      out();
-      newLine();
-
-      write("}");
-   }
-
-   public Instruction writeConditional(BranchSet _branchSet) throws CodeGenException {
-      return (writeConditional(_branchSet, false));
-   }
-
-   public Instruction writeConditional(BranchSet _branchSet, boolean _invert) throws CodeGenException {
-
-      final LogicalExpressionNode logicalExpression = _branchSet.getLogicalExpression();
-      write(_invert ? logicalExpression : logicalExpression.cloneInverted());
-      return (_branchSet.getLast().getNextExpr());
-   }
-
-   public void write(LogicalExpressionNode _node) throws CodeGenException {
-      if (_node instanceof SimpleLogicalExpressionNode) {
-         final SimpleLogicalExpressionNode sn = (SimpleLogicalExpressionNode) _node;
-
-         writeConditionalBranch16((ConditionalBranch16) sn.getBranch(), sn.isInvert());
-      } else {
-         final CompoundLogicalExpressionNode ln = (CompoundLogicalExpressionNode) _node;
-         boolean needParenthesis = false;
-         final CompoundLogicalExpressionNode parent = (CompoundLogicalExpressionNode) ln.getParent();
-         if (parent != null) {
-            if (!ln.isAnd() && parent.isAnd()) {
-               needParenthesis = true;
-            }
-         }
-         if (needParenthesis) {
-
-            write("(");
-         }
-         write(ln.getLhs());
-         write(ln.isAnd() ? " && " : " || ");
-         write(ln.getRhs());
-         if (needParenthesis) {
-
-            write(")");
-         }
-      }
-   }
-
-   public String convertType(String _typeDesc, boolean useClassModel) {
-      return (_typeDesc);
-   }
-
-   public String convertCast(String _cast) {
-      // Strip parens off cast
-      //System.out.println("cast = " + _cast);
-      final String raw = convertType(_cast.substring(1, _cast.length() - 1), false);
-      return ("(" + raw + ")");
-   }
-
-   public void writeInstruction(Instruction _instruction) throws CodeGenException {
-      if (_instruction instanceof CompositeIfElseInstruction) {
-         write("(");
-         final Instruction lhs = writeConditional(((CompositeInstruction) _instruction).getBranchSet());
-         write(")?");
-         writeInstruction(lhs);
-         write(":");
-         writeInstruction(lhs.getNextExpr().getNextExpr());
-      } else if (_instruction instanceof CompositeInstruction) {
-         writeComposite((CompositeInstruction) _instruction);
-
-      } else if (_instruction instanceof AssignToLocalVariable) {
-         final AssignToLocalVariable assignToLocalVariable = (AssignToLocalVariable) _instruction;
-
-         final LocalVariableInfo localVariableInfo = assignToLocalVariable.getLocalVariableInfo();
-         if (assignToLocalVariable.isDeclaration()) {
-            final String descriptor = localVariableInfo.getVariableDescriptor();
-            // Arrays always map to __global arrays
-            if (descriptor.startsWith("[")) {
-               write(" __global ");
-            }
-            write(convertType(descriptor, true));
-         }
-         if (localVariableInfo == null) {
-            throw new CodeGenException("outOfScope" + _instruction.getThisPC() + " = ");
-         } else {
-            write(localVariableInfo.getVariableName() + " = ");
-         }
-
-         for (Instruction operand = _instruction.getFirstChild(); operand != null; operand = operand.getNextExpr()) {
-            writeInstruction(operand);
-         }
-
-      } else if (_instruction instanceof AssignToArrayElement) {
-         final AssignToArrayElement arrayAssignmentInstruction = (AssignToArrayElement) _instruction;
-         writeInstruction(arrayAssignmentInstruction.getArrayRef());
-         write("[");
-         writeInstruction(arrayAssignmentInstruction.getArrayIndex());
-         write("]");
-         write(" ");
-         write(" = ");
-         writeInstruction(arrayAssignmentInstruction.getValue());
-      } else if (_instruction instanceof AccessArrayElement) {
-
-         //we're getting an element from an array
-         //if the array is a primitive then we just return the value
-         //so the generated code looks like
-         //arrayName[arrayIndex];
-         //but if the array is an object, or multidimensional array, then we want to return
-         //a pointer to our index our position in the array.  The code will look like
-         //&(arrayName[arrayIndex * this->arrayNameLen_dimension]
-         //
-         final AccessArrayElement arrayLoadInstruction = (AccessArrayElement) _instruction;
-
-         //object array, get address
-         boolean isMultiDimensional = arrayLoadInstruction instanceof I_AALOAD && isMultiDimensionalArray(arrayLoadInstruction);
-         if (isMultiDimensional) {
-            write("(&");
-         }
-         writeInstruction(arrayLoadInstruction.getArrayRef());
-         write("[");
-         writeInstruction(arrayLoadInstruction.getArrayIndex());
-
-         //object array, find the size of each object in the array
-         //for 2D arrays, this size is the size of a row.
-         if (isMultiDimensional) {
-            int dim = 0;
-            Instruction load = arrayLoadInstruction.getArrayRef();
-            while (load instanceof I_AALOAD) {
-               load = load.getFirstChild();
-               dim++;
-            }
-
-            NameAndTypeEntry nameAndTypeEntry = ((AccessInstanceField) load).getConstantPoolFieldEntry().getNameAndTypeEntry();
-            if (isMultiDimensionalArray(nameAndTypeEntry)) {
-               String arrayName = nameAndTypeEntry.getNameUTF8Entry().getUTF8();
-               write(" * this->" + arrayName + arrayDimMangleSuffix + dim);
-            }
-         }
-
-         write("]");
-
-         //object array, close parentheses
-         if (isMultiDimensional) {
-            write(")");
-         }
-      } else if (_instruction instanceof AccessField) {
-         final AccessField accessField = (AccessField) _instruction;
-         if (accessField instanceof AccessInstanceField) {
-            Instruction accessInstanceField = ((AccessInstanceField) accessField).getInstance();
-            if (accessInstanceField instanceof CloneInstruction) {
-               accessInstanceField = ((CloneInstruction) accessInstanceField).getReal();
-            }
-            if (!(accessInstanceField instanceof I_ALOAD_0)) {
-               writeInstruction(accessInstanceField);
-               write(".");
-            } else {
-               writeThisRef();
-            }
-         }
-         write(accessField.getConstantPoolFieldEntry().getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
-
-      } else if (_instruction instanceof I_ARRAYLENGTH) {
-
-         //getting the length of an array.
-         //if this is a primitive array, then this is trivial
-         //if we're getting an object array, then we need to find what dimension
-         //we're looking at
-         int dim = 0;
-         Instruction load = _instruction.getFirstChild();
-         while (load instanceof I_AALOAD) {
-            load = load.getFirstChild();
-            dim++;
-         }
-         NameAndTypeEntry nameAndTypeEntry = ((AccessInstanceField) load).getConstantPoolFieldEntry().getNameAndTypeEntry();
-         final String arrayName = nameAndTypeEntry.getNameUTF8Entry().getUTF8();
-         String dimSuffix = isMultiDimensionalArray(nameAndTypeEntry) ? Integer.toString(dim) : "";
-         write("this->" + arrayName + arrayLengthMangleSuffix + dimSuffix);
-      } else if (_instruction instanceof AssignToField) {
-         final AssignToField assignedField = (AssignToField) _instruction;
-
-         if (assignedField instanceof AssignToInstanceField) {
-            final Instruction accessInstanceField = ((AssignToInstanceField) assignedField).getInstance().getReal();
-
-            if (!(accessInstanceField instanceof I_ALOAD_0)) {
-               writeInstruction(accessInstanceField);
-               write(".");
-            } else {
-               writeThisRef();
-            }
-         }
-         write(assignedField.getConstantPoolFieldEntry().getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
-         write("=");
-         writeInstruction(assignedField.getValueToAssign());
-      } else if (_instruction instanceof Constant<?>) {
-         final Constant<?> constantInstruction = (Constant<?>) _instruction;
-         final Object value = constantInstruction.getValue();
-
-         if (value instanceof Float) {
-
-            final Float f = (Float) value;
-            if (f.isNaN()) {
-               write("NAN");
-            } else if (f.isInfinite()) {
-               if (f < 0) {
-                  write("-");
-               }
-               write("INFINITY");
-            } else {
-               write(value.toString());
-               write("f");
-            }
-         } else if (value instanceof Double) {
-
-            final Double d = (Double) value;
-            if (d.isNaN()) {
-               write("NAN");
-            } else if (d.isInfinite()) {
-               if (d < 0) {
-                  write("-");
-               }
-               write("INFINITY");
-            } else {
-               write(value.toString());
-            }
-         } else {
-            write(value.toString());
-            if (value instanceof Long) {
-               write("L");
-            }
-         }
-
-      } else if (_instruction instanceof AccessLocalVariable) {
-         final AccessLocalVariable localVariableLoadInstruction = (AccessLocalVariable) _instruction;
-         final LocalVariableInfo localVariable = localVariableLoadInstruction.getLocalVariableInfo();
-         write(localVariable.getVariableName());
-      } else if (_instruction instanceof I_IINC) {
-         final I_IINC location = (I_IINC) _instruction;
-         final LocalVariableInfo localVariable = location.getLocalVariableInfo();
-         final int adjust = location.getAdjust();
-
-         write(localVariable.getVariableName());
-         if (adjust == 1) {
-            write("++");
-         } else if (adjust == -1) {
-            write("--");
-         } else if (adjust > 1) {
-            write("+=" + adjust);
-         } else if (adjust < -1) {
-            write("-=" + (-adjust));
-         }
-      } else if (_instruction instanceof BinaryOperator) {
-         final BinaryOperator binaryInstruction = (BinaryOperator) _instruction;
-         final Instruction parent = binaryInstruction.getParentExpr();
-         boolean needsParenthesis = true;
-
-         if (parent instanceof AssignToLocalVariable) {
-            needsParenthesis = false;
-         } else if (parent instanceof AssignToField) {
-            needsParenthesis = false;
-         } else if (parent instanceof AssignToArrayElement) {
-            needsParenthesis = false;
-         } else {
-            /**
-                        if (parent instanceof BinaryOperator) {
-                           BinaryOperator parentBinaryOperator = (BinaryOperator) parent;
-                           if (parentBinaryOperator.getOperator().ordinal() > binaryInstruction.getOperator().ordinal()) {
-                              needsParenthesis = false;
-                           }
-                        }
-            **/
-         }
-
-         if (needsParenthesis) {
-            write("(");
-         }
-
-         writeInstruction(binaryInstruction.getLhs());
-
-         write(" " + binaryInstruction.getOperator().getText() + " ");
-         writeInstruction(binaryInstruction.getRhs());
-
-         if (needsParenthesis) {
-            write(")");
-         }
-
-      } else if (_instruction instanceof CastOperator) {
-         final CastOperator castInstruction = (CastOperator) _instruction;
-         //  write("(");
-         write(convertCast(castInstruction.getOperator().getText()));
-
-         writeInstruction(castInstruction.getUnary());
-         //    write(")");
-      } else if (_instruction instanceof UnaryOperator) {
-         final UnaryOperator unaryInstruction = (UnaryOperator) _instruction;
-         //   write("(");
-         write(unaryInstruction.getOperator().getText());
-
-         writeInstruction(unaryInstruction.getUnary());
-         //   write(")");
-      } else if (_instruction instanceof Return) {
-
-         final Return ret = (Return) _instruction;
-         write("return");
-         if (ret.getStackConsumeCount() > 0) {
-            write("(");
-            writeInstruction(ret.getFirstChild());
-            write(")");
-         }
-
-      } else if (_instruction instanceof MethodCall) {
-         final MethodCall methodCall = (MethodCall) _instruction;
-
-         final MethodEntry methodEntry = methodCall.getConstantPoolMethodEntry();
-
-         writeMethod(methodCall, methodEntry);
-      } else if (_instruction.getByteCode().equals(ByteCode.CLONE)) {
-         final CloneInstruction cloneInstruction = (CloneInstruction) _instruction;
-         writeInstruction(cloneInstruction.getReal());
-      } else if (_instruction.getByteCode().equals(ByteCode.INCREMENT)) {
-         final IncrementInstruction incrementInstruction = (IncrementInstruction) _instruction;
-
-         if (incrementInstruction.isPre()) {
-            if (incrementInstruction.isInc()) {
-               write("++");
-            } else {
-               write("--");
-            }
-         }
-
-         writeInstruction(incrementInstruction.getFieldOrVariableReference());
-         if (!incrementInstruction.isPre()) {
-            if (incrementInstruction.isInc()) {
-               write("++");
-            } else {
-               write("--");
-            }
-         }
-      } else if (_instruction.getByteCode().equals(ByteCode.MULTI_ASSIGN)) {
-         final MultiAssignInstruction multiAssignInstruction = (MultiAssignInstruction) _instruction;
-         AssignToLocalVariable from = (AssignToLocalVariable) multiAssignInstruction.getFrom();
-         final AssignToLocalVariable last = (AssignToLocalVariable) multiAssignInstruction.getTo();
-         final Instruction common = multiAssignInstruction.getCommon();
-         final Stack<AssignToLocalVariable> stack = new Stack<AssignToLocalVariable>();
-
-         while (from != last) {
-            stack.push(from);
-            from = (AssignToLocalVariable) ((Instruction) from).getNextExpr();
-         }
-
-         for (AssignToLocalVariable alv = stack.pop(); alv != null; alv = stack.size() > 0 ? stack.pop() : null) {
-
-            final LocalVariableInfo localVariableInfo = alv.getLocalVariableInfo();
-            if (alv.isDeclaration()) {
-               write(convertType(localVariableInfo.getVariableDescriptor(), true));
-            }
-            if (localVariableInfo == null) {
-               throw new CodeGenException("outOfScope" + _instruction.getThisPC() + " = ");
-            } else {
-               write(localVariableInfo.getVariableName() + " = ");
-            }
-
-         }
-         writeInstruction(common);
-      } else if (_instruction.getByteCode().equals(ByteCode.INLINE_ASSIGN)) {
-         final InlineAssignInstruction inlineAssignInstruction = (InlineAssignInstruction) _instruction;
-         final AssignToLocalVariable assignToLocalVariable = inlineAssignInstruction.getAssignToLocalVariable();
-
-         final LocalVariableInfo localVariableInfo = assignToLocalVariable.getLocalVariableInfo();
-         if (assignToLocalVariable.isDeclaration()) {
-            // this is bad! we need a general way to hoist up a required declaration
-            throw new CodeGenException("/* we can't declare this " + convertType(localVariableInfo.getVariableDescriptor(), true)
-                  + " here */");
-         }
-         write(localVariableInfo.getVariableName());
-         write("=");
-         writeInstruction(inlineAssignInstruction.getRhs());
-      } else if (_instruction.getByteCode().equals(ByteCode.FIELD_ARRAY_ELEMENT_ASSIGN)) {
-         final FieldArrayElementAssign inlineAssignInstruction = (FieldArrayElementAssign) _instruction;
-         final AssignToArrayElement arrayAssignmentInstruction = inlineAssignInstruction.getAssignToArrayElement();
-
-         writeInstruction(arrayAssignmentInstruction.getArrayRef());
-         write("[");
-         writeInstruction(arrayAssignmentInstruction.getArrayIndex());
-         write("]");
-         write(" ");
-         write(" = ");
-
-         writeInstruction(inlineAssignInstruction.getRhs());
-      } else if (_instruction.getByteCode().equals(ByteCode.FIELD_ARRAY_ELEMENT_INCREMENT)) {
-
-         final FieldArrayElementIncrement fieldArrayElementIncrement = (FieldArrayElementIncrement) _instruction;
-         final AssignToArrayElement arrayAssignmentInstruction = fieldArrayElementIncrement.getAssignToArrayElement();
-         if (fieldArrayElementIncrement.isPre()) {
-            if (fieldArrayElementIncrement.isInc()) {
-               write("++");
-            } else {
-               write("--");
-            }
-         }
-         writeInstruction(arrayAssignmentInstruction.getArrayRef());
-
-         write("[");
-         writeInstruction(arrayAssignmentInstruction.getArrayIndex());
-         write("]");
-         if (!fieldArrayElementIncrement.isPre()) {
-            if (fieldArrayElementIncrement.isInc()) {
-               write("++");
-            } else {
-               write("--");
-            }
-         }
-
-      } else if (_instruction.getByteCode().equals(ByteCode.NONE)) {
-         // we are done
-      } else if (_instruction instanceof Branch) {
-         throw new CodeGenException(String.format("%s -> %04d", _instruction.getByteCode().toString().toLowerCase(),
-               ((Branch) _instruction).getTarget().getThisPC()));
-      } else if (_instruction instanceof I_POP) {
-         //POP discarded void call return?
-         writeInstruction(_instruction.getFirstChild());
-      } else {
-         throw new CodeGenException(String.format("%s", _instruction.getByteCode().toString().toLowerCase()));
-      }
-
-   }
-
-   private boolean isMultiDimensionalArray(NameAndTypeEntry nameAndTypeEntry) {
-      return nameAndTypeEntry.getDescriptorUTF8Entry().getUTF8().startsWith("[[");
-   }
-
-   private boolean isObjectArray(NameAndTypeEntry nameAndTypeEntry) {
-      return nameAndTypeEntry.getDescriptorUTF8Entry().getUTF8().startsWith("[L");
-   }
-
-   private boolean isMultiDimensionalArray(final AccessArrayElement arrayLoadInstruction) {
-      AccessInstanceField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction);
-      return isMultiDimensionalArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry());
-   }
-
-   private boolean isObjectArray(final AccessArrayElement arrayLoadInstruction) {
-      AccessInstanceField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction);
-      return isObjectArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry());
-   }
-
-   private AccessInstanceField getUltimateInstanceFieldAccess(final AccessArrayElement arrayLoadInstruction) {
-      Instruction load = arrayLoadInstruction.getArrayRef();
-      while (load instanceof I_AALOAD) {
-         load = load.getFirstChild();
-      }
-
-      return (AccessInstanceField) load;
-   }
-
-   public void writeMethod(MethodCall _methodCall, MethodEntry _methodEntry) throws CodeGenException {
-      boolean noCL = _methodEntry.getOwnerClassModel().getNoCLMethods()
-            .contains(_methodEntry.getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
-      if (noCL) {
-         return;
-      }
-
-      if (_methodCall instanceof VirtualMethodCall) {
-         final Instruction instanceInstruction = ((VirtualMethodCall) _methodCall).getInstanceReference();
-         if (!(instanceInstruction instanceof I_ALOAD_0)) {
-            writeInstruction(instanceInstruction);
-            write(".");
-         } else {
-            writeThisRef();
-         }
-      }
-      final int argc = _methodEntry.getStackConsumeCount();
-      write(_methodEntry.getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
-      write("(");
-
-      for (int arg = 0; arg < argc; arg++) {
-         if (arg != 0) {
-            write(", ");
-         }
-         writeInstruction(_methodCall.getArg(arg));
-      }
-      write(")");
-
-   }
-
-   public void writeThisRef() {
-      write("this.");
-   }
-
-   public void writeMethodBody(MethodModel _methodModel) throws CodeGenException {
-      if (_methodModel.isGetter() && !_methodModel.isNoCL()) {
-         FieldEntry accessorVariableFieldEntry = _methodModel.getAccessorVariableFieldEntry();
-         writeGetterBlock(accessorVariableFieldEntry);
-      } else {
-         writeBlock(_methodModel.getExprHead(), null);
-      }
-   }
-
-   public abstract void write(Entrypoint entryPoint) throws CodeGenException;
-}
+/*
+Copyright (c) 2010-2011, Advanced Micro Devices, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
+following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following
+disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
+disclaimer in the documentation and/or other materials provided with the distribution.
+
+Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+If you use the software (in whole or in part), you shall adhere to all applicable U.S., European, and other export
+laws, including but not limited to the U.S. Export Administration Regulations ("EAR"), (15 C.F.R. Sections 730 through
+774), and E.U. Council Regulation (EC) No 1334/2000 of 22 June 2000.  Further, pursuant to Section 740.6 of the EAR,
+you hereby certify that, except pursuant to a license granted by the United States Department of Commerce Bureau of
+Industry and Security or as otherwise permitted pursuant to a License Exception under the U.S. Export Administration
+Regulations ("EAR"), you will not (1) export, re-export or release to a national of a country in Country Groups D:1,
+E:1 or E:2 any restricted technology, software, or source code you receive hereunder, or (2) export to Country Groups
+D:1, E:1 or E:2 the direct product of such technology or software, if such foreign produced direct product is subject
+to national security controls as identified on the Commerce Control List (currently found in Supplement 1 to Part 774
+of EAR).  For the most current Country Group listings, or for additional information about the EAR or your obligations
+under those regulations, please refer to the U.S. Bureau of Industry and Security's website at http://www.bis.doc.gov/.
+
+*/
+package com.amd.aparapi.internal.writer;
+
+import com.amd.aparapi.*;
+import com.amd.aparapi.internal.exception.*;
+import com.amd.aparapi.internal.instruction.*;
+import com.amd.aparapi.internal.instruction.BranchSet.LogicalExpressionNode;
+import com.amd.aparapi.internal.instruction.InstructionSet.AccessInstanceField;
+import com.amd.aparapi.internal.instruction.BranchSet.*;
+import com.amd.aparapi.internal.instruction.InstructionSet.*;
+import com.amd.aparapi.internal.model.ClassModel.ConstantPool.*;
+import com.amd.aparapi.internal.model.ClassModel.*;
+import com.amd.aparapi.internal.model.*;
+import com.amd.aparapi.internal.model.ClassModel.ConstantPool.NameAndTypeEntry;
+
+import java.util.*;
+
+/**
+ * Base abstract class for converting <code>Aparapi</code> IR to text.<br/>
+ *
+ *
+ * @author gfrost
+ *
+ */
+
+public abstract class BlockWriter{
+
+   public final static String arrayLengthMangleSuffix = "__javaArrayLength";
+
+   public final static String arrayDimMangleSuffix = "__javaArrayDimension";
+
+   public abstract void write(String _string);
+
+   public void writeln(String _string) {
+      write(_string);
+      newLine();
+   }
+
+   public int indent = 0;
+
+   public void in() {
+      indent++;
+   }
+
+   public void out() {
+      indent--;
+   }
+
+   public void newLine() {
+      write("\n");
+      for (int i = 0; i < indent; i++) {
+         write("   ");
+      }
+   }
+
+   public void writeConditionalBranch16(ConditionalBranch16 _branch16, boolean _invert) throws CodeGenException {
+
+      if (_branch16 instanceof If) {
+         final If iff = (If) _branch16;
+
+         writeInstruction(iff.getLhs());
+         write(_branch16.getOperator().getText(_invert));
+         writeInstruction(iff.getRhs());
+      } else if (_branch16 instanceof I_IFNULL) {
+         final I_IFNULL iff = (I_IFNULL) _branch16;
+         writeInstruction(iff.getFirstChild());
+
+         if (_invert) {
+            write(" != NULL");
+         } else {
+            write(" == NULL");
+         }
+
+      } else if (_branch16 instanceof I_IFNONNULL) {
+         final I_IFNONNULL iff = (I_IFNONNULL) _branch16;
+         writeInstruction(iff.getFirstChild());
+
+         if (_invert) {
+            write(" == NULL");
+         } else {
+            write(" != NULL");
+         }
+      } else if (_branch16 instanceof IfUnary) {
+         final IfUnary branch16 = (IfUnary) _branch16;
+         final Instruction comparison = branch16.getUnary();
+         final ByteCode comparisonByteCode = comparison.getByteCode();
+         final String comparisonOperator = _branch16.getOperator().getText(_invert);
+
+         switch (comparisonByteCode) {
+            case FCMPG:
+            case DCMPG:
+            case FCMPL:
+            case DCMPL:
+               if (Config.verboseComparitor) {
+                  write("/* bytecode=" + comparisonByteCode.getName() + " invert=" + _invert + "*/");
+               }
+               writeInstruction(comparison.getFirstChild());
+               write(comparisonOperator);
+               writeInstruction(comparison.getLastChild());
+               break;
+            default:
+               if (Config.verboseComparitor) {
+                  write("/* default bytecode=" + comparisonByteCode.getName() + " invert=" + _invert + "*/");
+               }
+               writeInstruction(comparison);
+               write(comparisonOperator);
+               write("0");
+         }
+      }
+   }
+
+   public void writeComposite(CompositeInstruction instruction) throws CodeGenException {
+      if (instruction instanceof CompositeArbitraryScopeInstruction) {
+         newLine();
+
+         writeBlock(instruction.getFirstChild(), null);
+      } else if (instruction instanceof CompositeIfInstruction) {
+         newLine();
+         write("if (");
+         final Instruction blockStart = writeConditional(instruction.getBranchSet());
+
+         write(")");
+         writeBlock(blockStart, null);
+      } else if (instruction instanceof CompositeIfElseInstruction) {
+         newLine();
+         write("if (");
+         final Instruction blockStart = writeConditional(instruction.getBranchSet());
+         write(")");
+         Instruction elseGoto = blockStart;
+         while (!(elseGoto.isBranch() && elseGoto.asBranch().isUnconditional())) {
+            elseGoto = elseGoto.getNextExpr();
+         }
+         writeBlock(blockStart, elseGoto);
+         write(" else ");
+         writeBlock(elseGoto.getNextExpr(), null);
+      } else if (instruction instanceof CompositeForSunInstruction) {
+         newLine();
+         write("for (");
+         Instruction topBranch = instruction.getFirstChild();
+         if (topBranch instanceof AssignToLocalVariable) {
+            writeInstruction(topBranch);
+            topBranch = topBranch.getNextExpr();
+         }
+         write("; ");
+         final BranchSet branchSet = instruction.getBranchSet();
+         final Instruction blockStart = writeConditional(branchSet);
+
+         final Instruction lastGoto = instruction.getLastChild();
+
+         if (branchSet.getFallThrough() == lastGoto) {
+            // empty body no delta!
+            write(";){}");
+         } else {
+            final Instruction delta = lastGoto.getPrevExpr();
+            write("; ");
+            if (!(delta instanceof CompositeInstruction)) {
+               writeInstruction(delta);
+               write(")");
+               writeBlock(blockStart, delta);
+            } else {
+               write("){");
+               in();
+               writeSequence(blockStart, delta);
+
+               newLine();
+               writeSequence(delta, delta.getNextExpr());
+               out();
+               newLine();
+               write("}");
+
+            }
+         }
+
+      } else if (instruction instanceof CompositeWhileInstruction) {
+         newLine();
+         write("while (");
+         final BranchSet branchSet = instruction.getBranchSet();
+         final Instruction blockStart = writeConditional(branchSet);
+         write(")");
+         final Instruction lastGoto = instruction.getLastChild();
+         writeBlock(blockStart, lastGoto);
+
+      } else if (instruction instanceof CompositeEmptyLoopInstruction) {
+         newLine();
+         write("for (");
+         Instruction topBranch = instruction.getFirstChild();
+         if (topBranch instanceof AssignToLocalVariable) {
+            writeInstruction(topBranch);
+            topBranch = topBranch.getNextExpr();
+         }
+         write("; ");
+         writeConditional(instruction.getBranchSet());
+         write(";){}");
+
+      } else if (instruction instanceof CompositeForEclipseInstruction) {
+         newLine();
+         write("for (");
+         Instruction topGoto = instruction.getFirstChild();
+         if (topGoto instanceof AssignToLocalVariable) {
+            writeInstruction(topGoto);
+            topGoto = topGoto.getNextExpr();
+         }
+         write("; ");
+         Instruction last = instruction.getLastChild();
+         while (last.getPrevExpr().isBranch()) {
+            last = last.getPrevExpr();
+         }
+         writeConditional(instruction.getBranchSet(), true);
+         write("; ");
+         final Instruction delta = last.getPrevExpr();
+         if (!(delta instanceof CompositeInstruction)) {
+            writeInstruction(delta);
+            write(")");
+            writeBlock(topGoto.getNextExpr(), delta);
+         } else {
+            write("){");
+            in();
+            writeSequence(topGoto.getNextExpr(), delta);
+
+            newLine();
+            writeSequence(delta, delta.getNextExpr());
+            out();
+            newLine();
+            write("}");
+
+         }
+
+      } else if (instruction instanceof CompositeDoWhileInstruction) {
+         newLine();
+         write("do");
+         Instruction blockStart = instruction.getFirstChild();
+         Instruction blockEnd = instruction.getLastChild();
+         writeBlock(blockStart, blockEnd);
+         write("while(");
+         writeConditional(((CompositeInstruction) instruction).getBranchSet(), true);
+         write(");");
+         newLine();
+      }
+   }
+
+   public void writeSequence(Instruction _first, Instruction _last) throws CodeGenException {
+
+      for (Instruction instruction = _first; instruction != _last; instruction = instruction.getNextExpr()) {
+         if (instruction instanceof CompositeInstruction) {
+            writeComposite((CompositeInstruction) instruction);
+         } else if (!instruction.getByteCode().equals(ByteCode.NONE)) {
+            newLine();
+            writeInstruction(instruction);
+            write(";");
+
+         }
+      }
+
+   }
+
+   protected void writeGetterBlock(FieldEntry accessorVariableFieldEntry) {
+      write("{");
+      in();
+      newLine();
+      write("return this->");
+      write(accessorVariableFieldEntry.getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
+      write(";");
+      out();
+      newLine();
+
+      write("}");
+   }
+
+   public void writeBlock(Instruction _first, Instruction _last) throws CodeGenException {
+      write("{");
+      in();
+      writeSequence(_first, _last);
+      out();
+      newLine();
+
+      write("}");
+   }
+
+   public Instruction writeConditional(BranchSet _branchSet) throws CodeGenException {
+      return (writeConditional(_branchSet, false));
+   }
+
+   public Instruction writeConditional(BranchSet _branchSet, boolean _invert) throws CodeGenException {
+
+      final LogicalExpressionNode logicalExpression = _branchSet.getLogicalExpression();
+      write(_invert ? logicalExpression : logicalExpression.cloneInverted());
+      return (_branchSet.getLast().getNextExpr());
+   }
+
+   public void write(LogicalExpressionNode _node) throws CodeGenException {
+      if (_node instanceof SimpleLogicalExpressionNode) {
+         final SimpleLogicalExpressionNode sn = (SimpleLogicalExpressionNode) _node;
+
+         writeConditionalBranch16((ConditionalBranch16) sn.getBranch(), sn.isInvert());
+      } else {
+         final CompoundLogicalExpressionNode ln = (CompoundLogicalExpressionNode) _node;
+         boolean needParenthesis = false;
+         final CompoundLogicalExpressionNode parent = (CompoundLogicalExpressionNode) ln.getParent();
+         if (parent != null) {
+            if (!ln.isAnd() && parent.isAnd()) {
+               needParenthesis = true;
+            }
+         }
+         if (needParenthesis) {
+
+            write("(");
+         }
+         write(ln.getLhs());
+         write(ln.isAnd() ? " && " : " || ");
+         write(ln.getRhs());
+         if (needParenthesis) {
+
+            write(")");
+         }
+      }
+   }
+
+   public String convertType(String _typeDesc, boolean useClassModel) {
+      return (_typeDesc);
+   }
+
+   public String convertCast(String _cast) {
+      // Strip parens off cast
+      //System.out.println("cast = " + _cast);
+      final String raw = convertType(_cast.substring(1, _cast.length() - 1), false);
+      return ("(" + raw + ")");
+   }
+
+   public void writeInstruction(Instruction _instruction) throws CodeGenException {
+      if (_instruction instanceof CompositeIfElseInstruction) {
+         write("(");
+         write("(");
+         final Instruction lhs = writeConditional(((CompositeInstruction) _instruction).getBranchSet());
+         write(")?");
+         writeInstruction(lhs);
+         write(":");
+         writeInstruction(lhs.getNextExpr().getNextExpr());
+         write(")");
+      } else if (_instruction instanceof CompositeInstruction) {
+         writeComposite((CompositeInstruction) _instruction);
+
+      } else if (_instruction instanceof AssignToLocalVariable) {
+         final AssignToLocalVariable assignToLocalVariable = (AssignToLocalVariable) _instruction;
+
+         final LocalVariableInfo localVariableInfo = assignToLocalVariable.getLocalVariableInfo();
+         if (assignToLocalVariable.isDeclaration()) {
+            final String descriptor = localVariableInfo.getVariableDescriptor();
+            // Arrays always map to __global arrays
+            if (descriptor.startsWith("[")) {
+               write(" __global ");
+            }
+            write(convertType(descriptor, true));
+         }
+         if (localVariableInfo == null) {
+            throw new CodeGenException("outOfScope" + _instruction.getThisPC() + " = ");
+         } else {
+            write(localVariableInfo.getVariableName() + " = ");
+         }
+
+         for (Instruction operand = _instruction.getFirstChild(); operand != null; operand = operand.getNextExpr()) {
+            writeInstruction(operand);
+         }
+
+      } else if (_instruction instanceof AssignToArrayElement) {
+         final AssignToArrayElement arrayAssignmentInstruction = (AssignToArrayElement) _instruction;
+         writeInstruction(arrayAssignmentInstruction.getArrayRef());
+         write("[");
+         writeInstruction(arrayAssignmentInstruction.getArrayIndex());
+         write("]");
+         write(" ");
+         write(" = ");
+         writeInstruction(arrayAssignmentInstruction.getValue());
+      } else if (_instruction instanceof AccessArrayElement) {
+
+         //we're getting an element from an array
+         //if the array is a primitive then we just return the value
+         //so the generated code looks like
+         //arrayName[arrayIndex];
+         //but if the array is an object, or multidimensional array, then we want to return
+         //a pointer to our index our position in the array.  The code will look like
+         //&(arrayName[arrayIndex * this->arrayNameLen_dimension]
+         //
+         final AccessArrayElement arrayLoadInstruction = (AccessArrayElement) _instruction;
+
+         //object array, get address
+         boolean isMultiDimensional = arrayLoadInstruction instanceof I_AALOAD && isMultiDimensionalArray(arrayLoadInstruction);
+         if (isMultiDimensional) {
+            write("(&");
+         }
+         writeInstruction(arrayLoadInstruction.getArrayRef());
+         write("[");
+         writeInstruction(arrayLoadInstruction.getArrayIndex());
+
+         //object array, find the size of each object in the array
+         //for 2D arrays, this size is the size of a row.
+         if (isMultiDimensional) {
+            int dim = 0;
+            Instruction load = arrayLoadInstruction.getArrayRef();
+            while (load instanceof I_AALOAD) {
+               load = load.getFirstChild();
+               dim++;
+            }
+
+            NameAndTypeEntry nameAndTypeEntry = ((AccessInstanceField) load).getConstantPoolFieldEntry().getNameAndTypeEntry();
+            if (isMultiDimensionalArray(nameAndTypeEntry)) {
+               String arrayName = nameAndTypeEntry.getNameUTF8Entry().getUTF8();
+               write(" * this->" + arrayName + arrayDimMangleSuffix + dim);
+            }
+         }
+
+         write("]");
+
+         //object array, close parentheses
+         if (isMultiDimensional) {
+            write(")");
+         }
+      } else if (_instruction instanceof AccessField) {
+         final AccessField accessField = (AccessField) _instruction;
+         if (accessField instanceof AccessInstanceField) {
+            Instruction accessInstanceField = ((AccessInstanceField) accessField).getInstance();
+            if (accessInstanceField instanceof CloneInstruction) {
+               accessInstanceField = ((CloneInstruction) accessInstanceField).getReal();
+            }
+            if (!(accessInstanceField instanceof I_ALOAD_0)) {
+               writeInstruction(accessInstanceField);
+               write(".");
+            } else {
+               writeThisRef();
+            }
+         }
+         write(accessField.getConstantPoolFieldEntry().getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
+
+      } else if (_instruction instanceof I_ARRAYLENGTH) {
+
+         //getting the length of an array.
+         //if this is a primitive array, then this is trivial
+         //if we're getting an object array, then we need to find what dimension
+         //we're looking at
+         int dim = 0;
+         Instruction load = _instruction.getFirstChild();
+         while (load instanceof I_AALOAD) {
+            load = load.getFirstChild();
+            dim++;
+         }
+         NameAndTypeEntry nameAndTypeEntry = ((AccessInstanceField) load).getConstantPoolFieldEntry().getNameAndTypeEntry();
+         final String arrayName = nameAndTypeEntry.getNameUTF8Entry().getUTF8();
+         String dimSuffix = isMultiDimensionalArray(nameAndTypeEntry) ? Integer.toString(dim) : "";
+         write("this->" + arrayName + arrayLengthMangleSuffix + dimSuffix);
+      } else if (_instruction instanceof AssignToField) {
+         final AssignToField assignedField = (AssignToField) _instruction;
+
+         if (assignedField instanceof AssignToInstanceField) {
+            final Instruction accessInstanceField = ((AssignToInstanceField) assignedField).getInstance().getReal();
+
+            if (!(accessInstanceField instanceof I_ALOAD_0)) {
+               writeInstruction(accessInstanceField);
+               write(".");
+            } else {
+               writeThisRef();
+            }
+         }
+         write(assignedField.getConstantPoolFieldEntry().getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
+         write("=");
+         writeInstruction(assignedField.getValueToAssign());
+      } else if (_instruction instanceof Constant<?>) {
+         final Constant<?> constantInstruction = (Constant<?>) _instruction;
+         final Object value = constantInstruction.getValue();
+
+         if (value instanceof Float) {
+
+            final Float f = (Float) value;
+            if (f.isNaN()) {
+               write("NAN");
+            } else if (f.isInfinite()) {
+               if (f < 0) {
+                  write("-");
+               }
+               write("INFINITY");
+            } else {
+               write(value.toString());
+               write("f");
+            }
+         } else if (value instanceof Double) {
+
+            final Double d = (Double) value;
+            if (d.isNaN()) {
+               write("NAN");
+            } else if (d.isInfinite()) {
+               if (d < 0) {
+                  write("-");
+               }
+               write("INFINITY");
+            } else {
+               write(value.toString());
+            }
+         } else {
+            write(value.toString());
+            if (value instanceof Long) {
+               write("L");
+            }
+         }
+
+      } else if (_instruction instanceof AccessLocalVariable) {
+         final AccessLocalVariable localVariableLoadInstruction = (AccessLocalVariable) _instruction;
+         final LocalVariableInfo localVariable = localVariableLoadInstruction.getLocalVariableInfo();
+         write(localVariable.getVariableName());
+      } else if (_instruction instanceof I_IINC) {
+         final I_IINC location = (I_IINC) _instruction;
+         final LocalVariableInfo localVariable = location.getLocalVariableInfo();
+         final int adjust = location.getAdjust();
+
+         write(localVariable.getVariableName());
+         if (adjust == 1) {
+            write("++");
+         } else if (adjust == -1) {
+            write("--");
+         } else if (adjust > 1) {
+            write("+=" + adjust);
+         } else if (adjust < -1) {
+            write("-=" + (-adjust));
+         }
+      } else if (_instruction instanceof BinaryOperator) {
+         final BinaryOperator binaryInstruction = (BinaryOperator) _instruction;
+         final Instruction parent = binaryInstruction.getParentExpr();
+         boolean needsParenthesis = true;
+
+         if (parent instanceof AssignToLocalVariable) {
+            needsParenthesis = false;
+         } else if (parent instanceof AssignToField) {
+            needsParenthesis = false;
+         } else if (parent instanceof AssignToArrayElement) {
+            needsParenthesis = false;
+         } else {
+            /**
+                        if (parent instanceof BinaryOperator) {
+                           BinaryOperator parentBinaryOperator = (BinaryOperator) parent;
+                           if (parentBinaryOperator.getOperator().ordinal() > binaryInstruction.getOperator().ordinal()) {
+                              needsParenthesis = false;
+                           }
+                        }
+            **/
+         }
+
+         if (needsParenthesis) {
+            write("(");
+         }
+
+         writeInstruction(binaryInstruction.getLhs());
+
+         write(" " + binaryInstruction.getOperator().getText() + " ");
+         writeInstruction(binaryInstruction.getRhs());
+
+         if (needsParenthesis) {
+            write(")");
+         }
+
+      } else if (_instruction instanceof CastOperator) {
+         final CastOperator castInstruction = (CastOperator) _instruction;
+         //  write("(");
+         write(convertCast(castInstruction.getOperator().getText()));
+
+         writeInstruction(castInstruction.getUnary());
+         //    write(")");
+      } else if (_instruction instanceof UnaryOperator) {
+         final UnaryOperator unaryInstruction = (UnaryOperator) _instruction;
+         //   write("(");
+         write(unaryInstruction.getOperator().getText());
+
+         writeInstruction(unaryInstruction.getUnary());
+         //   write(")");
+      } else if (_instruction instanceof Return) {
+
+         final Return ret = (Return) _instruction;
+         write("return");
+         if (ret.getStackConsumeCount() > 0) {
+            write("(");
+            writeInstruction(ret.getFirstChild());
+            write(")");
+         }
+
+      } else if (_instruction instanceof MethodCall) {
+         final MethodCall methodCall = (MethodCall) _instruction;
+
+         final MethodEntry methodEntry = methodCall.getConstantPoolMethodEntry();
+
+         writeMethod(methodCall, methodEntry);
+      } else if (_instruction.getByteCode().equals(ByteCode.CLONE)) {
+         final CloneInstruction cloneInstruction = (CloneInstruction) _instruction;
+         writeInstruction(cloneInstruction.getReal());
+      } else if (_instruction.getByteCode().equals(ByteCode.INCREMENT)) {
+         final IncrementInstruction incrementInstruction = (IncrementInstruction) _instruction;
+
+         if (incrementInstruction.isPre()) {
+            if (incrementInstruction.isInc()) {
+               write("++");
+            } else {
+               write("--");
+            }
+         }
+
+         writeInstruction(incrementInstruction.getFieldOrVariableReference());
+         if (!incrementInstruction.isPre()) {
+            if (incrementInstruction.isInc()) {
+               write("++");
+            } else {
+               write("--");
+            }
+         }
+      } else if (_instruction.getByteCode().equals(ByteCode.MULTI_ASSIGN)) {
+         final MultiAssignInstruction multiAssignInstruction = (MultiAssignInstruction) _instruction;
+         AssignToLocalVariable from = (AssignToLocalVariable) multiAssignInstruction.getFrom();
+         final AssignToLocalVariable last = (AssignToLocalVariable) multiAssignInstruction.getTo();
+         final Instruction common = multiAssignInstruction.getCommon();
+         final Stack<AssignToLocalVariable> stack = new Stack<AssignToLocalVariable>();
+
+         while (from != last) {
+            stack.push(from);
+            from = (AssignToLocalVariable) ((Instruction) from).getNextExpr();
+         }
+
+         for (AssignToLocalVariable alv = stack.pop(); alv != null; alv = stack.size() > 0 ? stack.pop() : null) {
+
+            final LocalVariableInfo localVariableInfo = alv.getLocalVariableInfo();
+            if (alv.isDeclaration()) {
+               write(convertType(localVariableInfo.getVariableDescriptor(), true));
+            }
+            if (localVariableInfo == null) {
+               throw new CodeGenException("outOfScope" + _instruction.getThisPC() + " = ");
+            } else {
+               write(localVariableInfo.getVariableName() + " = ");
+            }
+
+         }
+         writeInstruction(common);
+      } else if (_instruction.getByteCode().equals(ByteCode.INLINE_ASSIGN)) {
+         final InlineAssignInstruction inlineAssignInstruction = (InlineAssignInstruction) _instruction;
+         final AssignToLocalVariable assignToLocalVariable = inlineAssignInstruction.getAssignToLocalVariable();
+
+         final LocalVariableInfo localVariableInfo = assignToLocalVariable.getLocalVariableInfo();
+         if (assignToLocalVariable.isDeclaration()) {
+            // this is bad! we need a general way to hoist up a required declaration
+            throw new CodeGenException("/* we can't declare this " + convertType(localVariableInfo.getVariableDescriptor(), true)
+                  + " here */");
+         }
+         write(localVariableInfo.getVariableName());
+         write("=");
+         writeInstruction(inlineAssignInstruction.getRhs());
+      } else if (_instruction.getByteCode().equals(ByteCode.FIELD_ARRAY_ELEMENT_ASSIGN)) {
+         final FieldArrayElementAssign inlineAssignInstruction = (FieldArrayElementAssign) _instruction;
+         final AssignToArrayElement arrayAssignmentInstruction = inlineAssignInstruction.getAssignToArrayElement();
+
+         writeInstruction(arrayAssignmentInstruction.getArrayRef());
+         write("[");
+         writeInstruction(arrayAssignmentInstruction.getArrayIndex());
+         write("]");
+         write(" ");
+         write(" = ");
+
+         writeInstruction(inlineAssignInstruction.getRhs());
+      } else if (_instruction.getByteCode().equals(ByteCode.FIELD_ARRAY_ELEMENT_INCREMENT)) {
+
+         final FieldArrayElementIncrement fieldArrayElementIncrement = (FieldArrayElementIncrement) _instruction;
+         final AssignToArrayElement arrayAssignmentInstruction = fieldArrayElementIncrement.getAssignToArrayElement();
+         if (fieldArrayElementIncrement.isPre()) {
+            if (fieldArrayElementIncrement.isInc()) {
+               write("++");
+            } else {
+               write("--");
+            }
+         }
+         writeInstruction(arrayAssignmentInstruction.getArrayRef());
+
+         write("[");
+         writeInstruction(arrayAssignmentInstruction.getArrayIndex());
+         write("]");
+         if (!fieldArrayElementIncrement.isPre()) {
+            if (fieldArrayElementIncrement.isInc()) {
+               write("++");
+            } else {
+               write("--");
+            }
+         }
+
+      } else if (_instruction.getByteCode().equals(ByteCode.NONE)) {
+         // we are done
+      } else if (_instruction instanceof Branch) {
+         throw new CodeGenException(String.format("%s -> %04d", _instruction.getByteCode().toString().toLowerCase(),
+               ((Branch) _instruction).getTarget().getThisPC()));
+      } else if (_instruction instanceof I_POP) {
+         //POP discarded void call return?
+         writeInstruction(_instruction.getFirstChild());
+      } else {
+         throw new CodeGenException(String.format("%s", _instruction.getByteCode().toString().toLowerCase()));
+      }
+
+   }
+
+   private boolean isMultiDimensionalArray(NameAndTypeEntry nameAndTypeEntry) {
+      return nameAndTypeEntry.getDescriptorUTF8Entry().getUTF8().startsWith("[[");
+   }
+
+   private boolean isObjectArray(NameAndTypeEntry nameAndTypeEntry) {
+      return nameAndTypeEntry.getDescriptorUTF8Entry().getUTF8().startsWith("[L");
+   }
+
+   private boolean isMultiDimensionalArray(final AccessArrayElement arrayLoadInstruction) {
+      AccessInstanceField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction);
+      return isMultiDimensionalArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry());
+   }
+
+   private boolean isObjectArray(final AccessArrayElement arrayLoadInstruction) {
+      AccessInstanceField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction);
+      return isObjectArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry());
+   }
+
+   private AccessInstanceField getUltimateInstanceFieldAccess(final AccessArrayElement arrayLoadInstruction) {
+      Instruction load = arrayLoadInstruction.getArrayRef();
+      while (load instanceof I_AALOAD) {
+         load = load.getFirstChild();
+      }
+
+      return (AccessInstanceField) load;
+   }
+
+   public void writeMethod(MethodCall _methodCall, MethodEntry _methodEntry) throws CodeGenException {
+      boolean noCL = _methodEntry.getOwnerClassModel().getNoCLMethods()
+            .contains(_methodEntry.getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
+      if (noCL) {
+         return;
+      }
+
+      if (_methodCall instanceof VirtualMethodCall) {
+         final Instruction instanceInstruction = ((VirtualMethodCall) _methodCall).getInstanceReference();
+         if (!(instanceInstruction instanceof I_ALOAD_0)) {
+            writeInstruction(instanceInstruction);
+            write(".");
+         } else {
+            writeThisRef();
+         }
+      }
+      final int argc = _methodEntry.getStackConsumeCount();
+      write(_methodEntry.getNameAndTypeEntry().getNameUTF8Entry().getUTF8());
+      write("(");
+
+      for (int arg = 0; arg < argc; arg++) {
+         if (arg != 0) {
+            write(", ");
+         }
+         writeInstruction(_methodCall.getArg(arg));
+      }
+      write(")");
+
+   }
+
+   public void writeThisRef() {
+      write("this.");
+   }
+
+   public void writeMethodBody(MethodModel _methodModel) throws CodeGenException {
+      if (_methodModel.isGetter() && !_methodModel.isNoCL()) {
+         FieldEntry accessorVariableFieldEntry = _methodModel.getAccessorVariableFieldEntry();
+         writeGetterBlock(accessorVariableFieldEntry);
+      } else {
+         writeBlock(_methodModel.getExprHead(), null);
+      }
+   }
+
+   public abstract void write(Entrypoint entryPoint) throws CodeGenException;
+}