/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.uiDesigner.wizard;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.uiDesigner.FormEditingUtil;
import com.intellij.uiDesigner.PsiPropertiesProvider;
import com.intellij.uiDesigner.UIDesignerBundle;
import com.intellij.uiDesigner.compiler.AlienFormFileException;
import com.intellij.uiDesigner.compiler.Utils;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwRootContainer;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author Anton Katilin
 * @author Vladimir Kondratyev
 */
public final class Generator {
  private static final Logger LOG = Logger.getInstance("#com.intellij.uiDesigner.wizard.Generator");

  private Generator() {
  }

  /**
   * @param rootContainer output parameter; should be LwRootContainer[1]
   */
  public static FormProperty[] exposeForm(final Project project, final VirtualFile formFile, final LwRootContainer[] rootContainer) throws MyException{
    final Module module = ModuleUtil.findModuleForFile(formFile, project);
    LOG.assertTrue(module != null);

    final PsiPropertiesProvider propertiesProvider = new PsiPropertiesProvider(module);

    final Document doc = FileDocumentManager.getInstance().getDocument(formFile);
    final LwRootContainer _rootContainer;
    try {
      _rootContainer = Utils.getRootContainer(doc.getText(), propertiesProvider);
    }
    catch (AlienFormFileException e) {
      throw new MyException(e.getMessage());
    }
    catch (Exception e) {
      throw new MyException(UIDesignerBundle.message("error.cannot.process.form.file", e));
    }

    rootContainer[0] = _rootContainer;

    final String classToBind = _rootContainer.getClassToBind();
    if (classToBind == null) {
      throw new MyException(UIDesignerBundle.message("error.form.is.not.bound.to.a.class"));
    }

    final PsiClass boundClass = FormEditingUtil.findClassToBind(module, classToBind);
    if(boundClass == null){
      throw new MyException(UIDesignerBundle.message("error.bound.class.does.not.exist", classToBind));
    }

    final ArrayList<FormProperty> result = new ArrayList<FormProperty>();
    final MyException[] exception = new MyException[1];

    FormEditingUtil.iterate(
      _rootContainer,
      new FormEditingUtil.ComponentVisitor<LwComponent>() {
        public boolean visit(final LwComponent component) {
          final String binding = component.getBinding();
          if (binding == null) {
            return true;
          }

          final PsiField[] fields = boundClass.getFields();
          PsiField field = null;
          for(int i = fields.length - 1; i >=0 ; i--){
            if(binding.equals(fields[i].getName())){
              field = fields[i];
              break;
            }
          }
          if(field == null){
            exception[0] = new MyException(UIDesignerBundle.message("error.field.not.found.in.class", binding, classToBind));
            return false;
          }

          final PsiClass fieldClass = getClassByType(field.getType());
          if (fieldClass == null) {
            exception[0] = new MyException(UIDesignerBundle.message("error.invalid.binding.field.type", binding, classToBind));
            return false;
          }

          if (instanceOf(fieldClass, JTextComponent.class.getName())) {
            result.add(new FormProperty(component, "getText", "setText", String.class.getName()));
          }
          else if (instanceOf(fieldClass, JCheckBox.class.getName())) {
            result.add(new FormProperty(component, "isSelected", "setSelected", boolean.class.getName()));
          }

          return true;
        }
      }
    );

    if (exception[0] != null) {
      throw exception[0];
    }

    return result.toArray(new FormProperty[result.size()]);
  }

  private static PsiClass getClassByType(final PsiType type) {
    if (!(type instanceof PsiClassType)) {
      return null;
    }
    return ((PsiClassType)type).resolve();
  }

  private static boolean instanceOf(final PsiClass jComponentClass, final String baseClassName) {
    for (PsiClass c = jComponentClass; c != null; c = c.getSuperClass()){
      if (baseClassName.equals(c.getQualifiedName())) {
        return true;
      }
    }
    return false;
  }

