@Override
  protected Statement convert(
      CompilationUnitRewrite cuRewrite, TextEditGroup group, LinkedProposalModel positionGroups)
      throws CoreException {
    ASTRewrite rewrite = cuRewrite.getASTRewrite();
    ImportRewrite importRewrite = cuRewrite.getImportRewrite();

    ForStatement forStatement = getForStatement();

    IJavaProject javaProject =
        ((CompilationUnit) forStatement.getRoot()).getJavaElement().getJavaProject();
    String[] proposals = getVariableNameProposals(fArrayAccess.resolveTypeBinding(), javaProject);

    String parameterName;
    if (fElementDeclaration != null) {
      parameterName = fElementDeclaration.getName().getIdentifier();
    } else {
      parameterName = proposals[0];
    }

    LinkedProposalPositionGroup pg = positionGroups.getPositionGroup(parameterName, true);
    if (fElementDeclaration != null) pg.addProposal(parameterName, null, 10);
    for (int i = 0; i < proposals.length; i++) {
      pg.addProposal(proposals[i], null, 10);
    }

    AST ast = forStatement.getAST();
    EnhancedForStatement result = ast.newEnhancedForStatement();

    SingleVariableDeclaration parameterDeclaration =
        createParameterDeclaration(
            parameterName,
            fElementDeclaration,
            fArrayAccess,
            forStatement,
            importRewrite,
            rewrite,
            group,
            pg,
            fMakeFinal);
    result.setParameter(parameterDeclaration);

    result.setExpression((Expression) rewrite.createCopyTarget(fArrayAccess));

    convertBody(
        forStatement.getBody(), fIndexBinding, fArrayBinding, parameterName, rewrite, group, pg);
    result.setBody(getBody(cuRewrite, group, positionGroups));

    positionGroups.setEndPosition(rewrite.track(result));

    return result;
  }
    /** {@inheritDoc} */
    public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel positionGroups)
        throws CoreException {
      InferTypeArgumentsTCModel model = new InferTypeArgumentsTCModel();
      InferTypeArgumentsConstraintCreator creator =
          new InferTypeArgumentsConstraintCreator(model, true);

      CompilationUnit root = cuRewrite.getRoot();
      root.accept(creator);

      InferTypeArgumentsConstraintsSolver solver = new InferTypeArgumentsConstraintsSolver(model);
      InferTypeArgumentsUpdate update = solver.solveConstraints(new NullProgressMonitor());
      solver = null; // free caches

      ASTNode[] nodes =
          InferTypeArgumentsRefactoring.inferArguments(fTypes, update, model, cuRewrite);
      if (nodes.length == 0) return;

      ASTRewrite astRewrite = cuRewrite.getASTRewrite();
      for (int i = 0; i < nodes.length; i++) {
        if (nodes[i] instanceof ParameterizedType) {
          ParameterizedType type = (ParameterizedType) nodes[0];
          List args = (List) type.getStructuralProperty(ParameterizedType.TYPE_ARGUMENTS_PROPERTY);
          int j = 0;
          for (Iterator iter = args.iterator(); iter.hasNext(); ) {
            LinkedProposalPositionGroup group =
                new LinkedProposalPositionGroup("G" + i + "_" + j); // $NON-NLS-1$ //$NON-NLS-2$
            Type argType = (Type) iter.next();
            if (!positionGroups.hasLinkedPositions()) {
              group.addPosition(astRewrite.track(argType), true);
            } else {
              group.addPosition(astRewrite.track(argType), false);
            }
            positionGroups.addPositionGroup(group);
            j++;
          }
        }
      }
      positionGroups.setEndPosition(astRewrite.track(nodes[0]));
    }
  private SingleVariableDeclaration createParameterDeclaration(
      String parameterName,
      VariableDeclarationFragment fragement,
      Expression arrayAccess,
      ForStatement statement,
      ImportRewrite importRewrite,
      ASTRewrite rewrite,
      TextEditGroup group,
      LinkedProposalPositionGroup pg,
      boolean makeFinal) {
    CompilationUnit compilationUnit = (CompilationUnit) arrayAccess.getRoot();
    AST ast = compilationUnit.getAST();

    SingleVariableDeclaration result = ast.newSingleVariableDeclaration();

    SimpleName name = ast.newSimpleName(parameterName);
    pg.addPosition(rewrite.track(name), true);
    result.setName(name);

    ITypeBinding arrayTypeBinding = arrayAccess.resolveTypeBinding();
    Type type =
        importType(arrayTypeBinding.getElementType(), statement, importRewrite, compilationUnit);
    if (arrayTypeBinding.getDimensions() != 1) {
      type = ast.newArrayType(type, arrayTypeBinding.getDimensions() - 1);
    }
    result.setType(type);

    if (fragement != null) {
      VariableDeclarationStatement declaration =
          (VariableDeclarationStatement) fragement.getParent();
      ModifierRewrite.create(rewrite, result).copyAllModifiers(declaration, group);
    }
    if (makeFinal
        && (fragement == null
            || ASTNodes.findModifierNode(Modifier.FINAL, ASTNodes.getModifiers(fragement))
                == null)) {
      ModifierRewrite.create(rewrite, result).setModifiers(Modifier.FINAL, 0, group);
    }

    return result;
  }