public static void prepareWizardData(final WizardData data, PsiClass boundClass)
      throws MyException {

    final PsiMethod[] allGetDataMethods = boundClass.findMethodsByName("getData", false);
    final PsiMethod[] allSetDataMethods = boundClass.findMethodsByName("setData", false);

    PsiMethod setDataMethod = null;
    PsiClass beanClass = null;

    // find get/set pair and bean class
    outer:
    for (int i = 0; i < allGetDataMethods.length; i++) {
      final PsiMethod _getMethod = allGetDataMethods[i];

      if (_getMethod.getReturnType() != PsiType.VOID) {
        continue;
      }

      final PsiParameter[] _getMethodParameters = _getMethod.getParameterList().getParameters();
      if (_getMethodParameters.length != 1) {
        continue;
      }

      final PsiClass _getParameterClass = getClassByType(_getMethodParameters[0].getType());
      if (_getParameterClass == null) {
        continue;
      }

      for (final PsiMethod _setMethod : allSetDataMethods) {
        if (_setMethod.getReturnType() != PsiType.VOID) {
          continue;
        }

        final PsiParameter[] _setMethodParameters = _setMethod.getParameterList().getParameters();
        if (_setMethodParameters.length != 1) {
          continue;
        }

        final PsiClass _setParameterClass = getClassByType(_setMethodParameters[0].getType());
        if (_setParameterClass != _getParameterClass) {
          continue;
        }

        // pair found !!!

        setDataMethod = _setMethod;
        beanClass = _getParameterClass;
        break outer;
      }
    }

    if (beanClass == null) {
      // nothing found
      return;
    }

    data.myBindToNewBean = false;
    data.myBeanClass = beanClass;

    // parse setData() and try to associate fields with bean
    {
      final PsiCodeBlock body = setDataMethod.getBody();
      if (body == null) {
        return;
      }

      final PsiElement[] children = body.getChildren();
      for (PsiElement child : children) {
        // Parses sequences like: a.foo(b.bar());
        final PsiField bindingField;

        if (!(child instanceof PsiExpressionStatement)) {
          continue;
        }

        final PsiExpression expression = ((PsiExpressionStatement) child).getExpression();
        if (!(expression instanceof PsiMethodCallExpression)) {
          continue;
        }

        final PsiMethodCallExpression callExpression = (PsiMethodCallExpression) expression;

        // find binding field ('a')
        int index = -1;
        {
          final PsiElement psiElement = getObjectForWhichMethodWasCalled(callExpression);
          if (!(psiElement instanceof PsiField)) {
            continue;
          }

          if (((PsiField) psiElement).getContainingClass() != boundClass) {
            continue;
          }

          bindingField = (PsiField) psiElement;

          // find binding for this field
          final FormProperty2BeanProperty[] bindings = data.myBindings;
          for (int j = 0; j < bindings.length; j++) {
            final FormProperty2BeanProperty binding = bindings[j];
            if (bindingField
                .getName()
                .equals(binding.myFormProperty.getLwComponent().getBinding())) {
              index = j;
              break;
            }
          }
        }

        if (index == -1) {
          continue;
        }

        // find 'bar()'
        {
          final PsiReferenceParameterList parameterList =
              callExpression.getMethodExpression().getParameterList();
          if (parameterList == null) {
            continue;
          }

          final PsiExpressionList argumentList = callExpression.getArgumentList();
          if (argumentList == null) {
            continue;
          }

          final PsiExpression[] expressions = argumentList.getExpressions();
          if (expressions == null || expressions.length != 1) {
            continue;
          }

          if (!(expressions[0] instanceof PsiMethodCallExpression)) {
            continue;
          }

          final PsiMethodCallExpression callExpression2 =
              ((PsiMethodCallExpression) expressions[0]);

          // check that 'b' is parameter
          final PsiElement psiElement = getObjectForWhichMethodWasCalled(callExpression2);
          if (!(psiElement instanceof PsiParameter)) {
            continue;
          }

          final PsiMethod barMethod = ((PsiMethod) callExpression2.getMethodExpression().resolve());
          if (barMethod == null) {
            continue;
          }

          if (!PropertyUtil.isSimplePropertyGetter(barMethod)) {
            continue;
          }

          final String propertyName = PropertyUtil.getPropertyName(barMethod);

          // There are two possible types: boolean and java.lang.String
          String typeName = barMethod.getReturnType().getCanonicalText();
          if (!"boolean".equals(typeName) && !"java.lang.String".equals(typeName)) {
            continue;
          }

          data.myBindings[index].myBeanProperty = new BeanProperty(propertyName, typeName);
        }
      }
    }
  }