private void changeParameter(
      int parameterIndex, JetParameter parameter, JetParameterInfo parameterInfo) {
    ASTNode valOrVarAstNode = parameter.getValOrVarNode();
    PsiElement valOrVarNode = valOrVarAstNode != null ? valOrVarAstNode.getPsi() : null;
    JetValVar valOrVar = parameterInfo.getValOrVar();

    JetPsiFactory psiFactory = JetPsiFactory(getProject());
    if (valOrVarNode != null) {
      if (valOrVar == JetValVar.None) {
        valOrVarNode.delete();
      } else {
        valOrVarNode.replace(psiFactory.createValOrVarNode(valOrVar.toString()).getPsi());
      }
    } else if (valOrVar != JetValVar.None) {
      PsiElement firstChild = parameter.getFirstChild();
      parameter.addBefore(psiFactory.createValOrVarNode(valOrVar.toString()).getPsi(), firstChild);
      parameter.addBefore(psiFactory.createWhiteSpace(), firstChild);
    }

    if (parameterInfo.getIsTypeChanged() && parameter.getTypeReference() != null) {
      String renderedType = parameterInfo.renderType(parameterIndex, this);
      parameter.setTypeReference(psiFactory.createType(renderedType));
    }

    PsiElement identifier = parameter.getNameIdentifier();

    if (identifier != null) {
      //noinspection unchecked
      String newName =
          parameterInfo.getInheritedName((JetFunctionDefinitionUsage<PsiElement>) this);
      identifier.replace(psiFactory.createIdentifier(newName));
    }
  }
  @Override
  public boolean processUsage(JetChangeInfo changeInfo, PsiElement element) {
    JetParameterList parameterList;

    JetPsiFactory psiFactory = JetPsiFactory(element.getProject());
    if (element instanceof JetFunction) {
      JetFunction function = (JetFunction) element;
      parameterList = function.getValueParameterList();

      if (changeInfo.isNameChanged()) {
        PsiElement identifier = function.getNameIdentifier();

        if (identifier != null) {
          identifier.replace(psiFactory.createIdentifier(changeInfo.getNewName()));
        }
      }

      boolean returnTypeIsNeeded =
          (changeInfo.isRefactoringTarget(originalFunctionDescriptor)
                  || !(function instanceof JetFunctionLiteral)
                  || function.getTypeReference() != null)
              && !(function instanceof JetSecondaryConstructor);
      if (changeInfo.isReturnTypeChanged() && returnTypeIsNeeded) {
        function.setTypeReference(null);
        String returnTypeText =
            changeInfo.renderReturnType((JetFunctionDefinitionUsage<PsiElement>) this);

        // TODO use ChangeFunctionReturnTypeFix.invoke when JetTypeCodeFragment.getType() is ready
        if (!KotlinBuiltIns.getInstance().getUnitType().toString().equals(returnTypeText)) {
          ShortenPackage.addToShorteningWaitSet(
              function.setTypeReference(JetPsiFactory(function).createType(returnTypeText)),
              Options.DEFAULT);
        }
      }
    } else {
      parameterList = ((JetClass) element).getPrimaryConstructorParameterList();
    }

    if (changeInfo.isParameterSetOrOrderChanged()) {
      processParameterListWithStructuralChanges(changeInfo, element, parameterList, psiFactory);
    } else if (parameterList != null) {
      int paramIndex = 0;

      for (JetParameter parameter : parameterList.getParameters()) {
        JetParameterInfo parameterInfo = changeInfo.getNewParameters()[paramIndex];
        changeParameter(paramIndex, parameter, parameterInfo);
        paramIndex++;
      }

      ShortenPackage.addToShorteningWaitSet(parameterList, Options.DEFAULT);
    }

    if (element instanceof JetFunction && changeInfo.isReceiverTypeChanged()) {
      //noinspection unchecked
      String receiverTypeText =
          changeInfo.renderReceiverType((JetFunctionDefinitionUsage<PsiElement>) this);
      JetTypeReference receiverTypeRef =
          receiverTypeText != null ? psiFactory.createType(receiverTypeText) : null;
      JetTypeReference newReceiverTypeRef =
          TypeRefHelpersPackage.setReceiverTypeReference((JetFunction) element, receiverTypeRef);
      if (newReceiverTypeRef != null) {
        ShortenPackage.addToShorteningWaitSet(
            newReceiverTypeRef, ShortenReferences.Options.DEFAULT);
      }
    }

    if (changeInfo.isVisibilityChanged() && !JetPsiUtil.isLocal((JetDeclaration) element)) {
      changeVisibility(changeInfo, element);
    }

    return true;
  }