Merge branch 'kjvdh/features/PhylogenyViewer_tabbedsupport' into merge/2_11_2/kjvdh...
authorJim Procter <j.procter@dundee.ac.uk>
Thu, 2 Jun 2022 15:05:51 +0000 (16:05 +0100)
committerJim Procter <j.procter@dundee.ac.uk>
Thu, 2 Jun 2022 15:05:51 +0000 (16:05 +0100)
Update from Release 2.11.2 develop branch JAL-1953
 Conflicts:
.classpath
.project
resources/lang/Messages.properties
src/jalview/bin/Jalview.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/fts/core/GFTSPanel.java
src/jalview/fts/service/pdb/PDBFTSPanel.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/CalculationChooser.java
src/jalview/gui/DasSourceBrowser.java
src/jalview/gui/Desktop.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/SplashScreen.java
src/jalview/gui/StructureViewerBase.java
src/jalview/gui/TreePanel.java
src/jalview/gui/WebserviceInfo.java
src/jalview/io/BioJsHTMLOutput.java
src/jalview/io/FileLoader.java
src/jalview/io/HtmlSvgOutput.java
src/jalview/io/NewickFile.java
src/jalview/math/Matrix.java
src/jalview/math/MatrixI.java
src/jalview/util/MappingUtils.java
src/jalview/ws/DBRefFetcher.java
src/jalview/ws/DasSequenceFeatureFetcher.java
src/jalview/ws/jws2/Jws2Discoverer.java
utils/eclipse/org.eclipse.jdt.core.jalview.prefs
utils/eclipse/org.eclipse.jdt.ui.prefs

38 files changed:
1  2 
resources/lang/Messages.properties
src/jalview/analysis/TreeModel.java
src/jalview/appletgui/OverviewPanel.java
src/jalview/appletgui/PCAPanel.java
src/jalview/appletgui/TreePanel.java
src/jalview/bin/Jalview.java
src/jalview/fts/service/pdb/PDBFTSPanel.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AppJmol.java
src/jalview/gui/CalculationChooser.java
src/jalview/gui/ChimeraViewFrame.java
src/jalview/gui/Console.java
src/jalview/gui/Desktop.java
src/jalview/gui/JalviewDialog.java
src/jalview/gui/OverviewPanel.java
src/jalview/gui/PaintRefresher.java
src/jalview/gui/RedundancyPanel.java
src/jalview/gui/StructureViewerBase.java
src/jalview/gui/TreeCanvas.java
src/jalview/gui/TreePanel.java
src/jalview/gui/VamsasApplication.java
src/jalview/gui/WebserviceInfo.java
src/jalview/gui/WsPreferences.java
src/jalview/io/BioJsHTMLOutput.java
src/jalview/io/FileLoader.java
src/jalview/io/NewickFile.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/math/Matrix.java
src/jalview/math/MatrixI.java
src/jalview/util/AWTConsole.java
src/jalview/util/MappingUtils.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/ws/DBRefFetcher.java
src/jalview/ws/jws1/Discoverer.java
src/jalview/ws/jws2/Jws2Discoverer.java
test/jalview/gui/FreeUpMemoryTest.java
test/jalview/io/NewickFileTests.java
utils/eclipse/org.eclipse.jdt.core.jalview.prefs

@@@ -554,10 -559,13 +557,10 @@@ label.right_align_sequence_id = Right A
  label.sequence_id_tooltip = Sequence ID Tooltip
  label.no_services = <No Services>
  label.select_copy_raw_html = Select this if you want to copy raw html
 -label.share_data_vamsas_applications = Share data with other vamsas applications
 -label.connect_to = Connect to
 -label.join_existing_vamsas_session = Join an existing vamsas session
 -label.from_url = From URL
 +label.from_url = from URL
  label.any_trees_calculated_or_loaded_alignment_automatically_sort = When selected, any trees calculated or loaded onto the alignment will automatically sort the alignment
  label.sort_with_new_tree = Sort With New Tree
- label.from_textbox = from Textbox
+ label.from_textbox = From Textbox
  label.window = Window
  label.preferences = Preferences
  label.tools = Tools
@@@ -1045,12 -1068,11 +1048,13 @@@ exception.pfam_no_sequences_found = No 
  exception.stockholm_invalid_format = This file is not in valid STOCKHOLM format: First line does not contain '# STOCKHOLM'
  exception.couldnt_parse_sequence_line = Could not parse sequence line: {0}
  exception.unknown_annotation_detected = Unknown annotation detected: {0} {1}
 -exception.couldnt_store_sequence_mappings = Couldn't store sequence mappings for {0}
 +exception.couldnt_store_sequence_mappings = Couldn''t store sequence mappings for {0}
  exception.matrix_too_many_iteration = Too many iterations in {0} (max is {1})
+ exception.invalid_matrix_identifier = Sequence identifier {0} not found in distance matrix.
  exception.browser_not_found = Exception in finding browser: {0}
 +exception.browser_unable_to_launch = Unable to launch browser: {0}
  exception.browser_unable_to_locate = Unable to locate browser: {0}
 +exception.browser_os_not_supported = Launching browser on this operating system not supported.  Use URL\n{0}
  exception.invocation_target_exception_creating_aedesc = InvocationTargetException while creating AEDesc: {0}
  exception.illegal_access_building_apple_evt= IllegalAccessException while building AppleEvent: {0}
  exception.unable_to_launch_url = Unable to launch URL: {0}
@@@ -147,17 -144,17 +145,17 @@@ public class TreeMode
  
        if (namesleft > -1)
        {
-         nam = algnIds.findIdMatch(realnam);
+         nodeSequence = algnIds.findIdMatch(nodeSequenceName);
        }
  
-       if (nam != null)
+       if (nodeSequence != null)
        {
-         j.setElement(nam);
-         if (one2many.contains(nam))
+         sn.setElement(nodeSequence);
+         if (one2many.contains(nodeSequence))
          {
            // countOne2Many++;
 -          // if (jalview.bin.Cache.log.isDebugEnabled())
 -          // jalview.bin.Cache.log.debug("One 2 many relationship for
 +          // if (Cache.isDebugEnabled())
 +          // Cache.debug("One 2 many relationship for
            // "+nam.getName());
          }
          else
        }
        else
        {
-         j.setElement(new Sequence(realnam, "THISISAPLACEHLDER"));
-         j.setPlaceholder(true);
+         sn.setElement(new Sequence(nodeSequenceName, "THISISAPLACEHLDER"));
+         sn.setPlaceholder(true);
        }
      }
 -    // if (jalview.bin.Cache.log.isDebugEnabled() && countOne2Many>0) {
 -    // jalview.bin.Cache.log.debug("There were "+countOne2Many+" alignment
 +    // if (Cache.isDebugEnabled() && countOne2Many>0) {
 +    // Cache.debug("There were "+countOne2Many+" alignment
      // sequence ids (out of "+one2many.size()+" unique ids) linked to two or
      // more leaves.");
      // }
Simple merge
Simple merge
@@@ -37,45 -58,14 +37,48 @@@ import java.security.PermissionCollecti
  import java.security.Permissions;
  import java.security.Policy;
  import java.util.HashMap;
 +import java.util.Locale;
  import java.util.Map;
  import java.util.Vector;
 +import java.util.logging.ConsoleHandler;
 +import java.util.logging.Level;
 +import java.util.logging.Logger;
  
  import javax.swing.UIManager;
 +import javax.swing.UIManager.LookAndFeelInfo;
 +
 +import com.threerings.getdown.util.LaunchUtil;
 +
 +//import edu.stanford.ejalbert.launching.IBrowserLaunching;
 +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.DataSourceType;
 +import jalview.io.FileFormat;
 +import jalview.io.FileFormatException;
 +import jalview.io.FileFormatI;
 +import jalview.io.FileFormats;
 +import jalview.io.FileLoader;
 +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.util.ChannelProperties;
 +import jalview.util.HttpUtils;
 +import jalview.util.MessageManager;
 +import jalview.util.Platform;
 +import jalview.ws.jws2.Jws2Discoverer;
  
