private Set<CtMethod> getPatchMethods(Set<CtClass> patchClasses) {
    Set<CtMethod> result = new HashSet<CtMethod>();

    // add all @PatchMethod found in a temporary map
    Map<String, List<CtMethod>> temp = new HashMap<String, List<CtMethod>>();
    for (CtClass patchClass : patchClasses) {
      for (CtMethod ctMethod : patchClass.getDeclaredMethods()) {
        if (ctMethod.hasAnnotation(PatchMethod.class)) {
          if (!Modifier.isStatic(ctMethod.getModifiers())) {
            throw new GwtTestPatchException(
                "@"
                    + PatchMethod.class.getName()
                    + " has to be static : '"
                    + ctMethod.getLongName()
                    + "'");
          }
          String nameAndSignature =
              ctMethod.getName() + Descriptor.toString(ctMethod.getSignature());
          List<CtMethod> correspondingMethods = temp.get(nameAndSignature);

          if (correspondingMethods == null) {
            correspondingMethods = new ArrayList<CtMethod>();
            temp.put(nameAndSignature, correspondingMethods);
          }

          correspondingMethods.add(ctMethod);
        }
      }
    }

    // for each @PatchMethod with the same signature, filter to get one with
    // override=true
    for (Map.Entry<String, List<CtMethod>> entry : temp.entrySet()) {
      CtMethod methodToUse = getMethodToUse(entry.getValue(), PatchMethod.class);
      methodToUse.setModifiers(Modifier.PUBLIC + Modifier.STATIC);
      result.add(methodToUse);
    }

    return result;
  }