public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod) {
    // Update the descriptor if it has any unused parameters.
    String descriptor = programMethod.getDescriptor(programClass);
    String newDescriptor = shrinkDescriptor(programMethod, descriptor);

    if (!descriptor.equals(newDescriptor)) {
      // Shrink the signature and parameter annotations.
      programMethod.attributesAccept(programClass, this);

      String name = programMethod.getName(programClass);
      String newName = name;

      // Append a code, if the method isn't a class instance initializer.
      if (!name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)) {
        newName +=
            ClassConstants.SPECIAL_MEMBER_SEPARATOR
                + Long.toHexString(Math.abs((descriptor).hashCode()));
      }

      if (DEBUG) {
        System.out.println("MethodDescriptorShrinker:");
        System.out.println("  Class file        = " + programClass.getName());
        System.out.println("  Method name       = " + name);
        System.out.println("                   -> " + newName);
        System.out.println("  Method descriptor = " + descriptor);
        System.out.println("                   -> " + newDescriptor);
      }

      ConstantPoolEditor constantPoolEditor = new ConstantPoolEditor(programClass);

      // Update the name, if necessary.
      if (!newName.equals(name)) {
        programMethod.u2nameIndex = constantPoolEditor.addUtf8Constant(newName);
      }

      // Update the referenced classes.
      programMethod.referencedClasses =
          shrinkReferencedClasses(programMethod, descriptor, programMethod.referencedClasses);

      // Finally, update the descriptor itself.
      programMethod.u2descriptorIndex = constantPoolEditor.addUtf8Constant(newDescriptor);

      // Visit the method, if required.
      if (extraMemberVisitor != null) {
        extraMemberVisitor.visitProgramMethod(programClass, programMethod);
      }
    }
  }
  public void visitProgramClass(ProgramClass programClass) {
    if (DEBUG) {
      System.out.println("SimpleEnumClassSimplifier: [" + programClass.getName() + "]");
    }

    // Unmark the class as an enum.
    programClass.u2accessFlags &= ~ClassConstants.ACC_ENUM;

    // Remove the valueOf method, if present.
    Method valueOfMethod = programClass.findMethod(ClassConstants.METHOD_NAME_VALUEOF, null);
    if (valueOfMethod != null) {
      new ClassEditor(programClass).removeMethod(valueOfMethod);
    }

    // Simplify the static initializer.
    programClass.methodAccept(
        ClassConstants.METHOD_NAME_CLINIT,
        ClassConstants.METHOD_TYPE_CLINIT,
        initializerSimplifier);
  }