content: import otherpackage.OtherPackagePublicEnum;
  
  import java.lang.reflect.*;
  
  public class Main {
      /** used by {@link #basisCall} */
      static private int basisTestValue = 12;
  
      static public void main(String[] args) throws Exception {
          try {
              Class<?> enumClass = Enum.class;
              Method enumValueOf = null;
              for (Method m : enumClass.getDeclaredMethods()) {
                  if (m.getName().equals("valueOf")) {
                      enumValueOf = m;
                      break;
                  }
              }
              enumValueOf.invoke(null, String.class, "blah");
              throw new AssertionError();
          } catch (InvocationTargetException expected) {
              IllegalArgumentException iae = (IllegalArgumentException) expected.getCause();
              if (!iae.getMessage().equals("class java.lang.String is not an enum type.")) {
                  throw new AssertionError();
              }
          }
  
          boolean timing = (args.length >= 1) && args[0].equals("--timing");
          run(timing);
      }
  
      static public void run(boolean timing) {
          preTest();
  
          long time0 = System.nanoTime();
          int count1 = test1(500);
          long time1 = System.nanoTime();
          int count2 = test2(500);
          long time2 = System.nanoTime();
          int count3 = test3(500);
          long time3 = System.nanoTime();
          int count4 = basis(500);
          long time4 = System.nanoTime();
  
          System.out.println("basis: performed " + count4 + " iterations");
          System.out.println("test1: performed " + count1 + " iterations");
          System.out.println("test2: performed " + count2 + " iterations");
          System.out.println("test3: performed " + count3 + " iterations");
  
          double msec1 = (time1 - time0) / (double) count1 / 1000000;
          double msec2 = (time2 - time1) / (double) count2 / 1000000;
          double msec3 = (time3 - time2) / (double) count3 / 1000000;
          double basisMsec = (time4 - time3) / (double) count4 / 1000000;
  
          double avg = (msec1 + msec2 + msec3) / 3;
          if (avg < (basisMsec * 10)) {
              System.out.println("Timing is acceptable.");
          } else {
              System.out.println("Iterations are taking too long!");
              timing = true;
          }
  
          if (timing) {
              System.out.printf("basis time: %.3g msec\n", basisMsec);
              System.out.printf("test1: %.3g msec per iteration\n", msec1);
              System.out.printf("test2: %.3g msec per iteration\n", msec2);
              System.out.printf("test3: %.3g msec per iteration\n", msec3);
          }
  
      }
  
      static public void preTest() {
          /*
           * This is meant to ensure that the basic enum functionality
           * really is working.
           */
  
          Class<SamePackagePublicEnum> c = SamePackagePublicEnum.class;
  
          System.out.println(Enum.valueOf(c, "FOUR"));
          System.out.println(Enum.valueOf(c, "ONE"));
          System.out.println(Enum.valueOf(c, "FOURTEEN"));
          System.out.println(Enum.valueOf(c, "NINE"));
          System.out.println(Enum.valueOf(c, "FIVE"));
          System.out.println(Enum.valueOf(c, "TWELVE"));
  
          System.out.println(Enum.valueOf(c, "ZERO").getClass().getName());
      }
  
      static final String[] BASIS_COMPARE_ARRAY = {
          "ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT",
          "NINE", "TEN", "ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN", "FIFTEEN",
          "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"
      };
  
      static public int basis(int iters) {
          for (int i = iters; i > 0; i--) {
              basisValueOf("ZERO");
              basisValueOf("ONE");
              basisValueOf("TWO");
              basisValueOf("THREE");
              basisValueOf("FOUR");
              basisValueOf("FIVE");
              basisValueOf("SIX");
              basisValueOf("SEVEN");
              basisValueOf("EIGHT");
              basisValueOf("NINE");
              basisValueOf("TEN");
              basisValueOf("ELEVEN");
              basisValueOf("TWELVE");
              basisValueOf("THIRTEEN");
              basisValueOf("FOURTEEN");
              basisValueOf("FIFTEEN");
              basisValueOf("SIXTEEN");
              basisValueOf("SEVENTEEN");
              basisValueOf("EIGHTEEN");
              basisValueOf("NINETEEN");
          }
  
          return iters * 20;
      }
  
      static String basisValueOf(String key) {
          for (String s : BASIS_COMPARE_ARRAY) {
              if (s.equals(key)) {
                  return s;
              }
          }
          throw new IllegalArgumentException();
      }
  
      static public int test1(int iters) {
          Class<SamePackagePublicEnum> c = SamePackagePublicEnum.class;
          for (int i = iters; i > 0; i--) {
              Enum.valueOf(c, "ZERO");
              Enum.valueOf(c, "ONE");
              Enum.valueOf(c, "TWO");
              Enum.valueOf(c, "THREE");
              Enum.valueOf(c, "FOUR");
              Enum.valueOf(c, "FIVE");
              Enum.valueOf(c, "SIX");
              Enum.valueOf(c, "SEVEN");
              Enum.valueOf(c, "EIGHT");
              Enum.valueOf(c, "NINE");
              Enum.valueOf(c, "TEN");
              Enum.valueOf(c, "ELEVEN");
              Enum.valueOf(c, "TWELVE");
              Enum.valueOf(c, "THIRTEEN");
              Enum.valueOf(c, "FOURTEEN");
              Enum.valueOf(c, "FIFTEEN");
              Enum.valueOf(c, "SIXTEEN");
              Enum.valueOf(c, "SEVENTEEN");
              Enum.valueOf(c, "EIGHTEEN");
              Enum.valueOf(c, "NINETEEN");
          }
  
          return iters * 20;
      }
  
      static public int test2(int iters) {
          Class<SamePackagePrivateEnum> c = SamePackagePrivateEnum.class;
          for (int i = iters; i > 0; i--) {
              Enum.valueOf(c, "ZERO");
              Enum.valueOf(c, "ONE");
              Enum.valueOf(c, "TWO");
              Enum.valueOf(c, "THREE");
              Enum.valueOf(c, "FOUR");
              Enum.valueOf(c, "FIVE");
              Enum.valueOf(c, "SIX");
              Enum.valueOf(c, "SEVEN");
              Enum.valueOf(c, "EIGHT");
              Enum.valueOf(c, "NINE");
              Enum.valueOf(c, "TEN");
              Enum.valueOf(c, "ELEVEN");
              Enum.valueOf(c, "TWELVE");
              Enum.valueOf(c, "THIRTEEN");
              Enum.valueOf(c, "FOURTEEN");
              Enum.valueOf(c, "FIFTEEN");
              Enum.valueOf(c, "SIXTEEN");
              Enum.valueOf(c, "SEVENTEEN");
              Enum.valueOf(c, "EIGHTEEN");
              Enum.valueOf(c, "NINETEEN");
          }
  
          return iters * 20;
      }
  
      static public int test3(int iters) {
          Class<OtherPackagePublicEnum> c = OtherPackagePublicEnum.class;
          for (int i = iters; i > 0; i--) {
              Enum.valueOf(c, "ZERO");
              Enum.valueOf(c, "ONE");
              Enum.valueOf(c, "TWO");
              Enum.valueOf(c, "THREE");
              Enum.valueOf(c, "FOUR");
              Enum.valueOf(c, "FIVE");
              Enum.valueOf(c, "SIX");
              Enum.valueOf(c, "SEVEN");
              Enum.valueOf(c, "EIGHT");
              Enum.valueOf(c, "NINE");
              Enum.valueOf(c, "TEN");
              Enum.valueOf(c, "ELEVEN");
              Enum.valueOf(c, "TWELVE");
              Enum.valueOf(c, "THIRTEEN");
              Enum.valueOf(c, "FOURTEEN");
              Enum.valueOf(c, "FIFTEEN");
              Enum.valueOf(c, "SIXTEEN");
              Enum.valueOf(c, "SEVENTEEN");
              Enum.valueOf(c, "EIGHTEEN");
              Enum.valueOf(c, "NINETEEN");
          }
  
          return iters * 20;
      }
  }
  