    public void visitForExpression(final JFXForExpression tree) {
        result = (new Translator( tree.pos(), toJava ) {
            private final TypeMorphInfo tmiResult = typeMorpher.typeMorphInfo(targetType(tree.type));
            private final Type resultElementType = tmiResult.getElementType();
            private final Type resultSequenceLocationType = typeMorpher.generifyIfNeeded(typeMorpher.locationType(TYPE_KIND_SEQUENCE), tmiResult);
            private final boolean isSimple = false;  
            private JCExpression makeResultClass() {
                return makeTypeInfo(diagPos, resultElementType);
            }
            private JCVariableDecl makeParam(Type type, Name name) {
                return make.at(diagPos).VarDef(
                        make.Modifiers(Flags.PARAMETER | Flags.FINAL),
                        name,
                        makeExpression(type),
                        null);
            }
            private JCExpression makeCore() {
                JCExpression body = translate(tree.getBodyExpression());
                if (!types.isSequence(tree.getBodyExpression().type)) {
                    List<JCExpression> args = List.of(makeResultClass(), body);
                    body = runtime(diagPos, cBoundSequences, "singleton", args);
                }
                JCExpression whereTest = null;
                for (JFXForExpressionInClause clause : tree.getForExpressionInClauses()) {
                    JCExpression where = translate(clause.getWhereExpression());
                    if (where != null) {
                        if (whereTest == null) {
                            whereTest = where;
                        } else {
                            whereTest = runtime(diagPos, cBoundOperators, "and_bb", List.of(whereTest, where));
                        }
                    }
                }
                if (whereTest != null) {
                    body = makeBoundConditional(diagPos,
                            tree.type,
                            body,
                            runtime(diagPos, cBoundSequences, "empty", List.of(makeTypeInfo(diagPos, resultElementType))),
                            whereTest);
                }
                return body;
            }
            private JCTree makeComputeElementsMethod(JFXForExpressionInClause clause, JCExpression inner, TypeMorphInfo tmiInduction) {
                Type iVarType;
                Type idxVarType;
                Name computeName;
                if  (isSimple) {
                   iVarType = tmiInduction.getRealFXType();
                   idxVarType = syms.intType;
                   computeName = computeElementsName;
                } else {
                   iVarType = tmiInduction.getLocationType();
                   idxVarType = typeMorpher.locationType(TYPE_KIND_INT);
                   computeName = computeElementsName;
                }
                ListBuffer<JCStatement> stmts = ListBuffer.lb();
                Name ivarName = clause.getVar().name;
                stmts.append(m().Return( inner ));
                List<JCVariableDecl> params = List.of(
                        makeParam(iVarType, ivarName),
                        makeParam(idxVarType, indexVarName(clause) )
                        );
                return m().MethodDef(
                        m().Modifiers(Flags.PROTECTED),
                        computeName,
                        makeExpression( resultSequenceLocationType ),
                        List.<JCTypeParameter>nil(),
                        params,
                        List.<JCExpression>nil(),
                        m().Block(0L, stmts.toList()),
                        null);
            }
            private JCExpression makeBoundComprehension(JFXForExpressionInClause clause, JCExpression inner) {
                JFXExpression seq = clause.getSequenceExpression();
                TypeMorphInfo tmiSeq = typeMorpher.typeMorphInfo(seq.type);
                TypeMorphInfo tmiInduction = typeMorpher.typeMorphInfo(clause.getVar().type);
                Type elementType = tmiSeq.getElementType();
                JCClassDecl classDecl = m().AnonymousClassDef(
                        m().Modifiers(0L),
                        List.<JCTree>of(makeComputeElementsMethod(clause, inner, tmiInduction)));
                List<JCExpression> typeArgs = List.nil();
                boolean useIndex = clause.getIndexUsed();
                JCExpression transSeq = translate( seq );
                if (!tmiSeq.isSequence()) {
                    transSeq = runtime(diagPos, cBoundSequences, "singleton", List.of(makeResultClass(), transSeq));
                }
                List<JCExpression> constructorArgs = List.of(
                        makeResultClass(),
                        transSeq,
                        m().Literal(TypeTags.BOOLEAN, useIndex? 1 : 0) );
                int typeKind = tmiInduction.getTypeKind();
                Type bcType = typeMorpher.boundComprehensionNCT[typeKind].type;
                JCExpression clazz = makeExpression(types.erasure(bcType));  
                ListBuffer<JCExpression> typeParams = ListBuffer.lb();
                if (typeKind == TYPE_KIND_OBJECT) {
                    typeParams.append( makeExpression(elementType) );
                }
                typeParams.append( makeExpression(resultElementType) );
                clazz = m().TypeApply(clazz, typeParams.toList());
                return m().NewClass(null,
                        typeArgs,
                        clazz,
                        constructorArgs,
                        classDecl);
            }
            public JCExpression doit() {
                List<JFXForExpressionInClause> clauses = tree.getForExpressionInClauses();
                JCExpression expr = makeCore();
                for (int inx = clauses.size() - 1; inx >= 0; --inx) {
                    JFXForExpressionInClause clause = clauses.get(inx);
                    expr = makeBoundComprehension(clause, expr);
                }
                return expr;
            }
        }).doit();
    }

    public void visitForExpression(final JFXForExpression tree) {
        result = (new Translator( tree.pos(), toJava ) {
            private final TypeMorphInfo tmiResult = typeMorpher.typeMorphInfo(targetType(tree.type));
            private final Type resultElementType = tmiResult.getElementType();
            private final Type resultSequenceLocationType = typeMorpher.generifyIfNeeded(typeMorpher.locationType(TYPE_KIND_SEQUENCE), tmiResult);
            private final boolean isSimple = false;  
            private JCExpression makeResultClass() {
                return makeTypeInfo(diagPos, resultElementType);
            }
            private JCVariableDecl makeParam(Type type, Name name) {
                return make.at(diagPos).VarDef(
                        make.Modifiers(Flags.PARAMETER | Flags.FINAL),
                        name,
                        makeExpression(type),
                        null);
            }
            private JCExpression makeCore() {
                JCExpression body;
                if (types.isSequence(tree.getBodyExpression().type)) {
                    body = translate(tree.getBodyExpression(), tmiTarget);
                } else {
                    JCExpression single = translate(tree.getBodyExpression(), tmiTarget.getElementType());
                    List<JCExpression> args = List.of(makeResultClass(), single);
                    body = runtime(diagPos, cBoundSequences, "singleton", args);
                }
                JCExpression whereTest = null;
                for (JFXForExpressionInClause clause : tree.getForExpressionInClauses()) {
                    JCExpression where = translate(clause.getWhereExpression());
                    if (where != null) {
                        if (whereTest == null) {
                            whereTest = where;
                        } else {
                            whereTest = runtime(diagPos, cBoundOperators, "and_bb", List.of(whereTest, where));
                        }
                    }
                }
                if (whereTest != null) {
                    body = makeBoundConditional(diagPos,
                            tree.type,
                            body,
                            runtime(diagPos, cBoundSequences, "empty", List.of(makeTypeInfo(diagPos, resultElementType))),
                            whereTest);
                }
                return body;
            }
            private JCTree makeComputeElementsMethod(JFXForExpressionInClause clause, JCExpression inner, TypeMorphInfo tmiInduction) {
                Type iVarType;
                Type idxVarType;
                Name computeName;
                if  (isSimple) {
                   iVarType = tmiInduction.getRealFXType();
                   idxVarType = syms.intType;
                   computeName = computeElementsName;
                } else {
                   iVarType = tmiInduction.getLocationType();
                   idxVarType = typeMorpher.locationType(TYPE_KIND_INT);
                   computeName = computeElementsName;
                }
                ListBuffer<JCStatement> stmts = ListBuffer.lb();
                Name ivarName = clause.getVar().name;
                stmts.append(m().Return( inner ));
                List<JCVariableDecl> params = List.of(
                        makeParam(iVarType, ivarName),
                        makeParam(idxVarType, indexVarName(clause) )
                        );
                return m().MethodDef(
                        m().Modifiers(Flags.PROTECTED),
                        computeName,
                        makeExpression( resultSequenceLocationType ),
                        List.<JCTypeParameter>nil(),
                        params,
                        List.<JCExpression>nil(),
                        m().Block(0L, stmts.toList()),
                        null);
            }
            private JCExpression makeBoundComprehension(JFXForExpressionInClause clause, JCExpression inner) {
                JFXExpression seq = clause.getSequenceExpression();
                TypeMorphInfo tmiSeq = typeMorpher.typeMorphInfo(seq.type);
                TypeMorphInfo tmiInduction = typeMorpher.typeMorphInfo(clause.getVar().type);
                Type elementType = tmiSeq.getElementType();
                JCClassDecl classDecl = m().AnonymousClassDef(
                        m().Modifiers(0L),
                        List.<JCTree>of(makeComputeElementsMethod(clause, inner, tmiInduction)));
                List<JCExpression> typeArgs = List.nil();
                boolean useIndex = clause.getIndexUsed();
                JCExpression transSeq = translate( seq );
                if (!tmiSeq.isSequence()) {
                    transSeq = runtime(diagPos, cBoundSequences, "singleton", List.of(makeResultClass(), transSeq));
                }
                List<JCExpression> constructorArgs = List.of(
                        makeResultClass(),
                        transSeq,
                        m().Literal(TypeTags.BOOLEAN, useIndex? 1 : 0) );
                int typeKind = tmiInduction.getTypeKind();
                Type bcType = typeMorpher.boundComprehensionNCT[typeKind].type;
                JCExpression clazz = makeExpression(types.erasure(bcType));  
                ListBuffer<JCExpression> typeParams = ListBuffer.lb();
                if (typeKind == TYPE_KIND_OBJECT) {
                    typeParams.append( makeExpression(elementType) );
                }
                typeParams.append( makeExpression(resultElementType) );
                clazz = m().TypeApply(clazz, typeParams.toList());
                return m().NewClass(null,
                        typeArgs,
                        clazz,
                        constructorArgs,
                        classDecl);
            }
            public JCExpression doit() {
                List<JFXForExpressionInClause> clauses = tree.getForExpressionInClauses();
                JCExpression expr = makeCore();
                for (int inx = clauses.size() - 1; inx >= 0; --inx) {
                    JFXForExpressionInClause clause = clauses.get(inx);
                    expr = makeBoundComprehension(clause, expr);
                }
                return expr;
            }
        }).doit();
    }
