@Override
  public boolean prepareSymptom(Symptom symptom) throws RefactoringException {
    loadEnvironment();
    //        reloadEnv();

    PullPushMethodSymptom pullPushMethodSymptom = (PullPushMethodSymptom) symptom;

    currentTarget =
        getProject()
            .getTypeRefForSourceName(pullPushMethodSymptom.getTargetQualifiedName())
            .getBinCIType();
    BinCIType owner =
        getProject()
            .getTypeRefForSourceName(pullPushMethodSymptom.getParentQualifiedName())
            .getBinCIType();

    BinMember member =
        owner.getDeclaredMethod(
            pullPushMethodSymptom.getMemberName(), pullPushMethodSymptom.getBinParameters());
    if (member == null) {
      member =
          getMethodManually(
              pullPushMethodSymptom.getMemberName(),
              owner,
              pullPushMethodSymptom.getBinParameters());
    }
    currentMethod = (BinMethod) member;

    return reloadRefactoring();
  }
  public void test() {
    String qName = "Test2";

    BinTypeRef ref = project.getTypeRefForName(qName);
    assertNotNull(ref);
    BinCIType type = ref.getBinCIType();

    BinMethod[] methods = type.getDeclaredMethods();
    for (int i = 0; i < methods.length; i++) {

      if (methods[i].getName().equals("main")) {
        MethodVisitor visitor = new MethodVisitor();
        methods[i].accept(visitor);

        for (int j = 0; j < visitor.METHODS.size(); j++) {

          if (((String) visitor.METHODS.get(j)).equals("target2")) {
            String retType = (String) visitor.RETTYPES.get(j);

            //            System.out.println(retType);

            assertTrue("Return type must be String, found: " + retType, retType.equals("String"));
          } else if (((String) visitor.METHODS.get(j)).equals("target")) {
            String retType = (String) visitor.RETTYPES.get(j);

            //            System.out.println(retType);

            assertTrue("Return type must be Integer, found: " + retType, retType.equals("Integer"));
          }
        }
      }
    }
  }
  private void findFolders(String prefix, BinPackage aPackage, Set result) {
    for (Iterator i = aPackage.getAllTypes(); i.hasNext(); ) {
      BinCIType type = ((BinTypeRef) i.next()).getBinCIType();

      Source folder = findFolder(prefix, type);
      if (folder != null) {
        result.add(folder);
      } else {
        getSourcesInWrongFolders().add(type.getCompilationUnit().getSource());
      }
    }
  }
  /**
   * Creates a method with a body for the getter.
   *
   * @return getter body
   */
  private String createGetterBody() {
    // TODO: use access modifier given by user

    int modifier = this.getGetterVisibility();
    if (field.isStatic()) {
      modifier |= BinModifier.STATIC;
    }
    BinMethod getter =
        new BinMethod(
            getterName,
            BinParameter.NO_PARAMS,
            getField().getTypeRef(),
            modifier,
            BinMethod.Throws.NO_THROWS);
    getter.setOwner(field.getOwner());

    BinMethodFormatter formatter = (BinMethodFormatter) getter.getFormatter();
    String result = FormatSettings.LINEBREAK + formatter.formHeader();

    // TODO migrate to formatting engine also?
    int baseIndent = new BinTypeFormatter(field.getOwner().getBinCIType()).getMemberIndent();
    result += FormatSettings.getIndentString(baseIndent + FormatSettings.getBlockIndent());
    result += "return ";
    if (field.isStatic()) {
      result += hostingClass.getName();
    } else {
      result += "this";
    }
    result += "." + getField().getName() + ";";
    result += FormatSettings.LINEBREAK;

    result += formatter.formFooter();

    return result;
  }
  private Source findFolder(String prefix, BinCIType type) {
    CompilationUnit compilationUnit = type.getCompilationUnit();
    if (compilationUnit == null) {
      return null;
    }

    return findParent(prefix, compilationUnit.getSource());
  }
  /**
   * Checks whether a to-be-created accessor doesn't conflict with the current classmodel.
   *
   * @param method virtual to-be-created accessor
   * @param errors list of error messages that is populated
   */
  private void checkVirtualAccessor(BinMethod method, List errors) {
    for (final Iterator i = hostingClass.getTypeRef().getAllSubclasses().iterator();
        i.hasNext(); ) {
      BinCIType subtype = ((BinTypeRef) i.next()).getBinCIType();
      BinMethod[] methods = subtype.getDeclaredMethods();
      for (int pos = 0, max = methods.length; pos < max; pos++) {
        BinMethod current = methods[pos];

        // FIXME: or vice-versa: method.isApplicable(current)?
        if (current.isApplicable(method)
            && method.isAccessible(hostingClass, subtype)
            && !current.isAbstract()) {
          CollectionUtil.addNew(errors, "Conflicts with the existing method '" + current + "'");
        }
      } // end for methods
    } // end for subtypes

    for (final Iterator i = hostingClass.getTypeRef().getAllSupertypes().iterator();
        i.hasNext(); ) {
      BinCIType supertype = ((BinTypeRef) i.next()).getBinCIType();
      BinMethod[] methods = supertype.getDeclaredMethods();
      for (int pos = 0, max = methods.length; pos < max; pos++) {
        BinMethod current = methods[pos];

        // FIXME: or vice-versa: method.isApplicable(current)?
        if (current.isApplicable(method)
            && current.isAccessible(supertype, hostingClass)
            && !current.isAbstract()) {
          CollectionUtil.addNew(errors, "Conflicts with the existing method '" + current + "'");
        }
      } // end for methods
    }
  }
  @Override
  public List<Symptom> findAllSymptoms() throws RefactoringException {
    if (!loadEnvironment()) {
      return null;
    }

    List<Symptom> result = new ArrayList<Symptom>();

    for (Object object : getProject().getDefinedTypes()) {
      BinCITypeRef binCITypeRef = (BinCITypeRef) object;
      BinCIType bcitr = binCITypeRef.getBinCIType();

      if (bcitr.isInterface()) {
        continue;
      }

      if (bcitr.isInnerType() && !bcitr.isStatic()) {
        continue;
      }

      if (bcitr.isAbstract()) {
        continue;
      }

      if (!classShouldBeVerified(binCITypeRef)) {
        continue;
      }

      BinClass cls = (BinClass) bcitr;
      BinConstructor[] constructors = cls.getConstructors();
      for (BinConstructor binConstructor : constructors) {
        Symptom symptom = new CreateFactoryMethodSymptom(binConstructor, this);
        result.add(symptom);
      }
    }
    return result;
  }
 /** @return setter for curent encapsulation, null if not present */
 private BinMethod getSetterMethod() {
   return hostingClass.getDeclaredMethod(
       setterName, new BinParameter[] {new BinParameter(field.getName(), field.getTypeRef(), 0)});
 }
 /** @return getter for curent encapsulation, null if not present */
 private BinMethod getGetterMethod() {
   return hostingClass.getDeclaredMethod(getterName, BinTypeRef.NO_TYPEREFS);
 }