JodeClass.setClassPath(cp.toString());
setClasspath(cp.toString());
  public static void main(String[] args)      throws NoSuchMethodException, IllegalAccessException, IOException, ClassNotFoundException {    // Scan the arguments until the end of keywords is reached, interpreting    // all the intermediate arguments and dealing with them as appropriate.    int i = 0;    boolean zipIt = true;    String fileName = null;    if (i < args.length && "unzip".equals(args[i])) {      zipIt = false;      i++;    }    if (i < args.length && "as".equals(args[i])) {      fileName = args[++i];      i++;    }    // The next word indicates the method used to decide whether an ambiguous    // argument of the form a.b.c is a class or a package. Any other word is an    // error, but checks further down will catch that.    int disambig = UNSPECIFIED;    if (i < args.length) {      if ("explicitly".equals(args[i])) {        disambig = EXPLICITLY;      } else if ("apis".equals(args[i])) {        disambig = APIS;      } else if ("byname".equals(args[i])) {        disambig = BYNAME;      } else if ("packages".equals(args[i])) {        disambig = PACKAGES;      } else if ("classes".equals(args[i])) {        disambig = CLASSES;      }      i++;    }    // Correct syntax requires that one of the previous cases must have matched,    // and also that there be at least one more word. Both these cases, however,    // can be errored below because they will result in both the path and the    // set of roots being empty.    if (i < args.length && disambig != UNSPECIFIED) {      // Identify each argument that's prefixed with + or - and put it in      // either the "roots" or the "exclusions" TreeSet as appropriate. Use      // the disambiguation method specified above for arguments that do not      // explicitly indicate if they are classes or packages.      for (; i < args.length; i++) {        char first = args[i].charAt(0);        String pkgpath = args[i].substring(1);        if (first == '+' || first == '-') {          SortedSet setToAddTo = first == '+' ? roots : exclusions;          // First identify *whether* it's ambiguous - and whether it's legal.          int commapos = pkgpath.indexOf(',');                    // If it contains a comma, and doesn't have a dot or a comma after          // that, then it's unambiguous.          if (commapos >= 0) {            if (pkgpath.indexOf(',', commapos + 1) >= 0 ||                pkgpath.indexOf('.', commapos + 1) >= 0) {              System.err.println("Illegal package/class name " + pkgpath +                                 " - skipping");            } else {              setToAddTo.add(pkgpath);            }          // Otherwise it's ambiguous. Figure out what to do based on the          // disambiguation rule set above.          } else {            switch (disambig) {              case EXPLICITLY:                System.err.println("Ambiguous package/class name " + pkgpath +                                   " not allowed with 'explicitly' - skipping");                break;              case APIS:                setToAddTo.add(toClassRoot(pkgpath));                setToAddTo.add(pkgpath + ",");                break;              case BYNAME:                int dotpos = pkgpath.lastIndexOf('.');                if (Character.isUpperCase(pkgpath.charAt(dotpos + 1))) {                  setToAddTo.add(toClassRoot(pkgpath));                } else {                  setToAddTo.add(pkgpath + ",");                }                break;              case PACKAGES:                setToAddTo.add(pkgpath + ",");                break;              case CLASSES:                setToAddTo.add(toClassRoot(pkgpath));                break;            }          }        // If it doesn't start with + or -, it's a path component.        } else {          path.add(args[i]);        }      }    }    if (path.isEmpty() || roots.isEmpty()) printUsage();    // If we are using Jode, we need to initialize Jode's classpath to    // find classes in the correct location.    StringBuffer cp = new StringBuffer();    for (Iterator j = path.iterator(); j.hasNext(); ) {      if (cp.length() > 0) cp.append(File.pathSeparatorChar);      cp.append(j.next());    }    JodeClass.setClassPath(cp.toString());    // Figure out what output writer to use.    if (fileName == null) {      if (zipIt) {        System.err.println("Note: for correct operation of tools that read japi files, it is strongly");        System.err.println("recommended to use a filename ending in japi.gz for a compressed japi file.");        out = new PrintWriter(new GZIPOutputStream(System.out));      } else {        System.err.println("Note: for correct operation of tools that read japi files, it is strongly");        System.err.println("recommended to use a filename ending in japi for an uncompressed japi file.");        out = new PrintWriter(System.out);      }    } else {      // Japize will only create output to files ending in .japi (uncompressed)      // or .japi.gz (compressed). It enforces this rule by adding .japi and .gz      // to the specified filename if it doesn't already have them. If the user      // specifies a .gz extension for uncompressed output, this is flagged as      // an error - if it's really what they meant, they can specify x.gz.japi.      if (fileName.endsWith(".gz")) {        if (!zipIt) {          System.err.println("Filename ending in .gz specified without zip output enabled.");          System.err.println("Please either omit 'unzip' or specify a different filename (did you");          System.err.println("mean '" + fileName + ".japi'?)");          System.exit(1);        }        // Trim ".gz" off the end. It'll be re-added later, but ".japi" might        // be inserted first.        fileName = fileName.substring(0, fileName.length() - 3);      }      // Add ".japi" if it's not already there.      if (!fileName.endsWith(".japi")) fileName += ".japi";      // Produce an output writer - compressed or not, as appropriate.      if (zipIt) {        out = new PrintWriter(new GZIPOutputStream(new BufferedOutputStream(              new FileOutputStream(fileName + ".gz"))));      } else {        out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));      }    }    // Now actually go and japize the classes.    doJapize();    out.close();  }