JAL-2089 patch broken merge to master for Release 2.10.0b1
[jalview.git] / src / jalview / bin / Jalview.java
index 8ad4cbd..763b10b 100755 (executable)
  */
 package jalview.bin;
 
+import groovy.lang.Binding;
+import groovy.util.GroovyScriptEngine;
+
+import jalview.ext.so.SequenceOntology;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
+import jalview.gui.PromptUserConfig;
+import jalview.io.AppletFormatAdapter;
 import jalview.io.BioJsHTMLOutput;
+import jalview.io.FileLoader;
+import jalview.io.FormatAdapter;
 import jalview.io.HtmlSvgOutput;
+import jalview.io.IdentifyFile;
+import jalview.io.NewickFile;
+import jalview.io.gff.SequenceOntologyFactory;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.UserColourScheme;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.ws.jws2.Jws2Discoverer;
 
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URL;
-import java.net.URLDecoder;
 import java.security.AllPermission;
 import java.security.CodeSource;
 import java.security.PermissionCollection;
@@ -51,7 +62,6 @@ import java.util.Map;
 import java.util.Vector;
 
 import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
 
 /**
  * Main class for Jalview Application <br>
@@ -63,11 +73,21 @@ import javax.swing.UnsupportedLookAndFeelException;
  */
 public class Jalview
 {
+  /*
+   * singleton instance of this class
+   */
+  private static Jalview instance;
+
+  private Desktop desktop;
+
+  public static AlignFrame currentAlignFrame;
+
   static
   {
     // grab all the rights we can the JVM
     Policy.setPolicy(new Policy()
     {
+      @Override
       public PermissionCollection getPermissions(CodeSource codesource)
       {
         Permissions perms = new Permissions();
@@ -75,6 +95,7 @@ public class Jalview
         return (perms);
       }
 
+      @Override
       public void refresh()
       {
       }
@@ -82,6 +103,71 @@ public class Jalview
   }
 
   /**
+   * keep track of feature fetching tasks.
+   * 
+   * @author JimP
+   * 
+   */
+  class FeatureFetcher
+  {
+    /*
+     * TODO: generalise to track all jalview events to orchestrate batch
+     * processing events.
+     */
+
+    private int queued = 0;
+
+    private int running = 0;
+
+    public FeatureFetcher()
+    {
+
+    }
+
+    public void addFetcher(final AlignFrame af,
+            final Vector<String> dasSources)
+    {
+      final long id = System.currentTimeMillis();
+      queued++;
+      final FeatureFetcher us = this;
+      new Thread(new Runnable()
+      {
+
+        @Override
+        public void run()
+        {
+          synchronized (us)
+          {
+            queued--;
+            running++;
+          }
+
+          af.setProgressBar(MessageManager
+                  .getString("status.das_features_being_retrived"), id);
+          af.featureSettings_actionPerformed(null);
+          af.featureSettings.fetchDasFeatures(dasSources, true);
+          af.setProgressBar(null, id);
+          synchronized (us)
+          {
+            running--;
+          }
+        }
+      }).start();
+    }
+
+    public synchronized boolean allFinished()
+    {
+      return queued == 0 && running == 0;
+    }
+
+  }
+
+  public static Jalview getInstance()
+  {
+    return instance;
+  }
+
+  /**
    * main class for Jalview application
    * 
    * @param args
@@ -89,6 +175,16 @@ public class Jalview
    */
   public static void main(String[] args)
   {
+    instance = new Jalview();
+    instance.doMain(args);
+  }
+
+  /**
+   * @param args
+   */
+  void doMain(String[] args)
+  {
+    System.setSecurityManager(null);
     System.out.println("Java version: "
             + System.getProperty("java.version"));
     System.out.println(System.getProperty("os.arch") + " "
@@ -161,7 +257,7 @@ public class Jalview
     try
     {
       Cache.initLogger();
-    } catch (java.lang.NoClassDefFoundError error)
+    } catch (NoClassDefFoundError error)
     {
       error.printStackTrace();
       System.out
@@ -170,7 +266,7 @@ public class Jalview
       System.exit(0);
     }
 
-    Desktop desktop = null;
+    desktop = null;
 
     try
     {
@@ -178,7 +274,7 @@ public class Jalview
     } catch (Exception ex)
     {
     }
-    if (new Platform().isAMac())
+    if (Platform.isAMac())
     {
       System.setProperty("com.apple.mrj.application.apple.menu.about.name",
               "Jalview");
@@ -187,13 +283,22 @@ public class Jalview
       {
         UIManager.setLookAndFeel(ch.randelshofer.quaqua.QuaquaManager
                 .getLookAndFeel());
-      } catch (UnsupportedLookAndFeelException e)
+      } catch (Throwable e)
       {
-        // TODO Auto-generated catch block
-        e.printStackTrace();
+        System.err.println("Failed to set QuaQua look and feel: "
+                + e.toString());
       }
     }
 
+    /*
+     * configure 'full' SO model if preferences say to, 
+     * else use the default (SO Lite)
+     */
+    if (Cache.getDefault("USE_FULL_SO", false))
+    {
+      SequenceOntologyFactory.setInstance(new SequenceOntology());
+    }
+
     if (!headless)
     {
       desktop = new Desktop();
@@ -234,26 +339,26 @@ public class Jalview
             Cache.log.debug("Starting questionnaire with default url: "
                     + defurl);
             desktop.checkForQuestionnaire(defurl);
-
           }
         }
       }
       else
       {
-        System.err
-.println("CMD [-noquestionnaire] executed successfully!");
+        System.err.println("CMD [-noquestionnaire] executed successfully!");
+      }
+
+      if (!aparser.contains("nonews"))
+      {
+        desktop.checkForNews();
       }
-      desktop.checkForNews();
-    }
 