  /**
   * 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());
    }
  }

  @NotNull
  private static PsiClass createBeanClass(final WizardData wizardData) throws MyException {
    final PsiManager psiManager = PsiManager.getInstance(wizardData.myProject);

    final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(wizardData.myProject);
    final ProjectFileIndex fileIndex = projectRootManager.getFileIndex();
    final VirtualFile sourceRoot = fileIndex.getSourceRootForFile(wizardData.myFormFile);
    if (sourceRoot == null) {
      throw new MyException(UIDesignerBundle.message("error.form.file.is.not.in.source.root"));
    }

    final PsiDirectory rootDirectory = psiManager.findDirectory(sourceRoot);
    LOG.assertTrue(rootDirectory != null);

    final PsiPackage aPackage = JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(wizardData.myPackageName);
    if (aPackage == null) {
      throw new MyException(UIDesignerBundle.message("error.package.does.not.exist", wizardData.myPackageName));
    }

    PsiDirectory targetDir = null;

    final PsiDirectory[] directories = aPackage.getDirectories();
    for (final PsiDirectory psiDirectory : directories) {
      if (PsiTreeUtil.isAncestor(rootDirectory, psiDirectory, false)) {
        targetDir = psiDirectory;
        break;
      }
    }

    if (targetDir == null) {
      // todo
      throw new MyException(UIDesignerBundle.message("error.cannot.find.package", wizardData.myPackageName));
    }

    //noinspection HardCodedStringLiteral
    final String body =
      "public class " + wizardData.myShortClassName + "{\n" +
      "public " + wizardData.myShortClassName + "(){}\n" +
      "}";

    try {
      PsiFile sourceFile =
        PsiFileFactory.getInstance(psiManager.getProject()).createFileFromText(wizardData.myShortClassName + ".java", body);
      sourceFile = (PsiFile)targetDir.add(sourceFile);

      final PsiClass beanClass = ((PsiJavaFile)sourceFile).getClasses()[0];

      final ArrayList<String> properties = new ArrayList<String>();
      final HashMap<String, String> property2fqClassName = new HashMap<String, String>();

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

        properties.add(binding.myBeanProperty.myName);

        // todo: handle "casts" ?

        final String propertyClassName = binding.myFormProperty.getComponentPropertyClassName();

        property2fqClassName.put(binding.myBeanProperty.myName, propertyClassName);
      }

      generateBean(beanClass, ArrayUtil.toStringArray(properties), property2fqClassName);

      return beanClass;
    }
    catch (IncorrectOperationException e) {
      throw new MyException(e.getMessage());
    }
  }

  // todo: inline
  private static void generateBean(
    final PsiClass aClass,
    final String[] properties,
    final HashMap<String, String> property2fqClassName
  ) throws MyException {
    final StringBuffer membersBuffer = new StringBuffer();
    final StringBuffer methodsBuffer = new StringBuffer();

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

    for (final String property : properties) {
      LOG.assertTrue(property != null);
      final String type = property2fqClassName.get(property);
      LOG.assertTrue(type != null);

      generateProperty(styler, property, type, membersBuffer, methodsBuffer);
    }

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

      final PsiField[] fields = fakeClass.getFields();
      for (final PsiField field : fields) {
        aClass.add(field);
      }

      final PsiMethod[] methods = fakeClass.getMethods();
      for (final PsiMethod method : methods) {
        aClass.add(method);
      }

      styler.shortenClassReferences(aClass);
      formatter.reformat(aClass);
    }
    catch (IncorrectOperationException e) {
      throw new MyException(e.getMessage());
    }
  }

  private static void generateProperty(final JavaCodeStyleManager codeStyleManager,
                                       final String property,
                                       final String type,
                                       @NonNls final StringBuffer membersBuffer, @NonNls final StringBuffer methodsBuffer) {
    final String field = codeStyleManager.suggestVariableName(VariableKind.FIELD, property, null, null).names[0];

    membersBuffer.append("private ");
    membersBuffer.append(type);
    membersBuffer.append(" ");
    membersBuffer.append(field);
    membersBuffer.append(";\n");

    // getter
    methodsBuffer.append("public ");
    methodsBuffer.append(type);
    methodsBuffer.append(" ");
    methodsBuffer.append(suggestGetterName(property, type));
    methodsBuffer.append("(){\n");
    methodsBuffer.append("return ");
    methodsBuffer.append(field);
    methodsBuffer.append(";}\n");

    // setter
    final String parameterName = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, property, null, null).names[0];
    methodsBuffer.append("public void ");
    methodsBuffer.append(PropertyUtil.suggestSetterName(property));
    methodsBuffer.append("(final ");
    methodsBuffer.append(type);
    methodsBuffer.append(" ");
    methodsBuffer.append(parameterName);
    methodsBuffer.append("){\n");
    if (parameterName.equals(field)) {
      methodsBuffer.append("this.");
    }
    methodsBuffer.append(field);
    methodsBuffer.append("=");
    methodsBuffer.append(parameterName);
    methodsBuffer.append(";}\n");
  }

  @SuppressWarnings({"HardCodedStringLiteral"})
  private static String suggestGetterName(final String propertyName, final String propertyType) {
    final StringBuffer name = new StringBuffer(StringUtil.capitalize(propertyName));
    if ("boolean".equals(propertyType)) {
      name.insert(0, "is");
    }
    else {
      name.insert(0, "get");
    }
    return name.toString();
  }

  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);
        }
      }
    }
  }

  private static PsiElement getObjectForWhichMethodWasCalled(final PsiMethodCallExpression callExpression) {
    final PsiExpression qualifierExpression = callExpression.getMethodExpression().getQualifierExpression();
    if (!(qualifierExpression instanceof PsiReferenceExpression)) {
      return null;
    }
    return ((PsiReferenceExpression)qualifierExpression).resolve();
  }

  public static final class MyException extends Exception{
    public MyException(final String message) {
      super(message);
    }
  }
}