+ import groovy.lang.Binding;
+ import groovy.util.GroovyScriptEngine;
  /**
   * Main class for Jalview Application <br>
   * <br>
@@@ -223,8 -220,9 +223,8 @@@ public class PDBFTSPanel extends GFTSPa
      }
  
      String ids = selectedIds.toString();
 -    // System.out.println(">>>>>>>>>>>>>>>> selected Ids: " + ids);
 -    seqFetcher.getTextArea().setText(ids);
 +    seqFetcher.setQuery(ids);
-     Thread worker = new Thread(seqFetcher);
+     Thread worker = new Thread(seqFetcher, "PDBFTSSeqFetcherThread");
      worker.start();
      delayAndEnableActionButtons();
    }
    {
      return PDB_AUTOSEARCH;
    }
 -}
 +
 +  @Override
 +  protected void showHelp()
 +  {
 +    try
 +    {
 +      Help.showHelpWindow(HelpId.PdbFts);
 +    } catch (HelpSetException e1)
 +    {
 +      e1.printStackTrace();
 +    }
 +  }
- }
++}
   */
  package jalview.gui;
  
 +import java.util.Locale;
+ import jalview.analysis.AlignmentSorter;
+ import jalview.analysis.AlignmentUtils;
+ import jalview.analysis.CrossRef;
+ import jalview.analysis.Dna;
+ import jalview.analysis.ParseProperties;
+ import jalview.analysis.SequenceIdMatcher;
+ import jalview.analysis.TreeModel;
+ import jalview.api.AlignExportSettingI;
+ import jalview.api.AlignViewControllerGuiI;
+ import jalview.api.AlignViewControllerI;
+ import jalview.api.AlignViewportI;
+ import jalview.api.AlignmentViewPanel;
+ import jalview.api.FeatureSettingsControllerI;
+ import jalview.api.SplitContainerI;
+ import jalview.api.ViewStyleI;
+ import jalview.bin.Cache;
+ import jalview.bin.Jalview;
+ import jalview.commands.CommandI;
+ import jalview.commands.EditCommand;
+ import jalview.commands.EditCommand.Action;
+ import jalview.commands.OrderCommand;
+ import jalview.commands.RemoveGapColCommand;
+ import jalview.commands.RemoveGapsCommand;
+ import jalview.commands.SlideSequencesCommand;
+ import jalview.commands.TrimRegionCommand;
+ import jalview.datamodel.AlignedCodonFrame;
+ import jalview.datamodel.Alignment;
+ import jalview.datamodel.AlignmentAnnotation;
+ import jalview.datamodel.AlignmentExportData;
+ import jalview.datamodel.AlignmentI;
+ import jalview.datamodel.AlignmentOrder;
+ import jalview.datamodel.AlignmentView;
+ import jalview.datamodel.ColumnSelection;
+ import jalview.datamodel.HiddenColumns;
+ import jalview.datamodel.HiddenSequences;
+ import jalview.datamodel.PDBEntry;
+ import jalview.datamodel.SeqCigar;
+ import jalview.datamodel.Sequence;
+ import jalview.datamodel.SequenceGroup;
+ import jalview.datamodel.SequenceI;
+ import jalview.ext.archaeopteryx.AptxInit;
+ import jalview.ext.forester.io.SupportedTreeFileFilter;
+ import jalview.ext.forester.io.TreeParser;
+ import jalview.gui.ColourMenuHelper.ColourChangeListener;
+ import jalview.gui.ViewSelectionMenu.ViewSetProvider;
+ import jalview.io.AlignmentProperties;
+ import jalview.io.AnnotationFile;
+ import jalview.io.BioJsHTMLOutput;
+ import jalview.io.DataSourceType;
+ import jalview.io.FileFormat;
+ import jalview.io.FileFormatI;
+ import jalview.io.FileFormats;
+ import jalview.io.FileLoader;
+ import jalview.io.FileParse;
+ import jalview.io.FormatAdapter;
+ import jalview.io.HtmlSvgOutput;
+ import jalview.io.IdentifyFile;
+ import jalview.io.JPredFile;
+ import jalview.io.JalviewFileChooser;
+ import jalview.io.JalviewFileView;
+ import jalview.io.JnetAnnotationMaker;
+ import jalview.io.NewickFile;
+ import jalview.io.ScoreMatrixFile;
+ import jalview.io.TCoffeeScoreFile;
+ import jalview.jbgui.GAlignFrame;
+ import jalview.schemes.ColourSchemeI;
+ import jalview.schemes.ColourSchemes;
+ import jalview.schemes.ResidueColourScheme;
+ import jalview.schemes.TCoffeeColourScheme;
+ import jalview.util.MessageManager;
+ import jalview.viewmodel.AlignmentViewport;
+ import jalview.viewmodel.ViewportRanges;
+ import jalview.ws.DBRefFetcher;
+ import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
+ import jalview.ws.jws1.Discoverer;
+ import jalview.ws.jws2.Jws2Discoverer;
+ import jalview.ws.jws2.jabaws2.Jws2Instance;
+ import jalview.ws.seqfetcher.DbSourceProxy;
  
  import java.awt.BorderLayout;
 +import java.awt.Color;
  import java.awt.Component;
+ import java.awt.Dimension;
+ import java.awt.GridLayout;
  import java.awt.Rectangle;
  import java.awt.Toolkit;
  import java.awt.datatransfer.Clipboard;
@@@ -59,11 -137,11 +139,13 @@@ import java.util.Deque
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.List;
+ import java.util.StringTokenizer;
  import java.util.Vector;
  
 +import javax.swing.ButtonGroup;
  import javax.swing.JCheckBoxMenuItem;
 +import javax.swing.JComponent;
+ import javax.swing.JComboBox;
  import javax.swing.JEditorPane;
  import javax.swing.JInternalFrame;
  import javax.swing.JLabel;
@@@ -4067,47 -3888,153 +4150,169 @@@ public class AlignFrame extends GAlignF
    @Override
    protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
    {
+     chooseTreeFile();
+   }
+   @Override
+   protected void loadTreeUrlItem_actionPerformed(ActionEvent e)
+   {
+     chooseTreeUrl();
+   }
+   @Override
+   protected void loadTreeBaseStudy_actionPerformed(ActionEvent e)
+   {
+     chooseTreeDb();
+   }
+   @Override
+   protected void loadTreeOfLife_actionPerformed(ActionEvent e)
+   {
+     chooseTreeDb();
+   }
+   @Override
+   protected void loadTreeFam_actionPerformed(ActionEvent e)
+   {
+     chooseTreeDb();
+   }
+   @Override
+   protected void loadTreePfam_actionPerformed(ActionEvent e)
+   {
+     chooseTreeDb();
+   }
+   @Override
+   protected void loadTreeBase_actionPerformed(ActionEvent e)
+   {
+     chooseTreeDb();
+   }
+   public void chooseTreeFile()
+   {
      // Pick the tree file
      JalviewFileChooser chooser = new JalviewFileChooser(
 -            jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
 +            Cache.getProperty("LAST_DIRECTORY"));
      chooser.setFileView(new JalviewFileView());
      chooser.setDialogTitle(
-             MessageManager.getString("label.select_newick_like_tree_file"));
+             MessageManager.getString("label.select_tree_file")); // modify
      chooser.setToolTipText(
-             MessageManager.getString("label.load_tree_file"));
+             MessageManager.getString("label.load_tree_for_sequence_set"));
+     for (SupportedTreeFileFilter treeFormat : SupportedTreeFileFilter
+             .values())
+     {
+       chooser.setFileFilter(treeFormat.getTreeFilter());
+     }
  
 -    int value = chooser.showOpenDialog(null);
 -
 -    if (value == JalviewFileChooser.APPROVE_OPTION)
 +    chooser.setResponseHandler(0, new Runnable()
      {
 -      String filePath = chooser.getSelectedFile().getPath();
 -      Cache.setProperty("LAST_DIRECTORY", filePath);
 -      
 -      
 -      TreeParser treeParser = new TreeParser(filePath);
 -      treeParser.loadTree(viewport);
 -
 +      @Override
 +      public void run()
 +      {
 +        String filePath = chooser.getSelectedFile().getPath();
 +        Cache.setProperty("LAST_DIRECTORY", filePath);
-         NewickFile fin = null;
-         try
-         {
-           fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
-                   DataSourceType.FILE));
-           viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
++      TreeParser treeParser = null;
++      try {
++        treeParser = new TreeParser(filePath);
++        treeParser.loadTree(viewport);        
 +        } catch (Exception ex)
 +        {
 +          JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
 +                  MessageManager
 +                          .getString("label.problem_reading_tree_file"),
 +                  JvOptionPane.WARNING_MESSAGE);
 +          ex.printStackTrace();
 +        }
 +        if (fin != null && fin.hasWarningMessage())
 +        {
 +          JvOptionPane.showMessageDialog(Desktop.desktop,
 +                  fin.getWarningMessage(),
 +                  MessageManager.getString(
 +                          "label.possible_problem_with_tree_file"),
 +                  JvOptionPane.WARNING_MESSAGE);
 +        }
 +      }
 +    });
 +    chooser.showOpenDialog(this);
