private PsiType inferIteratorType(
      GroovyResolveResult iteratorMethodResult, GrExpression tupleInitializer) {
    PsiElement method = iteratorMethodResult.getElement();
    if (method instanceof PsiMethod) {
      return iteratorMethodResult.getSubstitutor().substitute(((PsiMethod) method).getReturnType());
    } else {
      PsiType initializerType = tupleInitializer.getType();
      PsiType iterableParam = PsiUtil.extractIterableTypeParameter(initializerType, false);

      JavaPsiFacade facade = JavaPsiFacade.getInstance(context.project);
      PsiClass iterableClass =
          facade.findClass(CommonClassNames.JAVA_UTIL_ITERATOR, tupleInitializer.getResolveScope());
      if (iterableClass != null && iterableParam != null) {
        return facade.getElementFactory().createType(iterableClass, iterableParam);
      } else {
        return facade
            .getElementFactory()
            .createTypeFromText(CommonClassNames.JAVA_UTIL_ITERATOR, tupleInitializer);
      }
    }
  }
 public ControlFlowBuilder(Project project, GrControlFlowPolicy policy) {
   myPolicy = policy;
   myConstantEvaluator = JavaPsiFacade.getInstance(project).getConstantEvaluationHelper();
 }
  @Nullable
  private static GrExpression createDefaultValue(
      GroovyPsiElementFactory factory,
      JavaChangeInfo changeInfo,
      JavaParameterInfo info,
      final GrArgumentList list) {
    if (info.isUseAnySingleVariable()) {
      final PsiResolveHelper resolveHelper =
          JavaPsiFacade.getInstance(list.getProject()).getResolveHelper();
      final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager());
      final VariablesProcessor processor =
          new VariablesProcessor(false) {
            @Override
            protected boolean check(PsiVariable var, ResolveState state) {
              if (var instanceof PsiField
                  && !resolveHelper.isAccessible((PsiField) var, list, null)) return false;
              if (var instanceof GrVariable
                  && PsiUtil.isLocalVariable(var)
                  && list.getTextRange().getStartOffset() <= var.getTextRange().getStartOffset()) {
                return false;
              }
              if (PsiTreeUtil.isAncestor(var, list, false)) return false;
              final PsiType _type =
                  var instanceof GrVariable ? ((GrVariable) var).getTypeGroovy() : var.getType();
              final PsiType varType = state.get(PsiSubstitutor.KEY).substitute(_type);
              return type.isAssignableFrom(varType);
            }

            @Override
            public boolean execute(@NotNull PsiElement pe, @NotNull ResolveState state) {
              super.execute(pe, state);
              return size() < 2;
            }
          };
      ResolveUtil.treeWalkUp(list, processor, false);
      if (processor.size() == 1) {
        final PsiVariable result = processor.getResult(0);
        return factory.createExpressionFromText(result.getName(), list);
      }
      if (processor.size() == 0) {
        final PsiClass parentClass = PsiTreeUtil.getParentOfType(list, PsiClass.class);
        if (parentClass != null) {
          PsiClass containingClass = parentClass;
          final Set<PsiClass> containingClasses = new HashSet<PsiClass>();
          final PsiElementFactory jfactory = JavaPsiFacade.getElementFactory(list.getProject());
          while (containingClass != null) {
            if (type.isAssignableFrom(jfactory.createType(containingClass, PsiSubstitutor.EMPTY))) {
              containingClasses.add(containingClass);
            }
            containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
          }
          if (containingClasses.size() == 1) {
            return factory.createThisExpression(
                containingClasses.contains(parentClass)
                    ? null
                    : containingClasses.iterator().next());
          }
        }
      }
    }

    final String value = info.getDefaultValue();
    return !StringUtil.isEmpty(value) ? factory.createExpressionFromText(value, list) : null;
  }