/**
  * Generates the test cases for the state machine in {@link StateMachine#getInstance()} and writes
  * the file to the given output path.
  *
  * @param outputClassName The simple name of the generate class containing the generated test
  *     cases
  * @return The source code for the generated test class
  */
 public static String generate(String outputClassName) {
   final StateMachine machine = StateMachine.getInstance();
   final RoundTripPathTreeNode tree = RoundTripPathTreeNode.build(machine.getStartState());
   final List<BodyDeclaration> methods = generateTestMethods(tree);
   final ClassOrInterfaceDeclaration testClass =
       new ClassOrInterfaceDeclaration(ModifierSet.PUBLIC, false, outputClassName);
   testClass.setMembers(methods);
   final CompilationUnit file =
       new CompilationUnit(
           new PackageDeclaration(new NameExpr(machine.getPackageName())),
           generateImports(Assert.class, Test.class),
           Collections.<TypeDeclaration>singletonList(testClass));
   return file.toString();
 }
 // This finds the reflection method for a given name and parameter count and returns its return
 // type.
 // This assumes the methods have no overload on argument types, else it returns a non-existent
 // type to be corrected manually
 // If the method returns void, an exception is thrown as this shouldn't be happening. An
 // exception is also
 // thrown if the class isn't in the class path, which shouldn't happen either
 private static Type getReturnType(String methodName, int paramCount) {
   final Class<?> _class;
   try {
     _class =
         Class.forName(
             StateMachine.getInstance().getPackageName() + "." + getMachineClassName());
   } catch (ClassNotFoundException exception) {
     throw new RuntimeException("Expected state machine class to be in classpath", exception);
   }
   final Method[] methods = _class.getMethods();
   Type match = null;
   for (Method method : methods) {
     // Check for name match
     if (method.getName().equals(methodName)) {
       final int count = method.getParameterTypes().length;
       // Check for param count match, taking into account possible vararg expansion
       if (method.isVarArgs() ? count <= paramCount : count == paramCount) {
         if (match != null) {
           // Got a previous match, so we have an overload conflict on param types
           // This is hard to resolve, just give up, let the user figure it out
           return new ClassOrInterfaceType("FixMeType");
         }
         // Found a (so far) unique match, get the return type
         final Class<?> returnType = method.getReturnType();
         if (returnType == void.class) {
           throw new IllegalStateException("Getter shouldn't be returning void: " + methodName);
         }
         match = fromClass(returnType);
       }
     }
   }
   // We only get here if we find a unique method match
   return match;
 }
 // This returns the simple name of the machine currently loaded
 private static String getMachineClassName() {
   final String javaFileName = StateMachine.getInstance().getClassName();
   return javaFileName.substring(0, javaFileName.lastIndexOf(".java"));
 }