+     }
+   }
+   /**
+    * Break up and move to TreeParser?
+    */
+   public void chooseTreeUrl()
+   {
+     JLabel label = new JLabel(
+             MessageManager.getString("label.tree_url_example"));
+     // add "example" button
+     final JComboBox<String> history = new JComboBox<>();
+     JPanel panel = new JPanel(new GridLayout(2, 1));
+     panel.add(label);
+     panel.add(history);
+     history.setPreferredSize(new Dimension(400, 20));
+     history.setEditable(true);
+     history.addItem("http://www.");
+     String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
+     StringTokenizer st;
+     if (historyItems != null)
+       {
+       st = new StringTokenizer(historyItems, "\t");
+       while (st.hasMoreTokens())
+       {
+         history.addItem(st.nextToken());
+       }
+       }
+     int reply = JvOptionPane.showInternalConfirmDialog(this, panel,
+             MessageManager.getString("label.load_tree_url"),
+             JvOptionPane.OK_CANCEL_OPTION);
+     if (reply == JvOptionPane.OK_OPTION)
+     {
+       String urlString = history.getSelectedItem().toString();
+       URL treeUrl;
+       try
+       {
+         FileFormatI format = null;
+         format = new IdentifyFile().identify(urlString, DataSourceType.URL);
+         // add actual use for the format identification (jalview .jar files)
+         treeUrl = new URL(urlString);
+         AptxInit.createInstanceFromUrl(treeUrl, viewport);
+       } catch (IOException | RuntimeException e)
+       {
+         JvOptionPane.showMessageDialog(this, MessageManager.formatMessage(
+                 "exception.failed_to_read_data_from_source", new String[]
+                 { urlString }),
+                 MessageManager.getString("label.url_not_found"),
+                 JvOptionPane.ERROR_MESSAGE);
+         e.printStackTrace();
+       }
+     }
+     else
+     {
+     }
+   }
+   public void chooseTreeDb()
+   {
 -
 -
 -
    }
  
    public TreePanel showNewickTree(NewickFile nf, String treeTitle)
    protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
            final String source)
    {
-     new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
 -    new Thread(CrossRefAction.showProductsFor(sel, _odna, source, this),
++    new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this),
+             "CrossReferencesThread")
              .start();
    }
  
Simple merge
@@@ -25,8 -27,8 +27,9 @@@ import jalview.analysis.scoremodels.Sco
  import jalview.analysis.scoremodels.SimilarityParams;
  import jalview.api.analysis.ScoreModelI;
  import jalview.api.analysis.SimilarityParamsI;
 +import jalview.bin.Cache;
  import jalview.datamodel.SequenceGroup;
+ import jalview.ext.archaeopteryx.AptxInit;
  import jalview.util.MessageManager;
  
  import java.awt.BorderLayout;
@@@ -424,13 -422,6 +427,12 @@@ public class CalculationChooser extend
      Object curSel = comboBox.getSelectedItem();
      toolTips.clear();
      DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
 +    /*
 +     * select the score models applicable to the alignment type
 +     */
 +    boolean nucleotide = af.getViewport().getAlignment().isNucleotide();
 +    List<ScoreModelI> models = getApplicableScoreModels(nucleotide,
 +            pca.isSelected());
  
      /*
       * now we can actually add entries to the combobox,
Simple merge
@@@ -287,59 -146,9 +287,59 @@@ public class Console extends WindowAdap
      reader2.setDaemon(true);
      reader2.start();
      // and a thread to append text to the textarea
-     textAppender = new Thread(this);
+     textAppender = new Thread(this, "ConsoleTextAppendThread");
      textAppender.setDaemon(true);
      textAppender.start();
 +
 +    // set icons
 +    frame.setIconImages(ChannelProperties.getIconList());
 +  }
 +
 +  private void setChosenLogLevelCombo()
 +  {
 +    setChosenLogLevelCombo(startingLogLevel);
 +  }
 +
 +  private void setChosenLogLevelCombo(LogLevel setLogLevel)
 +  {
 +    logLevelCombo.setSelectedItem(setLogLevel);
 +    if (!logLevelCombo.getSelectedItem().equals(setLogLevel))
 +    {
 +      // setLogLevel not (yet) in list
 +      if (setLogLevel != null && setLogLevel instanceof LogLevel)
 +      {
 +        // add new item to list (might be set via .jalview_properties)
 +        boolean added = false;
 +        for (int i = 0; i < logLevelCombo.getItemCount(); i++)
 +        {
 +          LogLevel l = (LogLevel) logLevelCombo.getItemAt(i);
 +          if (l.compareTo(setLogLevel) >= 0)
 +          {
 +            logLevelCombo.insertItemAt(setLogLevel, i);
 +            added = true;
 +            break;
 +          }
 +        }
 +        if (!added) // lower priority than others or some confusion -- add to
 +                    // end of list
 +        {
 +          logLevelCombo.addItem(setLogLevel);
 +        }
 +        logLevelCombo.setSelectedItem(setLogLevel);
 +      }
 +      else
 +      {
 +        logLevelCombo.setSelectedItem(LogLevel.INFO);
 +      }
 +    }
 +  }
 +
 +  private void copyConsoleTextToClipboard()
 +  {
 +    String consoleText = textArea.getText();
 +    StringSelection consoleTextSelection = new StringSelection(consoleText);
 +    Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
 +    cb.setContents(consoleTextSelection, null);
    }
  
    PipedOutputStream pout = null, perr = null;
@@@ -705,23 -557,26 +705,23 @@@ public class Desktop extends jalview.jb
  
    void showNews(boolean visible)
    {
 +    jalview.bin.Console.debug((visible ? "Showing" : "Hiding") + " news.");
 +    showNews.setSelected(visible);
 +    if (visible && !jvnews.isVisible())
      {
 -      Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
 -      showNews.setSelected(visible);
 -      if (visible && !jvnews.isVisible())
 +      new Thread(new Runnable()
        {
 -        new Thread(new Runnable()
 +        @Override
 +        public void run()
          {
 -          @Override
 -          public void run()
 -          {
 -            long now = System.currentTimeMillis();
 -            Desktop.instance.setProgressBar(
 -                    MessageManager.getString("status.refreshing_news"),
 -                    now);
 -            jvnews.refreshNews();
 -            Desktop.instance.setProgressBar(null, now);
 -            jvnews.showNews();
 -          }
 +          long now = System.currentTimeMillis();
 +          Desktop.instance.setProgressBar(
 +                  MessageManager.getString("status.refreshing_news"), now);
 +          jvnews.refreshNews();
 +          Desktop.instance.setProgressBar(null, now);
 +          jvnews.showNews();
 +        }
-       }).start();
+         }, "ShowNewsWindowThread").start();
 -      }
      }
    }
  
        @Override
        public void run()
        {
 -        new SplashScreen(true);
 +        new SplashScreen(false);
        }
-     }).start();
+     }, "ShowAboutMenuThread").start();
    }
  
 -  public StringBuffer getAboutMessage(boolean shortv)
 +  /**
 +   * Returns the html text for the About screen, including any available version
 +   * number, build details, author details and citation reference, but without
 +   * the enclosing {@code html} tags
 +   * 
 +   * @return
 +   */
 +  public String getAboutMessage()
    {
 -    StringBuffer message = new StringBuffer();
 -    message.append("<html>");
 -    if (shortv)
 -    {
 -      message.append("<h1><strong>Version: "
 -              + jalview.bin.Cache.getProperty("VERSION")
 -              + "</strong></h1>");
 -      message.append("<strong>Last Updated: <em>"
 -              + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
 -              + "</em></strong>");
 -
 -    }
 -    else
 -    {
 +    StringBuilder message = new StringBuilder(1024);
 +    message.append("<div style=\"font-family: sans-serif;\">")
 +            .append("<h1><strong>Version: ")
 +            .append(Cache.getProperty("VERSION")).append("</strong></h1>")
 +            .append("<strong>Built: <em>")
 +            .append(Cache.getDefault("BUILD_DATE", "unknown"))
 +            .append("</em> from ").append(Cache.getBuildDetailsForSplash())
 +            .append("</strong>");
  
 -      message.append("<strong>Version "
 -              + jalview.bin.Cache.getProperty("VERSION")
 -              + "; last updated: "
 -              + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
 -    }
 -
 -    if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
 -            .equals("Checking"))
 +    String latestVersion = Cache.getDefault("LATEST_VERSION", "Checking");
 +    if (latestVersion.equals("Checking"))
      {
 -      message.append("<br>...Checking latest version...</br>");
 +      // JBP removed this message for 2.11: May be reinstated in future version
 +      // message.append("<br>...Checking latest version...</br>");
      }
 -    else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
 -            .equals(jalview.bin.Cache.getProperty("VERSION")))
 +    else if (!latestVersion.equals(Cache.getProperty("VERSION")))
      {
        boolean red = false;
 -      if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
 +      if (Cache.getProperty("VERSION").toLowerCase(Locale.ROOT)
                .indexOf("automated build") == -1)
        {
          red = true;
                      MessageManager.getString("label.couldnt_save_project"),
                      JvOptionPane.WARNING_MESSAGE);
            }
 -          setProgressBar(null, choice.hashCode());
 +          setProgressBar(null, chosenFile.hashCode());
          }
