JL5LocalDecl ld = nf.JL5LocalDecl(position(), fl, nf.CanonicalTypeNode(position(), ts.Int()), "$arg0", nf.IntLit(position(), polyglot.ast.IntLit.INT, 0));
IntLit il = nf.IntLit(position(), polyglot.ast.IntLit.INT, 0); il = (IntLit)il.type(ts.Int()); JL5LocalDecl ld = nf.JL5LocalDecl(position(), fl, nf.CanonicalTypeNode(position(), ts.Int()), "$arg0", il);
    public Node simplify(SimplifyVisitor sv) throws SemanticException{        JL5TypeSystem ts = (JL5TypeSystem)sv.typeSystem();        JL5NodeFactory nf = (JL5NodeFactory)sv.nodeFactory();                Type t = expr.type();        if (t.isArray()){            JL5LocalDecl origLd = (JL5LocalDecl)varDecls.get(0);            FlagAnnotations fl = new FlagAnnotations();            fl.classicFlags(origLd.flags());            fl.annotations(origLd.annotations());            JL5LocalDecl ld = nf.JL5LocalDecl(position(), fl, nf.CanonicalTypeNode(position(), ts.Int()), "$arg0", nf.IntLit(position(), polyglot.ast.IntLit.INT, 0));            LocalInstance li = ts.localInstance(position(), Flags.NONE, ts.Int(), "$arg0");            ld = (JL5LocalDecl)ld.localInstance(li);            Local local = nf.Local(position(), "$arg0");            local = local.localInstance(li);            JL5Field field = nf.JL5Field(position(), expr, "length");            FieldInstance fi = ts.fieldInstance(position(), t.toReference(), Flags.NONE, ts.Int(), "length");            field = (JL5Field)field.fieldInstance(fi);            Binary cond = nf.Binary(position(), local, polyglot.ast.Binary.LT, field);            cond = (Binary)cond.type(ts.Boolean());            Unary iter = nf.Unary(position(), polyglot.ast.Unary.POST_INC, local);            List iters = new ArrayList();            iters.add(nf.Eval(position(), iter));                        ArrayAccess aa = nf.ArrayAccess(position(), expr, local);            aa = (ArrayAccess)aa.type(expr.type());            Local orig = nf.Local(position(), origLd.name());            orig = orig.localInstance(origLd.localInstance());                        LocalAssign la = nf.LocalAssign(position(), orig, Assign.ASSIGN, aa);            Block b = null;            if (body() instanceof Block){                b = ((Block)body()).prepend(nf.Eval(position(), la)).prepend(origLd);            }            else {                b = nf.Block(position()).prepend(body()).prepend(nf.Eval(position(), la)).prepend(origLd);            }                       ArrayList inits = new ArrayList();            inits.add(ld);            return nf.For(position(), inits, cond, iters, b);        }        else if (ts.isSubtype(t, ts.Iterable())){            JL5LocalDecl origLd = (JL5LocalDecl)varDecls.get(0);            FlagAnnotations fl = new FlagAnnotations();            fl.classicFlags(origLd.flags());            fl.annotations(origLd.annotations());                        JL5Call initCall = (JL5Call)nf.JL5Call(position(), expr, "iterator", new ArrayList(), new ArrayList());            initCall = (JL5Call)initCall.type(ts.Iterator());            initCall = (JL5Call)initCall.methodInstance(ts.methodInstance(position(), expr.type().toReference(), Flags.NONE, ts.Iterator(), "iterator", new ArrayList(), new ArrayList()));            JL5LocalDecl ld = nf.JL5LocalDecl(position(), fl, nf.CanonicalTypeNode(position(), ts.Iterator()), "$arg0", initCall);            LocalInstance li = ts.localInstance(position(), Flags.NONE, ts.Iterator(), "$arg0");            ld = (JL5LocalDecl)ld.localInstance(li);            Local local = nf.Local(position(), "$arg0");            local = local.localInstance(li);                        JL5Call condCall = (JL5Call)nf.JL5Call(position(), local, "hasNext", new ArrayList(), new ArrayList());            condCall = (JL5Call)condCall.type(ts.Boolean());            condCall = (JL5Call)condCall.methodInstance(ts.methodInstance(position(), ts.Iterator(), Flags.NONE, ts.Boolean(), "hasNext", new ArrayList(), new ArrayList()));                        JL5Call resultCall = (JL5Call)nf.JL5Call(position(), local, "next", new ArrayList(), new ArrayList());            resultCall = (JL5Call)resultCall.type(ts.Object());            resultCall = (JL5Call)resultCall.methodInstance(ts.methodInstance(position(), ts.Iterator(), Flags.NONE, ts.Object(), "next", new ArrayList(),new ArrayList()));                        Expr assignExpr = resultCall;                        Local orig = nf.Local(position(), origLd.name());            orig = orig.localInstance(origLd.localInstance());                        if (!ts.equals(orig.localInstance().type(), ts.Object())){                Cast cast = nf.Cast(position(), nf.CanonicalTypeNode(position(), orig.localInstance().type()), resultCall);                cast = (Cast)cast.type(orig.localInstance().type());                assignExpr = cast;            }            LocalAssign la = nf.LocalAssign(position(), orig, Assign.ASSIGN, assignExpr);            Block b = null;            if (body() instanceof Block){                b = ((Block)body()).prepend(nf.Eval(position(), la)).prepend(origLd);            }            else {                b = nf.Block(position()).prepend(body()).prepend(nf.Eval(position(), la)).prepend(origLd);            }                       ArrayList inits = new ArrayList();            inits.add(ld);                        return nf.For(position(), inits, condCall, new ArrayList(), b);        }        return this;    }