public void setType(@Nullable PsiType type) {
    final GrTypeElement typeElement = getTypeElementGroovy();
    if (type == null) {
      if (typeElement == null) return;
      if (getModifierList().getModifiers().length == 0) {
        getModifierList().setModifierProperty(GrModifier.DEF, true);
      }
      typeElement.delete();
      return;
    }

    type = TypesUtil.unboxPrimitiveTypeWrapper(type);
    GrTypeElement newTypeElement;
    try {
      newTypeElement = GroovyPsiElementFactory.getInstance(getProject()).createTypeElement(type);
    } catch (IncorrectOperationException e) {
      LOG.error(e);
      return;
    }

    if (typeElement == null) {
      getModifierList().setModifierProperty(GrModifier.DEF, false);
      final GrVariable[] variables = getVariables();
      if (variables.length == 0) return;
      newTypeElement = (GrTypeElement) addBefore(newTypeElement, variables[0]);
    } else {
      newTypeElement = (GrTypeElement) typeElement.replace(newTypeElement);
    }

    JavaCodeStyleManager.getInstance(getProject()).shortenClassReferences(newTypeElement);
  }
  private void createNameAndReturnTypeEditors() {
    myNameCodeFragment = new GroovyCodeFragment(myProject, "");
    myNameField =
        new EditorTextField(
            PsiDocumentManager.getInstance(myProject).getDocument(myNameCodeFragment),
            myProject,
            myNameCodeFragment.getFileType());

    final JavaCodeFragmentFactory factory = JavaCodeFragmentFactory.getInstance(myProject);
    myReturnTypeCodeFragment =
        factory.createTypeCodeFragment("", myMethod, true, JavaCodeFragmentFactory.ALLOW_VOID);
    final Document document =
        PsiDocumentManager.getInstance(myProject).getDocument(myReturnTypeCodeFragment);
    myReturnTypeField =
        new EditorTextField(document, myProject, myReturnTypeCodeFragment.getFileType());

    myNameField.setText(myMethod.getName());
    final GrTypeElement element = myMethod.getReturnTypeElementGroovy();
    if (element != null) {
      myReturnTypeField.setText(element.getText());
    }

    myReturnTypeLabel = new JLabel();
    myReturnTypeLabel.setLabelFor(myReturnTypeField);

    myNameLabel = new JLabel();
    myNameLabel.setLabelFor(myNameField);
  }
  public static PsiTypeElement getOrCreateTypeElement(GrTypeElement typeElement) {
    if (typeElement == null) return null;

    final SoftReference<PsiTypeElement> ref = typeElement.getUserData(PSI_TYPE_ELEMENT);
    final PsiTypeElement element = ref == null ? null : ref.get();
    if (element != null) return element;
    final GrSyntheticTypeElement newTypeElement = new GrSyntheticTypeElement(typeElement);
    typeElement.putUserData(PSI_TYPE_ELEMENT, new SoftReference<PsiTypeElement>(newTypeElement));
    return newTypeElement;
  }
    @Override
    public void visitInstanceofExpression(GrInstanceOfExpression expression) {
      final GrExpression operand = expression.getOperand();
      final GrTypeElement typeElement = expression.getTypeElement();
      if (typeElement == null) return;

      if (myExpression == operand) {
        final PsiType type = typeElement.getType();
        myResult = new TypeConstraint[] {new SupertypeConstraint(type, type)};
      }
    }
 public void visitReturnStatement(GrReturnStatement returnStatement) {
   GrParametersOwner parent =
       PsiTreeUtil.getParentOfType(returnStatement, GrMethod.class, GrClosableBlock.class);
   if (parent instanceof GrMethod) {
     GrTypeElement typeElement = ((GrMethod) parent).getReturnTypeElementGroovy();
     if (typeElement != null) {
       PsiType type = typeElement.getType();
       myResult = new TypeConstraint[] {SubtypeConstraint.create(type)};
     }
   }
 }
  @Nullable
  private PsiType getNominalType() {
    if (PsiImplUtil.isMainMethod(this)) {
      return PsiType.VOID;
    }

    final GrTypeElement element = getReturnTypeElementGroovy();
    if (element != null) {
      return element.getType();
    }
    return null;
  }
 private static boolean safecastExpressionsAreEquivalent(
     GrSafeCastExpression expression1, GrSafeCastExpression expression2) {
   final GrExpression operand1 = expression1.getOperand();
   final GrExpression operand2 = expression2.getOperand();
   if (!expressionsAreEquivalent(operand1, operand2)) {
     return false;
   }
   final GrTypeElement typeElement1 = expression1.getCastTypeElement();
   final GrTypeElement typeElement2 = expression2.getCastTypeElement();
   final PsiType safe1 = typeElement1 == null ? null : typeElement1.getType();
   final PsiType safe2 = typeElement2 == null ? null : typeElement2.getType();
   return typesAreEquivalent(safe1, safe2);
 }
  private static PsiClassType doGetSuperClassType(GroovyScriptClass scriptClass) {
    GrVariableDeclaration declaration = findDeclaration(scriptClass.getContainingFile());
    if (declaration != null) {

      GrModifierList modifierList = declaration.getModifierList();
      if (modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_BASE_SCRIPT)
          != null) {
        GrTypeElement typeElement = declaration.getTypeElementGroovy();
        if (typeElement != null) {
          PsiType type = typeElement.getType();
          if (type instanceof PsiClassType) {
            return (PsiClassType) type;
          }
        }
      }
    }
    return null;
  }
  @Override
  @Nullable
  public GrTypeElement setReturnType(@Nullable PsiType newReturnType) {
    GrTypeElement typeElement = getReturnTypeElementGroovy();
    if (newReturnType == null || newReturnType == PsiType.NULL) {
      if (typeElement != null) typeElement.delete();
      insertPlaceHolderToModifierList();
      return null;
    }
    final GrTypeElement stub =
        GroovyPsiElementFactory.getInstance(getProject()).createTypeElement(newReturnType);
    GrTypeElement newTypeElement;
    if (typeElement == null) {
      final GrTypeParameterList typeParemeterList = getTypeParameterList();
      PsiElement anchor = typeParemeterList != null ? typeParemeterList : getModifierList();
      newTypeElement = (GrTypeElement) addAfter(stub, anchor);
    } else {
      newTypeElement = (GrTypeElement) typeElement.replace(stub);
    }

    return newTypeElement;
  }
  public static boolean isMainMethod(GrMethod method) {
    if (!method.getName().equals(MAIN_METHOD)) return false;
    else if (!method.hasModifierProperty(PsiModifier.STATIC)) return false;

    final GrParameter[] parameters = method.getParameters();

    if (parameters.length == 0) return false;
    if (parameters.length == 1 && parameters[0].getTypeElementGroovy() == null) return true;

    int args_count = 0;
    int optional_count = 0;

    for (GrParameter p : parameters) {
      final GrTypeElement declaredType = p.getTypeElementGroovy();
      if ((declaredType == null
              || declaredType.getType().equalsToText(CommonClassNames.JAVA_LANG_STRING + "[]"))
          && p.getInitializerGroovy() == null) {
        args_count++;
      }
      if (p.getInitializerGroovy() != null) optional_count++;
    }

    return optional_count == parameters.length - 1 && args_count == 1;
  }
 @Nullable
 public static String getTypeText(@Nullable GrTypeElement typeElement) {
   return typeElement == null ? null : typeElement.getText();
 }
  private static boolean processPrimaryMethodInner(
      JavaChangeInfo changeInfo, GrMethod method, @Nullable PsiMethod baseMethod) {
    if (changeInfo.isNameChanged()) {
      String newName =
          baseMethod == null
              ? changeInfo.getNewName()
              : RefactoringUtil.suggestNewOverriderName(
                  method.getName(), baseMethod.getName(), changeInfo.getNewName());
      if (newName != null && !newName.equals(method.getName())) {
        method.setName(changeInfo.getNewName());
      }
    }

    final GrModifierList modifierList = method.getModifierList();
    if (changeInfo.isVisibilityChanged()) {
      modifierList.setModifierProperty(changeInfo.getNewVisibility(), true);
    }

    PsiSubstitutor substitutor =
        baseMethod != null ? calculateSubstitutor(method, baseMethod) : PsiSubstitutor.EMPTY;

    final PsiMethod context = changeInfo.getMethod();
    GrTypeElement oldReturnTypeElement = method.getReturnTypeElementGroovy();
    if (changeInfo.isReturnTypeChanged()) {
      CanonicalTypes.Type newReturnType = changeInfo.getNewReturnType();
      if (newReturnType == null) {
        if (oldReturnTypeElement != null) {
          oldReturnTypeElement.delete();
          if (modifierList.getModifiers().length == 0) {
            modifierList.setModifierProperty(GrModifier.DEF, true);
          }
        }
      } else {
        PsiType type = newReturnType.getType(context, method.getManager());
        GrReferenceAdjuster.shortenAllReferencesIn(
            method.setReturnType(substitutor.substitute(type)));
        if (oldReturnTypeElement == null) {
          modifierList.setModifierProperty(GrModifier.DEF, false);
        }
      }
    }

    JavaParameterInfo[] newParameters = changeInfo.getNewParameters();
    final GrParameterList parameterList = method.getParameterList();
    GrParameter[] oldParameters = parameterList.getParameters();
    final PsiParameter[] oldBaseParams =
        baseMethod != null ? baseMethod.getParameterList().getParameters() : null;

    Set<GrParameter> toRemove = new HashSet<GrParameter>(oldParameters.length);
    ContainerUtil.addAll(toRemove, oldParameters);

    GrParameter anchor = null;
    final GrDocComment docComment = method.getDocComment();
    final GrDocTag[] tags = docComment == null ? null : docComment.getTags();

    for (JavaParameterInfo newParameter : newParameters) {
      // if old parameter name differs from base method parameter name we don't change it
      final String newName;
      final int oldIndex = newParameter.getOldIndex();
      if (oldIndex >= 0 && oldBaseParams != null) {
        final String oldName = oldParameters[oldIndex].getName();
        if (oldName.equals(oldBaseParams[oldIndex].getName())) {
          newName = newParameter.getName();
        } else {
          newName = oldName;
        }
      } else {
        newName = newParameter.getName();
      }

      final GrParameter oldParameter = oldIndex >= 0 ? oldParameters[oldIndex] : null;

      if (docComment != null && oldParameter != null) {
        final String oldName = oldParameter.getName();
        for (GrDocTag tag : tags) {
          if ("@param".equals(tag.getName())) {
            final GrDocParameterReference parameterReference = tag.getDocParameterReference();
            if (parameterReference != null && oldName.equals(parameterReference.getText())) {
              parameterReference.handleElementRename(newName);
            }
          }
        }
      }

      GrParameter grParameter =
          createNewParameter(substitutor, context, parameterList, newParameter, newName);
      if (oldParameter != null) {
        grParameter.getModifierList().replace(oldParameter.getModifierList());
      }

      if ("def".equals(newParameter.getTypeText())) {
        grParameter.getModifierList().setModifierProperty(GrModifier.DEF, true);
      } else if (StringUtil.isEmpty(newParameter.getTypeText())) {
        grParameter.getModifierList().setModifierProperty(GrModifier.DEF, false);
      }

      anchor = (GrParameter) parameterList.addAfter(grParameter, anchor);
    }

    for (GrParameter oldParameter : toRemove) {
      oldParameter.delete();
    }
    JavaCodeStyleManager.getInstance(parameterList.getProject())
        .shortenClassReferences(parameterList);
    CodeStyleManager.getInstance(parameterList.getProject()).reformat(parameterList);

    if (changeInfo.isExceptionSetOrOrderChanged()) {
      final ThrownExceptionInfo[] infos = changeInfo.getNewExceptions();
      PsiClassType[] exceptionTypes = new PsiClassType[infos.length];
      for (int i = 0; i < infos.length; i++) {
        ThrownExceptionInfo info = infos[i];
        exceptionTypes[i] = (PsiClassType) info.createType(method, method.getManager());
      }

      PsiReferenceList thrownList =
          GroovyPsiElementFactory.getInstance(method.getProject()).createThrownList(exceptionTypes);
      thrownList = (PsiReferenceList) method.getThrowsList().replace(thrownList);
      JavaCodeStyleManager.getInstance(thrownList.getProject()).shortenClassReferences(thrownList);
      CodeStyleManager.getInstance(method.getProject()).reformat(method.getThrowsList());
    }
    return true;
  }