-       }).start();
+       }, "SaveJalviewProjectThread").start();
      }
    }
  
      if (desktop != null)
      {
        AlignFrame[] frames = Desktop.getAlignFrames();
 -
 -      for (AlignFrame afr : frames)
 -      {
 -        if (sequenceSetId == null || afr.getViewport().getSequenceSetId()
 -                .equals(sequenceSetId))
 -        {
 -          if (afr.alignPanels != null)
 -          {
 -            for (AlignmentPanel ap : afr.alignPanels)
 -            {
 -              if (sequenceSetId == null
 -                      || sequenceSetId.equals(ap.av.getSequenceSetId()))
 -              {
 -                viewp.add(ap.av);
 -              }
 -            }
 -          }
 -          else
 -          {
 -            viewp.add(afr.getViewport());
 -          }
 -        }
 -      }
 -      if (viewp.size() > 0)
 -      {
 -        return viewp.toArray(new AlignmentViewport[viewp.size()]);
 -      }
 -    }
 -    return null;
 -  }
 -
 -  /**
 -   * Explode the views in the given frame into separate AlignFrame
 -   * 
 -   * @param af
 -   */
 -  public static void explodeViews(AlignFrame af)
 -  {
 -    int size = af.alignPanels.size();
 -    if (size < 2)
 -    {
 -      return;
 -    }
 -
 -    for (int i = 0; i < size; i++)
 -    {
 -      AlignmentPanel ap = af.alignPanels.get(i);
 -      AlignFrame newaf = new AlignFrame(ap);
 -
 -      /*
 -       * Restore the view's last exploded frame geometry if known. Multiple
 -       * views from one exploded frame share and restore the same (frame)
 -       * position and size.
 -       */
 -      Rectangle geometry = ap.av.getExplodedGeometry();
 -      if (geometry != null)
 -      {
 -        newaf.setBounds(geometry);
 -      }
 -
 -      ap.av.setGatherViewsHere(false);
 -
 -      addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
 -              AlignFrame.DEFAULT_HEIGHT);
 -    }
 -
 -    af.alignPanels.clear();
 -    af.closeMenuItem_actionPerformed(true);
 -
 -  }
 -
 -  /**
 -   * Gather expanded views (separate AlignFrame's) with the same sequence set
 -   * identifier back in to this frame as additional views, and close the
 -   * expanded views. Note the expanded frames may themselves have multiple
 -   * views. We take the lot.
 -   * 
 -   * @param source
 -   */
 -  public void gatherViews(AlignFrame source)
 -  {
 -    source.viewport.setGatherViewsHere(true);
 -    source.viewport.setExplodedGeometry(source.getBounds());
 -    JInternalFrame[] frames = desktop.getAllFrames();
 -    String viewId = source.viewport.getSequenceSetId();
 -
 -    for (int t = 0; t < frames.length; t++)
 -    {
 -      if (frames[t] instanceof AlignFrame && frames[t] != source)
 -      {
 -        AlignFrame af = (AlignFrame) frames[t];
 -        boolean gatherThis = false;
 -        for (int a = 0; a < af.alignPanels.size(); a++)
 -        {
 -          AlignmentPanel ap = af.alignPanels.get(a);
 -          if (viewId.equals(ap.av.getSequenceSetId()))
 -          {
 -            gatherThis = true;
 -            ap.av.setGatherViewsHere(false);
 -            ap.av.setExplodedGeometry(af.getBounds());
 -            source.addAlignmentPanel(ap, false);
 -          }
 -        }
 -
 -        if (gatherThis)
 -        {
 -          af.alignPanels.clear();
 -          af.closeMenuItem_actionPerformed(true);
 -        }
 -      }
 -    }
 -
 -  }
 -
 -  jalview.gui.VamsasApplication v_client = null;
 -
 -  @Override
 -  public void vamsasImport_actionPerformed(ActionEvent e)
 -  {
 -    if (v_client == null)
 -    {
 -      // Load and try to start a session.
 -      JalviewFileChooser chooser = new JalviewFileChooser(
 -              jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
 -
 -      chooser.setFileView(new JalviewFileView());
 -      chooser.setDialogTitle(
 -              MessageManager.getString("label.open_saved_vamsas_session"));
 -      chooser.setToolTipText(MessageManager.getString(
 -              "label.select_vamsas_session_opened_as_new_vamsas_session"));
 -
 -      int value = chooser.showOpenDialog(this);
 -
 -      if (value == JalviewFileChooser.APPROVE_OPTION)
 -      {
 -        String fle = chooser.getSelectedFile().toString();
 -        if (!vamsasImport(chooser.getSelectedFile()))
 -        {
 -          JvOptionPane.showInternalMessageDialog(Desktop.desktop,
 -                  MessageManager.formatMessage(
 -                          "label.couldnt_import_as_vamsas_session",
 -                          new Object[]
 -                          { fle }),
 -                  MessageManager
 -                          .getString("label.vamsas_document_import_failed"),
 -                  JvOptionPane.ERROR_MESSAGE);
 -        }
 -      }
 -    }
 -    else
 -    {
 -      jalview.bin.Cache.log.error(
 -              "Implementation error - load session from a running session is not supported.");
 -    }
 -  }
 -
 -  /**
 -   * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
 -   * 
 -   * @param file
 -   * @return true if import was a success and a session was started.
 -   */
 -  public boolean vamsasImport(URL url)
 -  {
 -    // TODO: create progress bar
 -    if (v_client != null)
 -    {
 -
 -      jalview.bin.Cache.log.error(
 -              "Implementation error - load session from a running session is not supported.");
 -      return false;
 -    }
 -
 -    try
 -    {
 -      // copy the URL content to a temporary local file
 -      // TODO: be a bit cleverer here with nio (?!)
 -      File file = File.createTempFile("vdocfromurl", ".vdj");
 -      FileOutputStream fos = new FileOutputStream(file);
 -      BufferedInputStream bis = new BufferedInputStream(url.openStream());
 -      byte[] buffer = new byte[2048];
 -      int ln;
 -      while ((ln = bis.read(buffer)) > -1)
 -      {
 -        fos.write(buffer, 0, ln);
 -      }
 -      bis.close();
 -      fos.close();
 -      v_client = new jalview.gui.VamsasApplication(this, file,
 -              url.toExternalForm());
 -    } catch (Exception ex)
 -    {
 -      jalview.bin.Cache.log.error(
 -              "Failed to create new vamsas session from contents of URL "
 -                      + url,
 -              ex);
 -      return false;
 -    }
 -    setupVamsasConnectedGui();
 -    v_client.initial_update(); // TODO: thread ?
 -    return v_client.inSession();
 -  }
 -
 -  /**
 -   * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
 -   * 
 -   * @param file
 -   * @return true if import was a success and a session was started.
 -   */
 -  public boolean vamsasImport(File file)
 -  {
 -    if (v_client != null)
 -    {
 -
 -      jalview.bin.Cache.log.error(
 -              "Implementation error - load session from a running session is not supported.");
 -      return false;
 -    }
 -
 -    setProgressBar(MessageManager.formatMessage(
 -            "status.importing_vamsas_session_from", new Object[]
 -            { file.getName() }), file.hashCode());
 -    try
 -    {
 -      v_client = new jalview.gui.VamsasApplication(this, file, null);
 -    } catch (Exception ex)
 -    {
 -      setProgressBar(MessageManager.formatMessage(
 -              "status.importing_vamsas_session_from", new Object[]
 -              { file.getName() }), file.hashCode());
 -      jalview.bin.Cache.log.error(
 -              "New vamsas session from existing session file failed:", ex);
 -      return false;
 -    }
 -    setupVamsasConnectedGui();
 -    v_client.initial_update(); // TODO: thread ?
 -    setProgressBar(MessageManager.formatMessage(
 -            "status.importing_vamsas_session_from", new Object[]
 -            { file.getName() }), file.hashCode());
 -    return v_client.inSession();
 -  }
 -
 -  public boolean joinVamsasSession(String mysesid)
 -  {
 -    if (v_client != null)
 -    {
 -      throw new Error(MessageManager
 -              .getString("error.try_join_vamsas_session_another"));
 -    }
 -    if (mysesid == null)
 -    {
 -      throw new Error(
 -              MessageManager.getString("error.invalid_vamsas_session_id"));
 -    }
 -    v_client = new VamsasApplication(this, mysesid);
 -    setupVamsasConnectedGui();
 -    v_client.initial_update();
 -    return (v_client.inSession());
 -  }
 -
 -  @Override
 -  public void vamsasStart_actionPerformed(ActionEvent e)
 -  {
 -    if (v_client == null)
 -    {
 -      // Start a session.
 -      // we just start a default session for moment.
 -      /*
 -       * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
 -       * getProperty("LAST_DIRECTORY"));
 -       * 
 -       * chooser.setFileView(new JalviewFileView());
 -       * chooser.setDialogTitle("Load Vamsas file");
 -       * chooser.setToolTipText("Import");
 -       * 
 -       * int value = chooser.showOpenDialog(this);
 -       * 
 -       * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
 -       * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
 -       */
 -      v_client = new VamsasApplication(this);
 -      setupVamsasConnectedGui();
 -      v_client.initial_update(); // TODO: thread ?
 -    }
 -    else
 -    {
 -      // store current data in session.
 -      v_client.push_update(); // TODO: thread
 -    }
 -  }
 -
 -  protected void setupVamsasConnectedGui()
 -  {
 -    vamsasStart.setText(MessageManager.getString("label.session_update"));
 -    vamsasSave.setVisible(true);
 -    vamsasStop.setVisible(true);
 -    vamsasImport.setVisible(false); // Document import to existing session is
 -    // not possible for vamsas-client-1.0.
 -  }
 -
 -  protected void setupVamsasDisconnectedGui()
 -  {
 -    vamsasSave.setVisible(false);
 -    vamsasStop.setVisible(false);
 -    vamsasImport.setVisible(true);
 -    vamsasStart
 -            .setText(MessageManager.getString("label.new_vamsas_session"));
 -  }
 -
 -  @Override
 -  public void vamsasStop_actionPerformed(ActionEvent e)
 -  {
 -    if (v_client != null)
 -    {
 -      v_client.end_session();
 -      v_client = null;
 -      setupVamsasDisconnectedGui();
 -    }
 -  }
 -
 -  protected void buildVamsasStMenu()
 -  {
 -    if (v_client == null)
 -    {
 -      String[] sess = null;
 -      try
 -      {
 -        sess = VamsasApplication.getSessionList();
 -      } catch (Exception e)
 +
 +      for (AlignFrame afr : frames)
        {
 -        jalview.bin.Cache.log.warn("Problem getting current sessions list.",
 -                e);
 -        sess = null;
 -      }
 -      if (sess != null)
 -      {
 -        jalview.bin.Cache.log.debug(
 -                "Got current sessions list: " + sess.length + " entries.");
 -        VamsasStMenu.removeAll();
 -        for (int i = 0; i < sess.length; i++)
 -        {
 -          JMenuItem sessit = new JMenuItem();
 -          sessit.setText(sess[i]);
 -          sessit.setToolTipText(MessageManager
 -                  .formatMessage("label.connect_to_session", new Object[]
 -                  { sess[i] }));
 -          final Desktop dsktp = this;
 -          final String mysesid = sess[i];
 -          sessit.addActionListener(new ActionListener()
 +        if (sequenceSetId == null || afr.getViewport().getSequenceSetId()
 +                .equals(sequenceSetId))
 +        {
 +          if (afr.alignPanels != null)
            {
 -
 -            @Override
 -            public void actionPerformed(ActionEvent e)
 +            for (AlignmentPanel ap : afr.alignPanels)
              {
 -              if (dsktp.v_client == null)
 +              if (sequenceSetId == null
 +                      || sequenceSetId.equals(ap.av.getSequenceSetId()))
                {
 -                Thread rthr = new Thread(new Runnable()
 -                {
 -
 -                  @Override
 -                  public void run()
 -                  {
 -                    dsktp.v_client = new VamsasApplication(dsktp, mysesid);
 -                    dsktp.setupVamsasConnectedGui();
 -                    dsktp.v_client.initial_update();
 -                  }
 -
 -                }, "VamsasSessionThread");
 -                rthr.start();
 +                viewp.add(ap.av);
                }
 -            };
 -          });
 -          VamsasStMenu.add(sessit);
 +            }
 +          }
 +          else
 +          {
 +            viewp.add(afr.getViewport());
 +          }
          }
 -        // don't show an empty menu.
 -        VamsasStMenu.setVisible(sess.length > 0);
 -
        }
 -      else
 +      if (viewp.size() > 0)
        {
 -        jalview.bin.Cache.log.debug("No current vamsas sessions.");
 -        VamsasStMenu.removeAll();
 -        VamsasStMenu.setVisible(false);
 +        return viewp.toArray(new AlignmentViewport[viewp.size()]);
        }
      }
 -    else
 -    {
 -      // Not interested in the content. Just hide ourselves.
 -      VamsasStMenu.setVisible(false);
 -    }
 +    return null;
    }
  
 -  @Override
 -  public void vamsasSave_actionPerformed(ActionEvent e)
 +  /**
 +   * Explode the views in the given frame into separate AlignFrame
 +   * 
 +   * @param af
 +   */
 +  public static void explodeViews(AlignFrame af)
    {
 -    if (v_client != null)
 +    int size = af.alignPanels.size();
 +    if (size < 2)
      {
 -      // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
 -      JalviewFileChooser chooser = new JalviewFileChooser("vdj",
 -              "Vamsas Document");
 +      return;
 +    }
  
 -      chooser.setFileView(new JalviewFileView());
 -      chooser.setDialogTitle(MessageManager
 -              .getString("label.save_vamsas_document_archive"));
 +    // FIXME: ideally should use UI interface API
 +    FeatureSettings viewFeatureSettings = (af.featureSettings != null
 +            && af.featureSettings.isOpen()) ? af.featureSettings : null;
 +    Rectangle fsBounds = af.getFeatureSettingsGeometry();
 +    for (int i = 0; i < size; i++)
 +    {
 +      AlignmentPanel ap = af.alignPanels.get(i);
  
 -      int value = chooser.showSaveDialog(this);
 +      AlignFrame newaf = new AlignFrame(ap);
  
 -      if (value == JalviewFileChooser.APPROVE_OPTION)
 +      // transfer reference for existing feature settings to new alignFrame
 +      if (ap == af.alignPanel)
        {
 -        java.io.File choice = chooser.getSelectedFile();
 -        JPanel progpanel = addProgressPanel(MessageManager
 -                .formatMessage("label.saving_vamsas_doc", new Object[]
 -                { choice.getName() }));
 -        Cache.setProperty("LAST_DIRECTORY", choice.getParent());
 -        String warnmsg = null;
 -        String warnttl = null;
 -        try
 +        if (viewFeatureSettings != null && viewFeatureSettings.fr.ap == ap)
          {
 -          v_client.vclient.storeDocument(choice);
 -        } catch (Error ex)
 -        {
 -          warnttl = "Serious Problem saving Vamsas Document";
 -          warnmsg = ex.toString();
 -          jalview.bin.Cache.log
 -                  .error("Error Whilst saving document to " + choice, ex);
 +          newaf.featureSettings = viewFeatureSettings;
 +        }
 +        newaf.setFeatureSettingsGeometry(fsBounds);
 +      }
  
 -        } catch (Exception ex)
 -        {
 -          warnttl = "Problem saving Vamsas Document.";
 -          warnmsg = ex.toString();
 -          jalview.bin.Cache.log.warn(
 -                  "Exception Whilst saving document to " + choice, ex);
 +      /*
 +       * Restore the view's last exploded frame geometry if known. Multiple views from
 +       * one exploded frame share and restore the same (frame) position and size.
 +       */
 +      Rectangle geometry = ap.av.getExplodedGeometry();
 +      if (geometry != null)
 +      {
 +        newaf.setBounds(geometry);
 +      }
  
 -        }
 -        removeProgressPanel(progpanel);
 -        if (warnmsg != null)
 -        {
 -          JvOptionPane.showInternalMessageDialog(Desktop.desktop,
 +      ap.av.setGatherViewsHere(false);
  
 -                  warnmsg, warnttl, JvOptionPane.ERROR_MESSAGE);
 -        }
 +      addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
 +              AlignFrame.DEFAULT_HEIGHT);
 +      // and materialise a new feature settings dialog instance for the new
 +      // alignframe
 +      // (closes the old as if 'OK' was pressed)
 +      if (ap == af.alignPanel && newaf.featureSettings != null
 +              && newaf.featureSettings.isOpen()
 +              && af.alignPanel.getAlignViewport().isShowSequenceFeatures())
 +      {
 +        newaf.showFeatureSettingsUI();
        }
      }
 -  }
  
 -  JPanel vamUpdate = null;
 +    af.featureSettings = null;
 +    af.alignPanels.clear();
 +    af.closeMenuItem_actionPerformed(true);
 +
 +  }
  
    /**
 -   * hide vamsas user gui bits when a vamsas document event is being handled.
 +   * Gather expanded views (separate AlignFrame's) with the same sequence set
 +   * identifier back in to this frame as additional views, and close the
 +   * expanded views. Note the expanded frames may themselves have multiple
 +   * views. We take the lot.
     * 
 -   * @param b
 -   *          true to hide gui, false to reveal gui
 +   * @param source
     */
 -  public void setVamsasUpdate(boolean b)
 +  public void gatherViews(AlignFrame source)
    {
 -    Cache.log.debug("Setting gui for Vamsas update "
 -            + (b ? "in progress" : "finished"));
 -
 -    if (vamUpdate != null)
 +    source.viewport.setGatherViewsHere(true);
 +    source.viewport.setExplodedGeometry(source.getBounds());
 +    JInternalFrame[] frames = desktop.getAllFrames();
 +    String viewId = source.viewport.getSequenceSetId();
 +    for (int t = 0; t < frames.length; t++)
      {
 -      this.removeProgressPanel(vamUpdate);
 +      if (frames[t] instanceof AlignFrame && frames[t] != source)
 +      {
 +        AlignFrame af = (AlignFrame) frames[t];
 +        boolean gatherThis = false;
 +        for (int a = 0; a < af.alignPanels.size(); a++)
 +        {
 +          AlignmentPanel ap = af.alignPanels.get(a);
 +          if (viewId.equals(ap.av.getSequenceSetId()))
 +          {
 +            gatherThis = true;
 +            ap.av.setGatherViewsHere(false);
 +            ap.av.setExplodedGeometry(af.getBounds());
 +            source.addAlignmentPanel(ap, false);
 +          }
 +        }
 +
 +        if (gatherThis)
 +        {
 +          if (af.featureSettings != null && af.featureSettings.isOpen())
 +          {
 +            if (source.featureSettings == null)
 +            {
 +              // preserve the feature settings geometry for this frame
 +              source.featureSettings = af.featureSettings;
 +              source.setFeatureSettingsGeometry(
 +                      af.getFeatureSettingsGeometry());
 +            }
 +            else
 +            {
 +              // close it and forget
 +              af.featureSettings.close();
 +            }
 +          }
 +          af.alignPanels.clear();
 +          af.closeMenuItem_actionPerformed(true);
 +        }
 +      }
      }
 -    if (b)
 +
 +    // refresh the feature setting UI for the source frame if it exists
 +    if (source.featureSettings != null && source.featureSettings.isOpen())
      {
 -      vamUpdate = this.addProgressPanel(
 -              MessageManager.getString("label.updating_vamsas_session"));
 +      source.showFeatureSettingsUI();
      }
 -    vamsasStart.setVisible(!b);
 -    vamsasStop.setVisible(!b);
 -    vamsasSave.setVisible(!b);
    }
  
    public JInternalFrame[] getAllFrames()
        }
        // JAL-940 - disabled JWS1 service configuration - always start discoverer
        // until we phase out completely