-    if (!isHeadlessMode())
-    {
       BioJsHTMLOutput.updateBioJS();
     }
 
     String file = null, protocol = null, format = null, data = null;
-    jalview.io.FileLoader fileLoader = new jalview.io.FileLoader(!headless);
-    Vector getFeatures = null; // vector of das source nicknames to fetch
+    FileLoader fileLoader = new FileLoader(!headless);
+    Vector<String> getFeatures = null; // vector of das source nicknames to
+                                       // fetch
     // features from
     // loading is done.
     String groovyscript = null; // script to execute after all loading is
@@ -267,8 +372,8 @@ public class Jalview
       System.out.println("No files to open!");
       System.exit(1);
     }
-    String vamsasImport = aparser.getValue("vdoc"), vamsasSession = aparser
-            .getValue("vsess");
+    String vamsasImport = aparser.getValue("vdoc");
+    String vamsasSession = aparser.getValue("vsess");
     if (vamsasImport != null || vamsasSession != null)
     {
       if (desktop == null || headless)
@@ -283,13 +388,13 @@ public class Jalview
       {
         try
         {
-          String viprotocol = jalview.io.AppletFormatAdapter
+          String viprotocol = AppletFormatAdapter
                   .checkProtocol(vamsasImport);
           if (viprotocol == jalview.io.FormatAdapter.FILE)
           {
             inSession = desktop.vamsasImport(new File(vamsasImport));
           }
-          else if (viprotocol == jalview.io.FormatAdapter.URL)
+          else if (viprotocol == FormatAdapter.URL)
           {
             inSession = desktop.vamsasImport(new URL(vamsasImport));
           }
@@ -358,14 +463,15 @@ public class Jalview
     {
       if (!headless)
       {
-        desktop.setProgressBar(MessageManager.getString("status.processing_commandline_args"),
+        desktop.setProgressBar(MessageManager
+                .getString("status.processing_commandline_args"),
                 progress = System.currentTimeMillis());
       }
       System.out.println("CMD [-open " + file + "] executed successfully!");
 
       if (!file.startsWith("http://"))
       {
-        if (!(new java.io.File(file)).exists())
+        if (!(new File(file)).exists())
         {
           System.out.println("Can't find " + file);
           if (headless)
@@ -375,9 +481,9 @@ public class Jalview
         }
       }
 
-      protocol = jalview.io.AppletFormatAdapter.checkProtocol(file);
+      protocol = AppletFormatAdapter.checkProtocol(file);
 
-      format = new jalview.io.IdentifyFile().Identify(file, protocol);
+      format = new IdentifyFile().identify(file, protocol);
 
       AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
               format);
@@ -387,19 +493,18 @@ public class Jalview
       }
       else
       {
-
+        setCurrentAlignFrame(af);
         data = aparser.getValue("colour", true);
         if (data != null)
         {
           data.replaceAll("%20", " ");
 
-          jalview.schemes.ColourSchemeI cs = jalview.schemes.ColourSchemeProperty
-                  .getColour(af.getViewport().getAlignment(), data);
+          ColourSchemeI cs = ColourSchemeProperty.getColour(af
+                  .getViewport().getAlignment(), data);
 
           if (cs == null)
           {
-            jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
-                    "white");
+            UserColourScheme ucs = new UserColourScheme("white");
             ucs.parseAppletParameter(data);
             cs = ucs;
           }
@@ -416,7 +521,7 @@ public class Jalview
         if (data != null)
         {
           af.parseFeaturesFile(data,
-                  jalview.io.AppletFormatAdapter.checkProtocol(data));
+                  AppletFormatAdapter.checkProtocol(data));
           // System.out.println("Added " + data);
           System.out.println("CMD groups[-" + data
                   + "]  executed successfully!");
@@ -425,7 +530,7 @@ public class Jalview
         if (data != null)
         {
           af.parseFeaturesFile(data,
-                  jalview.io.AppletFormatAdapter.checkProtocol(data));
+                  AppletFormatAdapter.checkProtocol(data));
           // System.out.println("Added " + data);
           System.out.println("CMD [-features " + data
                   + "]  executed successfully!");
@@ -445,8 +550,7 @@ public class Jalview
           af.getViewport().setSortByTree(true);
           if (af.getViewport().getSortByTree())
           {
-            System.out
-.println("CMD [-sortbytree] executed successfully!");
+            System.out.println("CMD [-sortbytree] executed successfully!");
           }
         }
         if (aparser.contains("no-annotation"))
@@ -454,8 +558,7 @@ public class Jalview
           af.getViewport().setShowAnnotation(false);
           if (!af.getViewport().isShowAnnotation())
           {
-            System.out
-.println("CMD no-annotation executed successfully!");
+            System.out.println("CMD no-annotation executed successfully!");
           }
         }
         if (aparser.contains("nosortbytree"))
@@ -475,8 +578,8 @@ public class Jalview
           {
             System.out.println("CMD [-tree " + data
                     + "] executed successfully!");
-            fin = new jalview.io.NewickFile(data,
-                    jalview.io.AppletFormatAdapter.checkProtocol(data));
+            fin = new NewickFile(data,
+                    AppletFormatAdapter.checkProtocol(data));
             if (fin != null)
             {
               af.getViewport().setCurrentTree(
@@ -516,21 +619,10 @@ public class Jalview
         {
           // Execute the groovy script after we've done all the rendering stuff
           // and before any images or figures are generated.
-          if (jalview.bin.Cache.groovyJarsPresent())
-          {
-            System.out.println("Executing script " + groovyscript);
-            executeGroovyScript(groovyscript, new Object[]
-            { desktop, af });
-
-            System.out.println("CMD groovy[" + groovyscript
-                    + "] executed successfully!");
-          }
-          else
-          {
-            System.err
-                    .println("Sorry. Groovy Support is not available, so ignoring the provided groovy script "
-                            + groovyscript);
-          }
+          System.out.println("Executing script " + groovyscript);
+          executeGroovyScript(groovyscript, af);
+          System.out.println("CMD groovy[" + groovyscript
+                  + "] executed successfully!");
           groovyscript = null;
         }
         String imageName = "unnamed.png";
@@ -541,14 +633,14 @@ public class Jalview
 
           if (format.equalsIgnoreCase("png"))
           {
-            af.createPNG(new java.io.File(file));
-            imageName = (new java.io.File(file)).getName();
+            af.createPNG(new File(file));
+            imageName = (new File(file)).getName();
             System.out.println("Creating PNG image: " + file);
             continue;
           }
           else if (format.equalsIgnoreCase("svg"))
           {
-            File imageFile = new java.io.File(file);
+            File imageFile = new File(file);
             imageName = imageFile.getName();
             af.createSVG(imageFile);
             System.out.println("Creating SVG image: " + file);
@@ -556,21 +648,21 @@ public class Jalview
           }
           else if (format.equalsIgnoreCase("html"))
           {
-            File imageFile = new java.io.File(file);
+            File imageFile = new File(file);
             imageName = imageFile.getName();
-            new HtmlSvgOutput(new java.io.File(file), af.alignPanel);
+            new HtmlSvgOutput(new File(file), af.alignPanel);
             System.out.println("Creating HTML image: " + file);
             continue;
           }
           else if (format.equalsIgnoreCase("imgMap"))
           {
-            af.createImageMap(new java.io.File(file), imageName);
+            af.createImageMap(new File(file), imageName);
             System.out.println("Creating image map: " + file);
             continue;
           }
           else if (format.equalsIgnoreCase("eps"))
           {
-            File outputFile = new java.io.File(file);
+            File outputFile = new File(file);
             System.out.println("Creating EPS file: "
                     + outputFile.getAbsolutePath());
             af.createEPS(outputFile);
@@ -630,7 +722,7 @@ public class Jalview
       }
       else
       {
-        format = new jalview.io.IdentifyFile().Identify(file, protocol);
+        format = new IdentifyFile().identify(file, protocol);
       }
 
       startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
@@ -652,11 +744,10 @@ public class Jalview
     // Once all other stuff is done, execute any groovy scripts (in order)
     if (groovyscript != null)
     {
-      if (jalview.bin.Cache.groovyJarsPresent())
+      if (Cache.groovyJarsPresent())
       {
         System.out.println("Executing script " + groovyscript);
-        executeGroovyScript(groovyscript, new Object[]
-        { desktop, startUpAlframe });
+        executeGroovyScript(groovyscript, startUpAlframe);
       }
       else
       {
@@ -693,6 +784,7 @@ public class Jalview
                     + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
                     + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
                     + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
+                    + "-json FILE\tCreate alignment file FILE in JSON format.\n"
                     + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
                     + "-png FILE\tCreate PNG image FILE from alignment.\n"
                     + "-svg FILE\tCreate SVG image FILE from alignment.\n"
@@ -701,6 +793,7 @@ public class Jalview
                     + "-eps FILE\tCreate EPS file FILE from alignment.\n"
                     + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
                     + "-noquestionnaire\tTurn off questionnaire check.\n"
+                    + "-nonews\tTurn off check for Jalview news.\n"
                     + "-nousagestats\tTurn off google analytics tracking for this session.\n"
                     + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
                     // +
@@ -722,8 +815,8 @@ public class Jalview
     /**
      * start a User Config prompt asking if we can log usage statistics.
      */
-    jalview.gui.PromptUserConfig prompter = new jalview.gui.PromptUserConfig(
-            desktop.desktop,
+    PromptUserConfig prompter = new PromptUserConfig(
+            Desktop.desktop,
             "USAGESTATS",
             "Jalview Usage Statistics",
             "Do you want to help make Jalview better by enabling "
@@ -731,6 +824,7 @@ public class Jalview
                     + "\n\n(you can enable or disable usage tracking in the preferences)",
             new Runnable()
             {
+              @Override
               public void run()
               {
                 Cache.log
@@ -740,6 +834,7 @@ public class Jalview
               }
             }, new Runnable()
             {
+              @Override
               public void run()
               {
                 Cache.log.debug("Not enabling Google Tracking.");
@@ -757,14 +852,8 @@ public class Jalview
    *          the Jalview Desktop object passed in to the groovy binding as the
    *          'Jalview' object.
    */
-  private static void executeGroovyScript(String groovyscript,
-          Object[] jalviewContext)
+  private void executeGroovyScript(String groovyscript, AlignFrame af)
   {
-    if (jalviewContext == null)
-    {
-      System.err
-              .println("Sorry. Groovy support is currently only available when running with the Jalview GUI enabled.");
-    }
     /**
      * for scripts contained in files
      */
@@ -781,8 +870,8 @@ public class Jalview
         tfile = File.createTempFile("jalview", "groovy");
         PrintWriter outfile = new PrintWriter(new OutputStreamWriter(
                 new FileOutputStream(tfile)));
-        BufferedReader br = new BufferedReader(
-                new java.io.InputStreamReader(System.in));
+        BufferedReader br = new BufferedReader(new InputStreamReader(
+                System.in));
         String line = null;
         while ((line = br.readLine()) != null)
         {
@@ -846,76 +935,23 @@ public class Jalview
         }
       }
     }
-    boolean success = false;
     try
     {
-      /*
-       * The following code performs the GroovyScriptEngine invocation using
-       * reflection, and is equivalent to this fragment from the embedding
-       * groovy documentation on the groovy site: <code> import
-       * groovy.lang.Binding; import groovy.util.GroovyScriptEngine;
-       * 
-       * String[] roots = new String[] { "/my/groovy/script/path" };
-       * GroovyScriptEngine gse = new GroovyScriptEngine(roots); Binding binding
-       * = new Binding(); binding.setVariable("input", "world");
-       * gse.run("hello.groovy", binding); </code>
-       */
-      Class<?>[] bspec;
-      Object[] binding;
-      int blen = ((jalviewContext[0] == null) ? 0 : 1)
-              + ((jalviewContext[1] == null) ? 0 : 1);
-      String cnames[] = new String[]
-      { "Jalview", "currentAlFrame" };
-      bspec = new Class[blen * 2];
-      binding = new Object[blen * 2];
-      blen = 0;
-      ClassLoader cl = null;
       Map<String, Object> vbinding = new HashMap<String, Object>();
-      for (int jc = 0; jc < jalviewContext.length; jc++)
+      vbinding.put("Jalview", this);
+      if (af != null)
       {
-        if (jalviewContext[jc] != null)
-        {
-          if (cl == null)
-          {
-            cl = jalviewContext[jc].getClass().getClassLoader();
-          }
-          bspec[blen * 2] = String.class;
-          bspec[blen * 2 + 1] = Object.class;
-          binding[blen * 2] = cnames[jc];
-          binding[blen * 2 + 1] = jalviewContext[jc];
-          vbinding.put(cnames[jc], jalviewContext[jc]);
-          blen++;
-        }
+        vbinding.put("currentAlFrame", af);
       }
-      Class<?> gbindingc = cl.loadClass("groovy.lang.Binding");
-      Constructor<?> gbcons;
-      Object gbinding;
-      try
+      Binding gbinding = new Binding(vbinding);
+      GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
+      gse.run(sfile.toString(), gbinding);
+      if ("STDIN".equals(groovyscript))
       {
-        gbcons = gbindingc.getConstructor(Map.class);
-        gbinding = gbcons.newInstance(vbinding);
-      } catch (NoSuchMethodException x)
-      {
-        // old style binding config - using series of string/object values to
-        // setVariable.
-        gbcons = gbindingc.getConstructor();
-        gbinding = gbcons.newInstance();
-        java.lang.reflect.Method setvar = gbindingc.getMethod(
-                "setVariable", bspec);
-        setvar.invoke(gbinding, binding);
+        // delete temp file that we made -
+        // only if it was successfully executed
+        tfile.delete();
       }
-
-      Class<?> gsec = cl.loadClass("groovy.util.GroovyScriptEngine");
-      Constructor<?> gseccons = gsec.getConstructor(new Class[]
-      { URL[].class }); // String[].class });
-      Object gse = gseccons.newInstance(new Object[]
-      { new URL[]
-      { sfile } }); // .toString() } });
-      java.lang.reflect.Method run = gsec.getMethod("run", new Class[]
-      { String.class, gbindingc });
-      run.invoke(gse, new Object[]
-      { sfile.toString(), gbinding });
-      success = true;
     } catch (Exception e)
     {
       System.err.println("Exception Whilst trying to execute file " + sfile
@@ -923,12 +959,6 @@ public class Jalview
       e.printStackTrace(System.err);
 
     }
-    if (success && groovyscript.equals("STDIN"))
-    {
-      // delete temp file that we made - but only if it was successfully
-      // executed
-      tfile.delete();
-    }
   }
 
   /**
@@ -936,16 +966,15 @@ public class Jalview
    * 
    * @return vector of DAS source nicknames to retrieve from
    */
-  private static Vector checkDasArguments(ArgsParser aparser)
+  private static Vector<String> checkDasArguments(ArgsParser aparser)
   {
-    Vector source = null;
+    Vector<String> source = null;
     String data;
     String locsources = Cache.getProperty(Cache.DAS_LOCAL_SOURCE);
     while ((data = aparser.getValue("dasserver", true)) != null)
     {
       String nickname = null;
       String url = null;
-      boolean seq = false, feat = true;
       int pos = data.indexOf('=');
       // determine capabilities
       if (pos > 0)
@@ -975,7 +1004,7 @@ public class Jalview
                         + nickname + "|" + url);
         if (source == null)
         {
-          source = new Vector();
+          source = new Vector<String>();
         }
         source.addElement(nickname);
       }
@@ -993,7 +1022,7 @@ public class Jalview
       System.out.println("adding source '" + data + "'");
       if (source == null)
       {
-        source = new Vector();
+        source = new Vector<String>();
       }
       source.addElement(data);
     }
@@ -1005,7 +1034,8 @@ public class Jalview
    * 
    * @param dasSources
    */
-  private static FeatureFetcher startFeatureFetching(final Vector dasSources)
+  private FeatureFetcher startFeatureFetching(
+          final Vector<String> dasSources)
   {
     FeatureFetcher ff = new FeatureFetcher();
     AlignFrame afs[] = Desktop.getAlignFrames();
@@ -1029,172 +1059,37 @@ public class Jalview
     }
     return false;
   }
-}
-
-/**
- * Notes: this argParser does not distinguish between parameter switches,
- * parameter values and argument text. If an argument happens to be identical to
- * a parameter, it will be taken as such (even though it didn't have a '-'
- * prefixing it).
- * 
- * @author Andrew Waterhouse and JBP documented.
- * 
- */
-
-class rnabuttonlistener implements ActionListener
-{
-  public void actionPerformed(ActionEvent arg0)
-  {
-    System.out.println("Good idea ! ");
-
-  }
-}
 
-class pbuttonlistener implements ActionListener
-{
-  public void actionPerformed(ActionEvent arg0)
+  public AlignFrame[] getAlignFrames()
   {
+    return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
+            : Desktop.getAlignFrames();
 
   }
-}
-
-class ArgsParser
-{
-  Vector vargs = null;
-
-  public ArgsParser(String[] args)
-  {
-    vargs = new Vector();
-    for (int i = 0; i < args.length; i++)
-    {
-      String arg = args[i].trim();
-      if (arg.charAt(0) == '-')
-      {
-        arg = arg.substring(1);
-      }
-      vargs.addElement(arg);
-    }
-  }
 
   /**
-   * check for and remove first occurence of arg+parameter in arglist.
-   * 
-   * @param arg
-   * @return return the argument following the given arg if arg was in list.
+   * Quit method delegates to Desktop.quit - unless running in headless mode
+   * when it just ends the JVM
    */
-  public String getValue(String arg)
-  {
-    return getValue(arg, false);
-  }
-
-  public String getValue(String arg, boolean utf8decode)
+  public void quit()
   {
-    int index = vargs.indexOf(arg);
-    String dc = null, ret = null;
-    if (index != -1)
-    {
-      ret = vargs.elementAt(index + 1).toString();
-      vargs.removeElementAt(index);
-      vargs.removeElementAt(index);
-      if (utf8decode && ret != null)
-      {
-        try
-        {
-          dc = URLDecoder.decode(ret, "UTF-8");
-          ret = dc;
-        } catch (Exception e)
-        {
-          // TODO: log failure to decode
-        }
-      }
-    }
-    return ret;
-  }
-
-  /**
-   * check for and remove first occurence of arg in arglist.
-   * 
-   * @param arg
-   * @return true if arg was present in argslist.
-   */
-  public boolean contains(String arg)
-  {
-    if (vargs.contains(arg))
+    if (desktop != null)
     {
-      vargs.removeElement(arg);
-      return true;
+      desktop.quit();
     }
     else
     {
-      return false;
+      System.exit(0);
     }
   }
 
-  public String nextValue()
-  {
-    return vargs.remove(0).toString();
-  }
-
-  public int getSize()
-  {
-    return vargs.size();
-  }
-
-}
-
-/**
- * keep track of feature fetching tasks.
- * 
- * @author JimP
- * 
- */
-class FeatureFetcher
-{
-  /*
-   * TODO: generalise to track all jalview events to orchestrate batch
-   * processing events.
-   */
-
-  private int queued = 0;
-
-  private int running = 0;
-
-  public FeatureFetcher()
-  {
-
-  }
-
-  public void addFetcher(final AlignFrame af, final Vector dasSources)
+  public static AlignFrame getCurrentAlignFrame()
   {
-    final long id = System.currentTimeMillis();
-    queued++;
-    final FeatureFetcher us = this;
-    new Thread(new Runnable()
-    {
-
-      public void run()
-      {
-        synchronized (us)
-        {
-          queued--;
-          running++;
-        }
-
-        af.setProgressBar(MessageManager.getString("status.das_features_being_retrived"), id);
-        af.featureSettings_actionPerformed(null);
-        af.featureSettings.fetchDasFeatures(dasSources, true);
-        af.setProgressBar(null, id);
-        synchronized (us)
-        {
-          running--;
-        }
-      }
-    }).start();
+    return Jalview.currentAlignFrame;
   }
 
-  public synchronized boolean allFinished()
+  public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
   {
-    return queued == 0 && running == 0;
+    Jalview.currentAlignFrame = currentAlignFrame;
   }
-
 }