public RemoveMiddlemanProcessor(PsiField field, List<MemberInfo> memberInfos) {
   super(field.getProject());
   this.field = field;
   containingClass = field.getContainingClass();
   final String propertyName = PropertyUtil.suggestPropertyName(field);
   final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
   getter = PropertyUtil.findPropertyGetter(containingClass, propertyName, isStatic, false);
   myDelegateMethodInfos = memberInfos;
 }
  @Override
  public void findExistingNameConflicts(
      PsiElement element, String newName, MultiMap<PsiElement, String> conflicts) {
    super.findExistingNameConflicts(element, newName, conflicts);

    GrField field = (GrField) element;
    final PsiClass containingClass = field.getContainingClass();
    if (containingClass == null) return;

    final PsiMethod getter = GroovyPropertyUtils.findGetterForField(field);
    if (getter instanceof GrAccessorMethod) {
      final PsiMethod newGetter =
          PropertyUtil.findPropertyGetter(
              containingClass, newName, field.hasModifierProperty(PsiModifier.STATIC), true);
      if (newGetter != null && !(newGetter instanceof GrAccessorMethod)) {
        conflicts.putValue(
            newGetter,
            GroovyRefactoringBundle.message(
                "implicit.getter.will.by.overriden.by.method",
                field.getName(),
                newGetter.getName()));
      }
    }
    final PsiMethod setter = GroovyPropertyUtils.findSetterForField(field);
    if (setter instanceof GrAccessorMethod) {
      final PsiMethod newSetter =
          PropertyUtil.findPropertySetter(
              containingClass, newName, field.hasModifierProperty(PsiModifier.STATIC), true);
      if (newSetter != null && !(newSetter instanceof GrAccessorMethod)) {
        conflicts.putValue(
            newSetter,
            GroovyRefactoringBundle.message(
                "implicit.setter.will.by.overriden.by.method",
                field.getName(),
                newSetter.getName()));
      }
    }
  }
  /** Should be invoked in command and write action */
  @SuppressWarnings({"HardCodedStringLiteral"})
  public static void generateDataBindingMethods(final WizardData data) throws MyException {
    if (data.myBindToNewBean) {
      data.myBeanClass = createBeanClass(data);
    } else {
      if (!CommonRefactoringUtil.checkReadOnlyStatus(
          data.myBeanClass.getProject(), data.myBeanClass)) {
        return;
      }
    }

    final HashMap<String, String> binding2beanGetter = new HashMap<String, String>();
    final HashMap<String, String> binding2beanSetter = new HashMap<String, String>();

    final FormProperty2BeanProperty[] bindings = data.myBindings;
    for (final FormProperty2BeanProperty form2bean : bindings) {
      if (form2bean == null || form2bean.myBeanProperty == null) {
        continue;
      }

      // check that bean contains the property, and if not, try to add the property to the bean
      {
        final String setterName = PropertyUtil.suggestSetterName(form2bean.myBeanProperty.myName);
        final PsiMethod[] methodsByName = data.myBeanClass.findMethodsByName(setterName, true);
        if (methodsByName.length < 1) {
          // bean does not contain this property
          // try to add...

          LOG.assertTrue(
              !data.myBindToNewBean); // just generated bean class should contain all necessary
                                      // properties

          if (!data.myBeanClass.isWritable()) {
            throw new MyException(
                "Cannot add property to non writable class " + data.myBeanClass.getQualifiedName());
          }

          final StringBuffer membersBuffer = new StringBuffer();
          final StringBuffer methodsBuffer = new StringBuffer();

          final Project project = data.myBeanClass.getProject();
          final CodeStyleManager formatter = CodeStyleManager.getInstance(project);
          final JavaCodeStyleManager styler = JavaCodeStyleManager.getInstance(project);

          generateProperty(
              styler,
              form2bean.myBeanProperty.myName,
              form2bean.myBeanProperty.myType,
              membersBuffer,
              methodsBuffer);

          final PsiClass fakeClass;
          try {
            fakeClass =
                JavaPsiFacade.getInstance(data.myBeanClass.getProject())
                    .getElementFactory()
                    .createClassFromText(membersBuffer.toString() + methodsBuffer.toString(), null);

            final PsiField[] fields = fakeClass.getFields();
            {
              final PsiElement result = data.myBeanClass.add(fields[0]);
              styler.shortenClassReferences(result);
              formatter.reformat(result);
            }

            final PsiMethod[] methods = fakeClass.getMethods();
            {
              final PsiElement result = data.myBeanClass.add(methods[0]);
              styler.shortenClassReferences(result);
              formatter.reformat(result);
            }
            {
              final PsiElement result = data.myBeanClass.add(methods[1]);
              styler.shortenClassReferences(result);
              formatter.reformat(result);
            }
          } catch (IncorrectOperationException e) {
            throw new MyException(e.getMessage());
          }
        }
      }

      final PsiMethod propertySetter =
          PropertyUtil.findPropertySetter(
              data.myBeanClass, form2bean.myBeanProperty.myName, false, true);
      final PsiMethod propertyGetter =
          PropertyUtil.findPropertyGetter(
              data.myBeanClass, form2bean.myBeanProperty.myName, false, true);

      if (propertyGetter == null) {
        // todo
        continue;
      }
      if (propertySetter == null) {
        // todo
        continue;
      }

      final String binding = form2bean.myFormProperty.getLwComponent().getBinding();
      binding2beanGetter.put(binding, propertyGetter.getName());
      binding2beanSetter.put(binding, propertySetter.getName());
    }

    final String dataBeanClassName = data.myBeanClass.getQualifiedName();

    final LwRootContainer[] rootContainer = new LwRootContainer[1];
    final FormProperty[] formProperties =
        exposeForm(data.myProject, data.myFormFile, rootContainer);

    final StringBuffer getDataBody = new StringBuffer();
    final StringBuffer setDataBody = new StringBuffer();
    final StringBuffer isModifiedBody = new StringBuffer();

    // iterate exposed formproperties

    for (final FormProperty formProperty : formProperties) {
      final String binding = formProperty.getLwComponent().getBinding();
      if (!binding2beanGetter.containsKey(binding)) {
        continue;
      }

      getDataBody.append("data.");
      getDataBody.append(binding2beanSetter.get(binding));
      getDataBody.append("(");
      getDataBody.append(binding);
      getDataBody.append(".");
      getDataBody.append(formProperty.getComponentPropertyGetterName());
      getDataBody.append("());\n");

      setDataBody.append(binding);
      setDataBody.append(".");
      setDataBody.append(formProperty.getComponentPropertySetterName());
      setDataBody.append("(data.");
      setDataBody.append(binding2beanGetter.get(binding));
      setDataBody.append("());\n");

      final String propertyClassName = formProperty.getComponentPropertyClassName();
      if ("boolean".equals(propertyClassName)) {
        isModifiedBody.append("if (");
        //
        isModifiedBody.append(binding);
        isModifiedBody.append(".");
        isModifiedBody.append(formProperty.getComponentPropertyGetterName());
        isModifiedBody.append("()");
        //
        isModifiedBody.append("!= ");
        //
        isModifiedBody.append("data.");
        isModifiedBody.append(binding2beanGetter.get(binding));
        isModifiedBody.append("()");
        //
        isModifiedBody.append(") return true;\n");
      } else {
        isModifiedBody.append("if (");
        //
        isModifiedBody.append(binding);
        isModifiedBody.append(".");
        isModifiedBody.append(formProperty.getComponentPropertyGetterName());
        isModifiedBody.append("()");
        //
        isModifiedBody.append("!= null ? ");
        //
        isModifiedBody.append("!");
        //
        isModifiedBody.append(binding);
        isModifiedBody.append(".");
        isModifiedBody.append(formProperty.getComponentPropertyGetterName());
        isModifiedBody.append("()");
        //
        isModifiedBody.append(".equals(");
        //
        isModifiedBody.append("data.");
        isModifiedBody.append(binding2beanGetter.get(binding));
        isModifiedBody.append("()");
        isModifiedBody.append(") : ");
        //
        isModifiedBody.append("data.");
        isModifiedBody.append(binding2beanGetter.get(binding));
        isModifiedBody.append("()");
        isModifiedBody.append("!= null");
        //
        isModifiedBody.append(") return true;\n");
      }
    }
    isModifiedBody.append("return false;\n");

    final String textOfMethods =
        "public void setData("
            + dataBeanClassName
            + " data){\n"
            + setDataBody.toString()
            + "}\n"
            + "\n"
            + "public void getData("
            + dataBeanClassName
            + " data){\n"
            + getDataBody.toString()
            + "}\n"
            + "\n"
            + "public boolean isModified("
            + dataBeanClassName
            + " data){\n"
            + isModifiedBody.toString()
            + "}\n";

    // put them to the bound class

    final Module module = ModuleUtil.findModuleForFile(data.myFormFile, data.myProject);
    LOG.assertTrue(module != null);
    final PsiClass boundClass =
        FormEditingUtil.findClassToBind(module, rootContainer[0].getClassToBind());
    LOG.assertTrue(boundClass != null);

    if (!CommonRefactoringUtil.checkReadOnlyStatus(module.getProject(), boundClass)) {
      return;
    }

    // todo: check that this method does not exist yet

    final PsiClass fakeClass;
    try {
      fakeClass =
          JavaPsiFacade.getInstance(data.myProject)
              .getElementFactory()
              .createClassFromText(textOfMethods, null);

      final PsiMethod methodSetData = fakeClass.getMethods()[0];
      final PsiMethod methodGetData = fakeClass.getMethods()[1];
      final PsiMethod methodIsModified = fakeClass.getMethods()[2];

      final PsiMethod existing1 = boundClass.findMethodBySignature(methodSetData, false);
      final PsiMethod existing2 = boundClass.findMethodBySignature(methodGetData, false);
      final PsiMethod existing3 = boundClass.findMethodBySignature(methodIsModified, false);

      // warning already shown
      if (existing1 != null) {
        existing1.delete();
      }
      if (existing2 != null) {
        existing2.delete();
      }
      if (existing3 != null) {
        existing3.delete();
      }

      final CodeStyleManager formatter = CodeStyleManager.getInstance(module.getProject());
      final JavaCodeStyleManager styler = JavaCodeStyleManager.getInstance(module.getProject());

      final PsiElement setData = boundClass.add(methodSetData);
      styler.shortenClassReferences(setData);
      formatter.reformat(setData);

      final PsiElement getData = boundClass.add(methodGetData);
      styler.shortenClassReferences(getData);
      formatter.reformat(getData);

      if (data.myGenerateIsModified) {
        final PsiElement isModified = boundClass.add(methodIsModified);
        styler.shortenClassReferences(isModified);
        formatter.reformat(isModified);
      }

      final OpenFileDescriptor descriptor =
          new OpenFileDescriptor(
              setData.getProject(),
              setData.getContainingFile().getVirtualFile(),
              setData.getTextOffset());
      FileEditorManager.getInstance(data.myProject).openTextEditor(descriptor, true);
    } catch (IncorrectOperationException e) {
      throw new MyException(e.getMessage());
    }
  }
  private void findUsagesForField(PsiField field, List<FixableUsageInfo> usages) {
    final PsiManager psiManager = field.getManager();
    final Project project = psiManager.getProject();
    final GlobalSearchScope scope = GlobalSearchScope.allScope(project);

    final String qualifiedName = getQualifiedName();
    @NonNls String getter = null;
    if (myGenerateAccessors) {
      getter = GenerateMembersUtil.suggestGetterName(field);
    } else {
      final PsiMethod fieldGetter =
          PropertyUtil.findPropertyGetter(sourceClass, field.getName(), false, false);
      if (fieldGetter != null && isInMovedElement(fieldGetter)) {
        getter = fieldGetter.getName();
      }
    }

    @NonNls String setter = null;
    if (myGenerateAccessors) {
      setter = GenerateMembersUtil.suggestSetterName(field);
    } else {
      final PsiMethod fieldSetter =
          PropertyUtil.findPropertySetter(sourceClass, field.getName(), false, false);
      if (fieldSetter != null && isInMovedElement(fieldSetter)) {
        setter = fieldSetter.getName();
      }
    }
    final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);

    for (PsiReference reference : ReferencesSearch.search(field, scope)) {
      final PsiElement element = reference.getElement();
      if (isInMovedElement(element)) {
        continue;
      }

      if (element instanceof PsiReferenceExpression) {
        final PsiReferenceExpression exp = (PsiReferenceExpression) element;
        if (RefactoringUtil.isPlusPlusOrMinusMinus(exp.getParent())) {
          usages.add(
              isStatic
                  ? new ReplaceStaticVariableIncrementDecrement(exp, qualifiedName)
                  : new ReplaceInstanceVariableIncrementDecrement(
                      exp, delegateFieldName, setter, getter, field.getName()));
        } else if (RefactoringUtil.isAssignmentLHS(exp)) {
          usages.add(
              isStatic
                  ? new ReplaceStaticVariableAssignment(exp, qualifiedName)
                  : new ReplaceInstanceVariableAssignment(
                      PsiTreeUtil.getParentOfType(exp, PsiAssignmentExpression.class),
                      delegateFieldName,
                      setter,
                      getter,
                      field.getName()));

        } else {
          usages.add(
              isStatic
                  ? new ReplaceStaticVariableAccess(
                      exp, qualifiedName, enumConstants.contains(field))
                  : new ReplaceInstanceVariableAccess(
                      exp, delegateFieldName, getter, field.getName()));
        }

        if (!isStatic) {
          delegationRequired = true;
        }
      } else if (element instanceof PsiDocTagValue) {
        usages.add(new BindJavadocReference(element, qualifiedName, field.getName()));
      }
    }
  }