-       (t0 = new Thread(discoverer)).start();
+       (t0 = new Thread(discoverer, "DiscovererThread")).start();
      }
  
 -    if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
 +    if (ignore_SHOW_JWS2_SERVICES_preference
 +            || Cache.getDefault("SHOW_JWS2_SERVICES", true))
      {
        t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
                .startDiscoverer(changeSupport);
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -401,9 -350,9 +401,9 @@@ public abstract class StructureViewerBa
                }
              }
              // and call ourselves again.
 -            addStructure(pdbentry, seqs, chains, align, alignFrame);
 +            addStructure(pdbentry, seqs, chains, alignFrame);
            }
-         }).start();
+         }, "Adding3DStructureQueueThread").start();
          return;
        }
      }
              { seqs }, new String[][] { chains });
      addingStructures = true;
      _started = false;
-     worker = new Thread(this);
 -    alignAddedStructures = align;
+     worker = new Thread(this, "Adding3DStructureThread");
      worker.start();
      return;
    }
Simple merge
   */
  package jalview.gui;
  
 +import java.util.Locale;
 +
  import jalview.analysis.AlignmentSorter;
- import jalview.analysis.AverageDistanceTree;
- import jalview.analysis.NJTree;
- import jalview.analysis.TreeBuilder;
  import jalview.analysis.TreeModel;
