private void createParametersPanel() {
    myParameterModel = new GrParameterTableModel(myMethod, this, myProject);
    myParameterModel.addTableModelListener(
        new TableModelListener() {
          public void tableChanged(TableModelEvent e) {
            updateSignature();
          }
        });
    myParameterTable = new JBTable(myParameterModel);
    myParameterTable.setPreferredScrollableViewportSize(
        new Dimension(550, myParameterTable.getRowHeight() * 8));

    myParameterButtonPanel =
        EditableRowTable.createButtonsTable(myParameterTable, myParameterModel, true);

    myParameterTable.setCellSelectionEnabled(true);
    final TableColumnModel columnModel = myParameterTable.getColumnModel();
    columnModel.getColumn(0).setCellRenderer(new CodeFragmentTableCellRenderer(myProject));
    columnModel.getColumn(1).setCellRenderer(new GrCodeFragmentTableCellRenderer(myProject));
    columnModel.getColumn(2).setCellRenderer(new GrCodeFragmentTableCellRenderer(myProject));
    columnModel.getColumn(3).setCellRenderer(new GrCodeFragmentTableCellRenderer(myProject));

    columnModel.getColumn(0).setCellEditor(new JavaCodeFragmentTableCellEditor(myProject));
    columnModel.getColumn(1).setCellEditor(new GrCodeFragmentTableCellEditor(myProject));
    columnModel.getColumn(2).setCellEditor(new GrCodeFragmentTableCellEditor(myProject));
    columnModel.getColumn(3).setCellEditor(new GrCodeFragmentTableCellEditor(myProject));

    if (myParameterModel.getRowCount() > 0) {
      myParameterTable.setRowSelectionInterval(0, 0);
      myParameterTable.setColumnSelectionInterval(0, 0);
    }
  }
  private String generateSignatureText() {
    String name = getNewName();
    String type = myReturnTypeField.getText().trim();

    StringBuilder builder = new StringBuilder();
    if (myPublicRadioButton.isSelected() && type.length() == 0) {
      builder.append(GrModifier.DEF);
    }
    if (myPrivateRadioButton.isSelected()) {
      builder.append(GrModifier.PRIVATE).append(' ');
    } else if (myProtectedRadioButton.isSelected()) {
      builder.append(GrModifier.PROTECTED).append(' ');
    }
    builder.append(type).append(' ');
    builder.append(name).append('(');

    final List<GrTableParameterInfo> infos = myParameterModel.getParameterInfos();
    if (infos.size() > 0) {
      final List<String> paramsText =
          ContainerUtil.map(
              infos,
              new Function<GrTableParameterInfo, String>() {
                public String fun(GrTableParameterInfo grParameterInfo) {
                  return generateParameterText(grParameterInfo);
                }
              });
      builder.append("\n").append(INDENT);
      builder.append(StringUtil.join(paramsText, ",\n" + INDENT));
      builder.append('\n');
    }
    builder.append(')');

    final PsiTypeCodeFragment[] exceptions = myExceptionTableModel.getTypeCodeFragments();
    if (exceptions.length > 0) {
      builder.append("\nthrows\n");
      final List<String> exceptionNames =
          ContainerUtil.map(
              exceptions,
              new Function<PsiTypeCodeFragment, String>() {
                public String fun(PsiTypeCodeFragment fragment) {
                  return fragment.getText();
                }
              });

      builder.append(INDENT).append(StringUtil.join(exceptionNames, ",\n" + INDENT));
    }
    return builder.toString();
  }
  @Override
  protected void doAction() {
    if (!validateInputData()) {
      return;
    }

    stopEditing();
    String modifier = "";
    if (myPublicRadioButton.isSelected()) {
      modifier = GrModifier.PUBLIC;
    } else if (myPrivateRadioButton.isSelected()) {
      modifier = GrModifier.PRIVATE;
    } else if (myProtectedRadioButton.isSelected()) {
      modifier = GrModifier.PROTECTED;
    }

    PsiType returnType = null;
    try {
      returnType = myReturnTypeCodeFragment.getType();
    } catch (PsiTypeCodeFragment.TypeSyntaxException ignored) {
    } catch (PsiTypeCodeFragment.NoTypeException ignored) {
    }

    String newName = getNewName();
    final List<GrTableParameterInfo> tableParameterInfos = myParameterModel.getParameterInfos();
    final List<GrParameterInfo> parameterInfos =
        ContainerUtil.map(
            tableParameterInfos,
            new Function<GrTableParameterInfo, GrParameterInfo>() {
              public GrParameterInfo fun(GrTableParameterInfo info) {
                return info.generateParameterInfo();
              }
            });
    final ThrownExceptionInfo[] exceptionInfos = myExceptionTableModel.getThrownExceptions();
    invokeRefactoring(
        new GrChangeSignatureProcessor(
            myProject,
            new GrChangeInfoImpl(
                myMethod,
                modifier,
                returnType == null ? null : CanonicalTypes.createTypeWrapper(returnType),
                newName,
                parameterInfos,
                exceptionInfos,
                myDelegateRadioButton.isSelected())));
  }
  private boolean validateInputData() {
    if (!isGroovyMethodName(getNewName())) {
      showErrorHint(message("name.is.wrong", getNewName()));
      return false;
    }

    if (!checkType(myReturnTypeCodeFragment, true)) {
      showErrorHint(message("return.type.is.wrong"));
      return false;
    }

    List<GrTableParameterInfo> parameterInfos = myParameterModel.getParameterInfos();
    for (int i = 0; i < parameterInfos.size(); i++) {
      GrTableParameterInfo info = parameterInfos.get(i);
      if (!StringUtil.isJavaIdentifier(info.getName())) {
        showErrorHint(message("name.is.wrong", info.getName()));
        return false;
      }
      if (!checkType(info.getTypeFragment(), i == parameterInfos.size() - 1)) {
        showErrorHint(message("type.for.parameter.is.incorrect", info.getName()));
        return false;
      }
      String defaultValue = info.getDefaultValue();
      final String initializer = info.getDefaultInitializerFragment().getText();
      if (info.getOldIndex() < 0
          && defaultValue.trim().length() == 0
          && initializer.trim().length() == 0) {
        showErrorHint(message("specify.default.value", info.getName()));
        return false;
      }
    }

    ThrownExceptionInfo[] exceptionInfos = myExceptionTableModel.getThrownExceptions();
    PsiTypeCodeFragment[] typeCodeFragments = myExceptionTableModel.getTypeCodeFragments();
    for (int i = 0; i < exceptionInfos.length; i++) {
      ThrownExceptionInfo exceptionInfo = exceptionInfos[i];
      PsiTypeCodeFragment typeCodeFragment = typeCodeFragments[i];
      try {
        PsiType type = typeCodeFragment.getType();
        if (!(type instanceof PsiClassType)) {
          showErrorHint(
              GroovyRefactoringBundle.message(
                  "changeSignature.wrong.type.for.exception", typeCodeFragment.getText()));
          return false;
        }

        PsiClassType throwable =
            JavaPsiFacade.getInstance(myMethod.getProject())
                .getElementFactory()
                .createTypeByFQClassName("java.lang.Throwable", myMethod.getResolveScope());
        if (!throwable.isAssignableFrom(type)) {
          showErrorHint(
              GroovyRefactoringBundle.message(
                  "changeSignature.not.throwable.type", typeCodeFragment.getText()));
          return false;
        }
        exceptionInfo.setType((PsiClassType) type);
      } catch (PsiTypeCodeFragment.TypeSyntaxException e) {
        showErrorHint(
            GroovyRefactoringBundle.message(
                "changeSignature.wrong.type.for.exception", typeCodeFragment.getText()));
        return false;
      } catch (PsiTypeCodeFragment.NoTypeException e) {
        showErrorHint(GroovyRefactoringBundle.message("changeSignature.no.type.for.exception"));
        return false;
      }
    }

    return true;
  }