gt:                             if (jars != null) {
context: // ========================================================================
  // Copyright (c) 2002 Mort Bay Consulting (Australia) Pty. Ltd.
  // $Id$
  // ========================================================================
  /**
   * This is an adopted version of the corresponding classes shipped
   * with Jetty.
   */
  package org.exist.start;
  
  import java.io.*;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.util.ArrayList;
  import java.util.Hashtable;
  import java.util.List;
  import java.util.StringTokenizer;
  
  /**
   * @author Jan Hlavaty (hlavac@code.cz)
   * @author Wolfgang Meier (meier@ifs.tu-darmstadt.de)
   * @version $Revision$
   *          <p/>
   *          TODO:
   *          - finish possible jetty.home locations
   *          - use File.toURI.toURL() on JDK 1.4+
   *          - better handling of errors (i.e. when jetty.home cannot be autodetected...)
   *          - include entries from lib _when needed_
   */
  public class Main {
  
      private String _classname = null;
      
      private String _mode = "jetty";
  
      private static Main exist;
  
      private boolean _debug = Boolean.getBoolean("exist.start.debug");
  
      // Stores the path to the "start.config" file that's used to configure
      // the runtime classpath.
      private String startConfigFileName = "";
  
      // Used to find latest version of jar files that should be added to the
      // classpath.
      private final LatestFileResolver jarFileResolver = new LatestFileResolver();
  
      public static void main(String[] args) {
          try {
              getMain().run(args);
  
          } catch (final Exception e) {
              e.printStackTrace();
          }
      }
  
      /**
       * Singleton Factory Method
       */
      public static Main getMain() {
          if (exist == null) {
              exist = new Main();
          }
          return exist;
      }
  
      public String getMode() {
          return this._mode;
      }
  
      private Main() {
      }
  
      public Main(String mode) {
          this._mode = mode;
      }
  
      static File getDirectory(String name) {
          try {
              if (name != null) {
                  final File dir = new File(name).getCanonicalFile();
                  if (dir.isDirectory()) {
                      return dir;
                  }
              }
          } catch (final IOException e) {
              // NOP
          }
          return null;
      }
  
      boolean isAvailable(String classname, Classpath classpath) {
          try {
              Class.forName(classname);
              return true;
  
          } catch (final ClassNotFoundException e) {
              //ignore
          }
  
          final ClassLoader loader = classpath.getClassLoader(null);
          try {
              loader.loadClass(classname);
              return true;
  
          } catch (final ClassNotFoundException e) {
              //ignore
          }
  
          return false;
      }
  
      public static void invokeMain(ClassLoader classloader, String classname, String[] args)
              throws IllegalAccessException, InvocationTargetException,
              NoSuchMethodException, ClassNotFoundException {
  
          final Class<?> invoked_class = classloader.loadClass(classname);
  
          final Class<?>[] method_param_types = new Class[1];
          method_param_types[0] = args.getClass();
  
          final Method main = invoked_class.getDeclaredMethod("main", method_param_types);
  
          final Object[] method_params = new Object[1];
          method_params[0] = args;
          main.invoke(null, method_params);
      }
  
      void configureClasspath(String home, Classpath classpath, InputStream config, String[] args, String mode) {
  
          // Any files referenced in start.config that don't exist or cannot be resolved
          // are placed in this list.
          final List<String> invalidJars = new ArrayList<String>();
  
          try {
              final BufferedReader cfg = new BufferedReader(new InputStreamReader(config, "ISO-8859-1"));
              final Version java_version = new Version(System.getProperty("java.version"));
              final Version ver = new Version();
  
              // JAR's already processed
              final Hashtable<String, String> done = new Hashtable<String, String>();
              String line = cfg.readLine();
  
              while (line != null) {
                  try {
                      if ((line.length() > 0) && (!line.startsWith("#"))) {
  
                          if (_debug) {
                              System.err.println(">" + line);
                          }
  
                          final StringTokenizer st = new StringTokenizer(line);
                          final String subject = st.nextToken();
  
                          boolean include_subject = true;
                          String condition = null;
  
                          while (include_subject && st.hasMoreTokens()) {
                              condition = st.nextToken();
                              if ("never".equals(condition)) {
                                  include_subject = false;
  
                              } else if ("always".equals(condition)) {
                                  // ignore
  
                              } else if ("available".equals(condition)) {
                                  final String class_to_check = st.nextToken();
                                  include_subject &= isAvailable(class_to_check, classpath);
  
                              } else if ("!available".equals(condition)) {
                                  final String class_to_check = st.nextToken();
                                  include_subject &= !isAvailable(class_to_check, classpath);
  
                              } else if ("java".equals(condition)) {
                                  final String operator = st.nextToken();
                                  final String version = st.nextToken();
                                  ver.parse(version);
                                  include_subject &= ("<".equals(operator) && java_version.compare(ver) < 0)
                                          || (">".equals(operator) && java_version.compare(ver) > 0)
                                          || ("<=".equals(operator) && java_version.compare(ver) <= 0)
                                          || ("=<".equals(operator) && java_version.compare(ver) <= 0)
                                          || ("=>".equals(operator) && java_version.compare(ver) >= 0)
                                          || (">=".equals(operator) && java_version.compare(ver) >= 0)
                                          || ("==".equals(operator) && java_version.compare(ver) == 0)
                                          || ("!=".equals(operator) && java_version.compare(ver) != 0);
  
                              } else if ("nargs".equals(condition)) {
                                  final String operator = st.nextToken();
                                  final int number = Integer.parseInt(st.nextToken());
                                  include_subject &= ("<".equals(operator) && args.length < number)
                                          || (">".equals(operator) && args.length > number)
                                          || ("<=".equals(operator) && args.length <= number)
                                          || ("=<".equals(operator) && args.length <= number)
                                          || ("=>".equals(operator) && args.length >= number)
                                          || (">=".equals(operator) && args.length >= number)
                                          || ("==".equals(operator) && args.length == number)
                                          || ("!=".equals(operator) && args.length != number);
  
                              } else if ("mode".equals(condition)) {
                                  final String operator = st.nextToken();
                                  final String m = st.nextToken();
                                  include_subject &= ("==".equals(operator) && mode.equals(m))
                                          || ("!=".equals(operator) && (!mode.equals(m)));
  
                              } else {
                                  System.err.println("ERROR: Unknown condition: " + condition);
                              }
                          }
  
                          final String file =
                                  subject.startsWith("/")
                                  ? subject.replace('/', File.separatorChar)
                                  : home + File.separatorChar + subject.replace('/', File.separatorChar);
  
                          if (_debug) {
                              System.err.println("subject=" + subject + " file=" + file
                                      + " condition=" + condition + " include_subject=" + include_subject);
                          }
  
                          // ok, should we include?
                          if (subject.endsWith("/*")) {
                              // directory of JAR files
                              final File extdir = new File(file.substring(0, file.length() - 1));
                              final File[] jars = extdir.listFiles(new FilenameFilter() {
                                  public boolean accept(File dir, String name) {
                                      String namelc = name.toLowerCase();
                                      return namelc.endsWith(".jar") || name.endsWith(".zip");
                                  }
                              });
  
  