- import jalview.analysis.scoremodels.ScoreModels;
- import jalview.api.analysis.ScoreModelI;
- import jalview.api.analysis.SimilarityParamsI;
  import jalview.bin.Cache;
 +import jalview.bin.Console;
  import jalview.commands.CommandI;
  import jalview.commands.OrderCommand;
  import jalview.datamodel.Alignment;
@@@ -86,9 -74,7 +78,9 @@@ public class TreePanel extends GTreePan
  
    String treeTitle; // if tree loaded
  
 +  SimilarityParamsI similarityParams;
 +
-   private TreeCanvas treeCanvas;
+   TreeCanvas treeCanvas;
  
    TreeModel tree;
  
  
    public AlignmentViewport getViewPort()
    {
 -    return treeCanvas.av;
 +    // @Mungo - Why don't we return our own viewport ???
 +    return getTreeCanvas().getViewport();
    }
  
-   void initTreePanel(AlignmentPanel ap, String type, String modelName,
-           NewickFile newTree, AlignmentView inputData)
+   /**
+    * Initialize a tree panel based on a calculated tree
+    * 
+    * @param ap
+    * @param tree
+    */
+   void initTreePanel(AlignmentPanel ap, TreeModel tree)
    {
+     buildTreeCanvas(ap);
  
-     av = ap.av;
-     this.treeType = type;
-     this.scoreModelName = modelName;
-     treeCanvas = new TreeCanvas(this, ap, scrollPane);
-     scrollPane.setViewportView(treeCanvas);
-     PaintRefresher.Register(this, ap.av.getSequenceSetId());
-     buildAssociatedViewMenu();
-     final PropertyChangeListener listener = addAlignmentListener();
-     /*
-      * remove listener when window is closed, so that this
-      * panel can be garbage collected
-      */
-     addInternalFrameListener(new InternalFrameAdapter()
-     {
-       @Override
-       public void internalFrameClosed(InternalFrameEvent evt)
-       {
-         if (av != null)
-         {
-           av.removePropertyChangeListener(listener);
-         }
-         releaseReferences();
-       }
-     });
-     TreeLoader tl = new TreeLoader(newTree, inputData);
+     TreeLoader tl = new TreeLoader(null, null);
      tl.start();
  
    }
@@@ -319,18 -304,16 +312,13 @@@ public void buildTreeCanvas(AlignmentPa
          {
            originalSeqData.setVisible(false);
          }
 -
 -
 -
        }
-       else
-       {
-         ScoreModelI sm = ScoreModels.getInstance().getScoreModel(
-                 scoreModelName, treeCanvas.getAssociatedPanel());
-         TreeBuilder njtree = treeType.equals(TreeBuilder.NEIGHBOUR_JOINING)
-                 ? new NJTree(av, sm, similarityParams)
-                 : new AverageDistanceTree(av, sm, similarityParams);
-         tree = new TreeModel(njtree);
-         showDistances(true);
-       }
+       showTree(tree);
  
+     }
+       
+     public void showTree(TreeModel tree)
+     {
        tree.reCount(tree.getTopNode());
        tree.findHeight(tree.getTopNode());
        treeCanvas.setTree(tree);
      {
        return treeTitle;
      }
+     else
+     {
+       /*
+        * i18n description of Neighbour Joining or Average Distance method
+        */
+       String treecalcnm = MessageManager
+               .getString("label.tree_calc_" + treeType.toLowerCase());
  
 -      /*
 -       * short score model name (long description can be too long)
 -       */
 -      String smn = substitutionMatrix;
 -
 -      /*
 -       * put them together as <method> Using <model>
 -       */
 -      final String ttl = MessageManager
 -              .formatMessage("label.treecalc_title", treecalcnm, smn);
 +    /*
 +     * i18n description of Neighbour Joining or Average Distance method
 +     */
 +    String treecalcnm = MessageManager.getString(
 +            "label.tree_calc_" + treeType.toLowerCase(Locale.ROOT));
 +
 +    /*
 +     * short score model name (long description can be too long)
 +     */
 +    String smn = scoreModelName;
 +
 +    /*
 +     * put them together as <method> Using <model>
 +     */
 +    final String ttl = MessageManager.formatMessage("label.calc_title",
 +            treecalcnm, smn);
-     return ttl;
+       return ttl;
+     }
    }
 +
 +  /**
 +   * Builds an EPS image and writes it to the specified file.
 +   * 
 +   * @param outFile
 +   * @param textOption
 +   *          true for Text character rendering, false for Lineart
 +   */
 +  protected void writeEpsFile(File outFile, boolean textOption)
 +  {
 +    try
 +    {
 +      int width = treeCanvas.getWidth();
 +      int height = treeCanvas.getHeight();
 +
 +      FileOutputStream out = new FileOutputStream(outFile);
 +      EpsGraphics2D pg = new EpsGraphics2D("Tree", out, 0, 0, width,
 +              height);
 +      pg.setAccurateTextMode(!textOption);
 +      treeCanvas.draw(pg, width, height);
 +
 +      pg.flush();
 +      pg.close();
 +    } catch (Exception ex)
 +    {
 +      System.err.println("Error writing tree as EPS");
 +      ex.printStackTrace();
 +    }
 +  }
 +
 +  public AlignViewport getViewport()
 +  {
 +    return av;
 +  }
 +
 +  public void setViewport(AlignViewport av)
 +  {
 +    this.av = av;
 +  }
 +
 +  public TreeCanvas getTreeCanvas()
 +  {
 +    return treeCanvas;
 +  }
  }
@@@ -319,13 -320,13 +319,13 @@@ public class VamsasApplication implemen
        @Override
        public void run()
        {
 -        Cache.log.info("Jalview updating to the Vamsas Session.");
 +        Console.info("Jalview updating to the Vamsas Session.");
  
          dealWithDocumentUpdate(true);
 -        Cache.log.info("Jalview finished updating to the Vamsas Session.");
 +        Console.info("Jalview finished updating to the Vamsas Session.");
        }
  
-     });
+     }, "UpdateVamsasThread");
      udthread.start();
    }
  
@@@ -346,27 -342,26 +346,27 @@@ public class WebserviceInfo extends GWe
      }
  
      AnimatedPanel ap = new AnimatedPanel();
 -    titlePanel.add(ap, BorderLayout.CENTER);
 +    ap.setPreferredSize(new Dimension(60, 60));
 +    titlePanel.add(ap, BorderLayout.WEST);
 +    titlePanel.add(titleText, BorderLayout.CENTER);
 +    setStatus(currentStatus);
  
-     Thread thread = new Thread(ap);
+     Thread thread = new Thread(ap, "AnimatedPanelThread");
      thread.start();
      final WebserviceInfo thisinfo = this;
 -    frame.addInternalFrameListener(
 -            new javax.swing.event.InternalFrameAdapter()
 -            {
 -              @Override
 -              public void internalFrameClosed(
 -                      javax.swing.event.InternalFrameEvent evt)
 -              {
 -                // System.out.println("Shutting down webservice client");
 -                WSClientI service = thisinfo.getthisService();
 -                if (service != null && service.isCancellable())
 -                {
 -                  service.cancelJob();
 -                }
 -              };
 -            });
 +    frame.addInternalFrameListener(new InternalFrameAdapter()
 +    {
 +      @Override
 +      public void internalFrameClosed(InternalFrameEvent evt)
 +      {
 +        // System.out.println("Shutting down webservice client");
 +        WSClientI service = thisinfo.getthisService();
 +        if (service != null && service.isCancellable())
 +        {
 +          service.cancelJob();
 +        }
 +      }
 +    });
      frame.validate();
  
    }
Simple merge
Simple merge
@@@ -208,8 -183,19 +208,7 @@@ public class FileLoader implements Runn
     */
    protected AlignFrame _LoadFileWaitTillLoaded()
    {
 -    Thread loader = new Thread(this, "LoadFileWithWaitingThread");
 -    loader.start();
 -
 -    while (loader.isAlive())
 -    {
 -      try
 -      {
 -        Thread.sleep(500);
 -      } catch (Exception ex)
 -      {
 -      }
 -    }
 -
 +    this.run();
      return alignFrame;
    }
  
@@@ -470,9 -477,9 +470,9 @@@ public class NewickFile extends FilePar
            {
              try
              {
 -              bootstrap = (new Integer(nbootstrap.stringMatched(1)))
 +              bootstrap = (Integer.valueOf(nbootstrap.stringMatched(1)))
                        .intValue();
-               HasBootstrap = true;
+               hasBootstrap = true;
              } catch (Exception e)
              {
                Error = ErrorStringrange(Error, "Can't parse bootstrap value",
@@@ -1791,12 -1810,8 +1893,12 @@@ public class GAlignFrame extends JInter
      fileMenu.add(exportImageMenu);
      fileMenu.add(exportFeatures);
      fileMenu.add(exportAnnotations);
-     fileMenu.add(loadTreeMenuItem);
+     fileMenu.add(loadTreeMenu);
      fileMenu.add(associatedData);
 +    if (!Platform.isJS())
 +    {
 +      fileMenu.add(loadVcf);
 +    }
      fileMenu.addSeparator();
      fileMenu.add(closeMenuItem);
  
      // JAL-574
      // selectMenu.addSeparator();
      // selectMenu.add(listenToViewSelections);
+   }
+   protected void loadTreeOfLife_actionPerformed(ActionEvent e)
+   {
+     // TODO Auto-generated method stub
+   }
+   protected void loadTreeFam_actionPerformed(ActionEvent e)
+   {
+     // TODO Auto-generated method stub
+   }
+   protected void loadTreePfam_actionPerformed(ActionEvent e)
+   {
+     // TODO Auto-generated method stub
+   }
+   protected void loadTreeBase_actionPerformed(ActionEvent e)
+   {
+     // TODO Auto-generated method stub
+   }
+   protected void loadTreeBaseStudy_actionPerformed(ActionEvent e)
+   {
+     // TODO Auto-generated method stub
    }
  
 +  protected void loadVcf_actionPerformed()
 +  {
 +  }
 +
    /**
     * Constructs the entries on the Colour menu (but does not add them to the
     * menu).
@@@ -973,53 -996,10 +973,59 @@@ public class Matrix implements Matrix
      }
    }
  
 +  @Override
 +  public void setD(double[] v)
 +  {
 +    d = v;
 +  }
 +
 +  @Override
 +  public void setE(double[] v)
 +  {
 +    e = v;
 +  }
 +
 +  public double getTotal()
 +  {
 +    double d = 0d;
 +    for (int i = 0; i < this.height(); i++)
 +    {
 +      for (int j = 0; j < this.width(); j++)
 +      {
 +        d += value[i][j];
 +      }
 +    }
 +    return d;
 +  }
 +
 +  /**
 +   * {@inheritDoc}
 +   */
 +  @Override
 +  public boolean equals(MatrixI m2, double delta)
 +  {
 +    if (m2 == null || this.height() != m2.height()
 +            || this.width() != m2.width())
 +    {
 +      return false;
 +    }
 +    for (int i = 0; i < this.height(); i++)
 +    {
 +      for (int j = 0; j < this.width(); j++)
 +      {
 +        double diff = this.getValue(i, j) - m2.getValue(i, j);
 +        if (Math.abs(diff) > delta)
 +        {
 +          return false;
 +        }
 +      }
 +    }
 +    return true;
 +  }
+   @Override
+   public double[][] getValues()
+   {
+     return value;
+   }
  }
@@@ -68,48 -64,20 +68,56 @@@ public interface Matrix
    double[] getRow(int i);
  
    /**
 +   * Answers a new matrix with a copy of the values in this one
 +   * 
 +   * @return
 +   */
 +  MatrixI copy();
 +
 +  /**
+    * Answers all values present in the Matrix ordered by row,column
+    * 
+    * @return the double array containing the values ordered in {row values} per
+    *         column
+    */
+   double[][] getValues();
 -
 -  MatrixI copy();
 -
++  /**
 +   * Returns a new matrix which is the transpose of this one
 +   * 
 +   * @return
 +   */
    MatrixI transpose();
  
 +  /**
 +   * Returns a new matrix which is the result of premultiplying this matrix by
 +   * the supplied argument. If this of size AxB (A rows and B columns), and the
 +   * argument is CxA (C rows and A columns), the result is of size CxB.
 +   * 
 +   * @param in
 +   * 
 +   * @return
 +   * @throws IllegalArgumentException
 +   *           if the number of columns in the pre-multiplier is not equal to
 +   *           the number of rows in the multiplicand (this)
 +   */
    MatrixI preMultiply(MatrixI m);
  
 +  /**
 +   * Returns a new matrix which is the result of postmultiplying this matrix by
 +   * the supplied argument. If this of size AxB (A rows and B columns), and the
 +   * argument is BxC (B rows and C columns), the result is of size AxC.
 +   * <p>
 +   * This method simply returns the result of in.preMultiply(this)
 +   * 
 +   * @param in
 +   * 
 +   * @return
 +   * @throws IllegalArgumentException
 +   *           if the number of rows in the post-multiplier is not equal to the
 +   *           number of columns in the multiplicand (this)
 +   * @see #preMultiply(Matrix)
 +   */
    MatrixI postMultiply(MatrixI m);
  
    double[] getD();
Simple merge
@@@ -1027,86 -991,22 +1027,103 @@@ public final class MappingUtil
      }
    }
  
 +  /**
 +   * Converts a list of {@code start-end} ranges to a single array of
 +   * {@code start1, end1, start2, ... } ranges
 +   * 
 +   * @param ranges
 +   * @return
 +   */
 +  public static int[] rangeListToArray(List<int[]> ranges)
 +  {
 +    int rangeCount = ranges.size();
 +    int[] result = new int[rangeCount * 2];
 +    int j = 0;
 +    for (int i = 0; i < rangeCount; i++)
 +    {
 +      int[] range = ranges.get(i);
 +      result[j++] = range[0];
 +      result[j++] = range[1];
 +    }
 +    return result;
 +  }
 +
 +  /*
 +   * Returns the maximal start-end positions in the given (ordered) list of
 +   * ranges which is overlapped by the given begin-end range, or null if there
 +   * is no overlap.
 +   * 
 +   * <pre>
 +   * Examples:
 +   *   if ranges is {[4, 8], [10, 12], [16, 19]}
 +   * then
 +   *   findOverlap(ranges, 1, 20) == [4, 19]
 +   *   findOverlap(ranges, 6, 11) == [6, 11]
 +   *   findOverlap(ranges, 9, 15) == [10, 12]
 +   *   findOverlap(ranges, 13, 15) == null
 +   * </pre>
 +   * 
 +   * @param ranges
 +   * @param begin
 +   * @param end
 +   * @return
 +   */
 +  protected static int[] findOverlap(List<int[]> ranges, final int begin,
 +          final int end)
 +  {
 +    boolean foundStart = false;
 +    int from = 0;
 +    int to = 0;
  
 +    /*
 +     * traverse the ranges to find the first position (if any) >= begin,
 +     * and the last position (if any) <= end
 +     */
 +    for (int[] range : ranges)
 +    {
 +      if (!foundStart)
 +      {
 +        if (range[0] >= begin)
 +        {
 +          /*
 +           * first range that starts with, or follows, begin
 +           */
 +          foundStart = true;
 +          from = Math.max(range[0], begin);
 +        }
 +        else if (range[1] >= begin)
 +        {
 +          /*
 +           * first range that contains begin
 +           */
 +          foundStart = true;
 +          from = begin;
 +        }
 +      }
 +
 +      if (range[0] <= end)
 +      {
 +        to = Math.min(end, range[1]);
 +      }
 +    }
 +
 +    return foundStart && to >= from ? new int[] { from, to } : null;
 +  }
++    
+   public static <K, V> Map<K, V> putWithDuplicationCheck(Map<K, V> map, K key,
+           V value)
+   {
+     if (!map.containsKey(key))
+     {
+       map.put(key, value);
+     }
+     else
+     {
+       jalview.bin.Cache.log.warn(
+               "Attempt to add duplicate entry detected for map with key: "
+                       + key.toString() + " and value: " + value.toString());
+     }
+   
+     return map;
 -    
+   }
  }
@@@ -814,25 -824,20 +814,27 @@@ public class DBRefFetcher implements Ru
     */
    private SequenceI[] recoverDbSequences(SequenceI[] sequencesArray)
    {
 -    Vector<SequenceI> nseq = new Vector<>();
 -    for (int i = 0; sequencesArray != null
 -            && i < sequencesArray.length; i++)
 +    int n;
 +    if (sequencesArray == null || (n = sequencesArray.length) == 0)
+     {
 -      nseq.addElement(sequencesArray[i]);
 -      DBRefEntry[] dbr = sequencesArray[i].getDBRefs();
 +      return sequencesArray;
++    }
 +    ArrayList<SequenceI> nseq = new ArrayList<>();
 +    for (int i = 0; i < n; i++)
 +    {
 +      nseq.add(sequencesArray[i]);
 +      List<DBRefEntry> dbr = sequencesArray[i].getDBRefs();
        Mapping map = null;
 -      for (int r = 0; (dbr != null) && r < dbr.length; r++)
 +      if (dbr != null)
        {
 -        if ((map = dbr[r].getMap()) != null)
 +        for (int r = 0, rn = dbr.size(); r < rn; r++)
          {
 -          if (map.getTo() != null && !nseq.contains(map.getTo()))
 +          if ((map = dbr.get(r).getMap()) != null)
            {
 -            nseq.addElement(map.getTo());
 +            if (map.getTo() != null && !nseq.contains(map.getTo()))
 +            {
 +              nseq.add(map.getTo());
 +            }
            }
          }
        }
Simple merge
@@@ -457,9 -457,9 +457,8 @@@ public class Jws2Discoverer implements 
                            sv.action, sv);
                    changeSupport.firePropertyChange("services",
                            new Vector<Jws2Instance>(), services);
-                 }
-               }).start();
+                 };
+               }, "LoadPreferredServiceThread").start();
 -
              }
            });
          }
Simple merge
index 4b7c545,0000000..d3f77b1
mode 100644,000000..100644
--- /dev/null
@@@ -1,298 -1,0 +1,316 @@@
 +eclipse.preferences.version=1
 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
 +org.eclipse.jdt.core.compiler.compliance=11
 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate
 +org.eclipse.jdt.core.compiler.debug.localVariable=generate
 +org.eclipse.jdt.core.compiler.debug.sourceFile=generate
 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
 +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
 +org.eclipse.jdt.core.compiler.source=11
++org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=52
 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0
 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
++org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
++org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
++org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
++org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1
 +org.eclipse.jdt.core.formatter.blank_lines_before_field=1
 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1
 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0
 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line
 +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line
 +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=next_line_on_wrap
 +org.eclipse.jdt.core.formatter.brace_position_for_block=next_line
 +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line
 +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line
 +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line
 +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line
 +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
 +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line
 +org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line
 +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
 +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
 +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
++org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false
 +org.eclipse.jdt.core.formatter.comment.format_block_comments=false
 +org.eclipse.jdt.core.formatter.comment.format_header=false
 +org.eclipse.jdt.core.formatter.comment.format_html=true
 +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
 +org.eclipse.jdt.core.formatter.comment.format_line_comments=true
 +org.eclipse.jdt.core.formatter.comment.format_source_code=true
 +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
 +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
 +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
 +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
 +org.eclipse.jdt.core.formatter.comment.line_length=80
 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
 +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
 +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
 +org.eclipse.jdt.core.formatter.compact_else_if=true
 +org.eclipse.jdt.core.formatter.continuation_indentation=4
 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
 +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
 +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
 +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
 +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
 +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
 +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
 +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
 +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
 +org.eclipse.jdt.core.formatter.indent_empty_lines=false
 +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
 +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
 +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
 +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
 +org.eclipse.jdt.core.formatter.indentation.size=8
++org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
 +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
 +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
 +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
 +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
 +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
 +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
 +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
 +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
 +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
 +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
 +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
 +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
 +org.eclipse.jdt.core.formatter.join_lines_in_comments=true
 +org.eclipse.jdt.core.formatter.join_wrapped_lines=true
 +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
 +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=true
 +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
 +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
 +org.eclipse.jdt.core.formatter.lineSplit=76
 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
 +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
 +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
++org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
++org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
++org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
++org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
++org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
++org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
++org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
++org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
++org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
++org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
 +org.eclipse.jdt.core.formatter.tabulation.char=space
 +org.eclipse.jdt.core.formatter.tabulation.size=2
 +org.eclipse.jdt.core.formatter.use_on_off_tags=true
 +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
++org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
 +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
++org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
 +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
 +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
 +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning