[med-svn] [SCM] igv branch, master, updated. upstream/1.5.21-49-g6cfce68

Andreas Tille tille at debian.org
Sat Mar 12 23:26:37 UTC 2011


The following commit has been merged in the master branch:
commit 6cfce68c8ca9c43b80a3be5c8658f1332b8b18fa
Merge: 5dc74793169055c6450091cbcb7caf543b95eb5e 2321f628e95797bed4f6d5e3d349510d6292ab06
Author: Andreas Tille <tille at debian.org>
Date:   Sun Mar 13 00:25:50 2011 +0100

    Merge commit 'upstream/1.5.56'
    
    Conflicts:
    	build.xml
    	igv_mac-intel.command
    	igv_win.bat
    	src/log4j.properties
    	src/org/broad/igv/IGVPreferences.java
    	src/org/broad/igv/PreferenceManager.java
    	src/org/broad/igv/das/DASFeatureSource.java
    	src/org/broad/igv/data/AbstractDataSource.java
    	src/org/broad/igv/data/IGVDataset.java
    	src/org/broad/igv/data/IGVDatasetParser.java
    	src/org/broad/igv/data/seg/SegmentedDataWriter.java
    	src/org/broad/igv/exceptions/DataLoadException.java
    	src/org/broad/igv/feature/Exon.java
    	src/org/broad/igv/feature/GFFParser.java
    	src/org/broad/igv/feature/GeneManager.java
    	src/org/broad/igv/feature/Genome.java
    	src/org/broad/igv/feature/GenomeImporter.java
    	src/org/broad/igv/feature/GenomeManager.java
    	src/org/broad/igv/feature/dranger/DRangerFeature.java
    	src/org/broad/igv/h5/HDF5EntityCache.java
    	src/org/broad/igv/h5/HDF5LocalReader.java
    	src/org/broad/igv/h5/HDF5ReaderFactory.java
    	src/org/broad/igv/h5/TestH5String.java
    	src/org/broad/igv/maf/MAFRemoteReader.java
    	src/org/broad/igv/main/BatchRunner.java
    	src/org/broad/igv/main/CommandExecutor.java
    	src/org/broad/igv/renderer/BasicFeatureRenderer.java
    	src/org/broad/igv/sam/AbstractAlignment.java
    	src/org/broad/igv/sam/Alignment.java
    	src/org/broad/igv/sam/AlignmentDataManager.java
    	src/org/broad/igv/sam/AlignmentInterval.java
    	src/org/broad/igv/sam/AlignmentLoader.java
    	src/org/broad/igv/sam/AlignmentRenderer.java
    	src/org/broad/igv/sam/AlignmentTrack.java
    	src/org/broad/igv/sam/CoverageTrack.java
    	src/org/broad/igv/sam/DotAlignedAlignment.java
    	src/org/broad/igv/sam/FeatureWrappedAlignment.java
    	src/org/broad/igv/sam/SamAlignment.java
    	src/org/broad/igv/sam/reader/BAMHttpQueryReader.java
    	src/org/broad/igv/sam/reader/CachingQueryReader.java
    	src/org/broad/igv/sam/reader/FeatureIndex.java
    	src/org/broad/igv/sam/reader/GeraldParser.java
    	src/org/broad/igv/sam/reader/GeraldQueryReader.java
    	src/org/broad/igv/sam/reader/SamQueryReaderFactory.java
    	src/org/broad/igv/sam/reader/SamQueryTextReader.java
    	src/org/broad/igv/sam/reader/SamUtils.java
    	src/org/broad/igv/session/Session.java
    	src/org/broad/igv/session/SessionReader.java
    	src/org/broad/igv/session/SessionWriter.java
    	src/org/broad/igv/session/ViewContext.java
    	src/org/broad/igv/tdf/TDFDataset.java
    	src/org/broad/igv/tdf/TDFReader.java
    	src/org/broad/igv/tools/IgvTools.java
    	src/org/broad/igv/tools/IgvToolsGui.java
    	src/org/broad/igv/track/AttributeManager.java
    	src/org/broad/igv/track/FeatureDirSource.java
    	src/org/broad/igv/track/FeatureTrack.java
    	src/org/broad/igv/track/IndexedBEDFeatureSource.java
    	src/org/broad/igv/track/TrackLoader.java
    	src/org/broad/igv/track/TrackManager.java
    	src/org/broad/igv/track/TrackMenuUtils.java
    	src/org/broad/igv/track/tribble/CachingFeatureReader.java
    	src/org/broad/igv/track/tribble/CodecFactory.java
    	src/org/broad/igv/track/tribble/TribbleFeatureSource.java
    	src/org/broad/igv/ui/IGVCommandBar.java
    	src/org/broad/igv/ui/IGVMainFrame.java
    	src/org/broad/igv/ui/PreferencesEditor.java
    	src/org/broad/igv/ui/PreferencesEditor.jfd
    	src/org/broad/igv/ui/ShutdownThread.java
    	src/org/broad/igv/ui/UIConstants.java
    	src/org/broad/igv/ui/action/FitDataToWindowMenuAction.java
    	src/org/broad/igv/ui/action/LoadFromServerAction.java
    	src/org/broad/igv/ui/action/LoadFromURLMenuAction.java
    	src/org/broad/igv/ui/action/OpenSessionMenuAction.java
    	src/org/broad/igv/ui/action/RegionsBaseMenuAction.java
    	src/org/broad/igv/ui/action/SearchCommand.java
    	src/org/broad/igv/util/FileUtils.java
    	src/org/broad/igv/util/LRUCache.java
    	src/org/broad/igv/util/MacroSnapshotAction.java
    	src/org/broad/igv/util/SeekableFileStream.java
    	src/org/broad/tribble/readers/BasicFeatureReader.java
    	src/resources/about.properties

diff --combined build.xml
index d86c1f2,253fe5c..d76db4b
--- a/build.xml
+++ b/build.xml
@@@ -26,14 -26,6 +26,6 @@@
      <property name="src.dir"       value="${basedir}/src/" />
      <property name="lib.dir"       value="${basedir}/lib/" />
  
-     <!-- Platform specific input files -->
-     <property name="native.dir"        value="${basedir}/native/" />
-     <property name="win.dir"           value="${native.dir}/win/" />
-     <property name="mac.intel.dir"     value="${native.dir}/mac-intel/" />
-     <property name="mac.powerpc.dir"   value="${native.dir}/mac-powerpc/" />
-     <property name="linux64.dir"       value="${native.dir}/linux-64/" />
-     <property name="linux.dir"       value="${native.dir}/linux/" />
- 
      <!-- Temp directory.  Sources are compiled here prior to archiving -->
      <property name="tmp.dir"       value="${basedir}/tmp/" />
      <property name="resource.dir"  value="${tmp.dir}resources/" />
@@@ -45,6 -37,7 +37,7 @@@
      <property name="build-number"  value="0" />
      <property name="version"       value="${build-number}" />
      <property name="data-server-url"    value="http://www.broad.mit.edu/igv/resources/dataServerRegistry" />
+     <property name="genome-server-url"    value="http://igv.broadinstitute.org/genomes/genomes.txt" />
  
  
      <!-- Clean all generated artifacts -->
@@@ -90,8 -83,6 +83,11 @@@
  			<pathelement path="${lib.dir}commons-net-2.0.jar" />
              <pathelement path="${lib.dir}concurrent.jar" />
              <pathelement path="${lib.dir}jargs.jar" />
++<<<<<<< HEAD
 +            <pathelement path="${lib.dir}jhdf5.jar" />
 +            <pathelement path="${lib.dir}jhdf.jar" />
++=======
++>>>>>>> upstream/1.5.56
              <pathelement path="${lib.dir}jide-action.jar" />
              <pathelement path="${lib.dir}jide-common.jar" />
              <pathelement path="${lib.dir}jide-components.jar" />
@@@ -101,7 -92,7 +97,11 @@@
              <pathelement path="${lib.dir}jlfgr-1_0.jar" />
              <pathelement path="${lib.dir}junit-4.5.jar" />   
              <pathelement path="${lib.dir}log4j-1.2.15.jar" />
++<<<<<<< HEAD
 +            <pathelement path="${lib.dir}sam-1.21.jar" />
++=======
+             <pathelement path="${lib.dir}sam-1.38.jar" />
++>>>>>>> upstream/1.5.56
              <pathelement path="${lib.dir}swing-layout-1.0.jar" />           
              <pathelement path="${lib.dir}xml-apis-ext-1.3.04" />
              <pathelement path="${lib.dir}xml-apis-1.3.04.jar" />
@@@ -121,6 -112,7 +121,7 @@@
          <replace file="${resource.dir}about.properties" token="@BUILD" value="${build-number}"/>
          <replace file="${resource.dir}about.properties" token="@TIMESTAMP" value="${timestamp}"/>
          <replace file="${resource.dir}about.properties" token="@DEFAULT_MASTER_RESOURCE_URL" value="${data-server-url}"/>
+         <replace file="${resource.dir}about.properties" token="@DEFAULT_MASTER_GENOME_URL" value="${genome-server-url}"/>
  
      </target>
  
diff --combined igv_win.bat
index 52dbd20,fcc5980..a2de71e
--- a/igv_win.bat
+++ b/igv_win.bat
@@@ -1,4 -1,4 +1,8 @@@
  ::Get the current batch file's short path
  for %%x in (%0) do set BatchPath=%%~dpsx
  for %%x in (%BatchPath%) do set BatchPath=%%~dpsx
- java -Xmx750m -Djava.library.path=./native/win -Dsun.java2d.noddraw=true -jar %BatchPath%\igv.jar
 -java -Xmx750m -Dsun.java2d.noddraw=true -jar %BatchPath%\igv.jar
++<<<<<<< HEAD
++java -Xmx750m -Djava.library.path=./native/win -Dsun.java2d.noddraw=true -jar %BatchPath%\igv.jar
++=======
++java -Xmx750m -Dsun.java2d.noddraw=true -jar %BatchPath%\igv.jar
++>>>>>>> upstream/1.5.56
diff --combined src/log4j.properties
index df14b6c,5779623..363927b
--- a/src/log4j.properties
+++ b/src/log4j.properties
@@@ -1,5 -1,5 +1,10 @@@
++<<<<<<< HEAD
 +#log4j.rootLogger=INFO, stdout, R
 +log4j.rootLogger=DEBUG, stdout, R
++=======
+ log4j.rootLogger=INFO, stdout, R
+ #log4j.rootLogger=DEBUG, stdout, R
++>>>>>>> upstream/1.5.56
  #log4j.logger.org.broad.igv.sam=DEBUG, stdout, R
  
  
diff --combined src/org/broad/igv/IGVPreferences.java
index 4c79e8c,3cc7550..0d05434
--- a/src/org/broad/igv/IGVPreferences.java
+++ b/src/org/broad/igv/IGVPreferences.java
@@@ -39,12 -39,9 +39,14 @@@ import java.util.Map
  public class IGVPreferences {
  
      private static Logger log = Logger.getLogger(IGVPreferences.class);
++<<<<<<< HEAD
 +    static File rootDir = new File(UIConstants.DEFAULT_IGV_DIRECTORY);
 +    static File prefFile = new File(rootDir, "prefs.properties");
++=======
++>>>>>>> upstream/1.5.56
      static Hashtable<String, String> cache = null;
      boolean suspendStorage = false;
  
- 
      public void put(String key, String value) {
          if (cache == null) {
              loadPreferences();
@@@ -93,6 -90,11 +95,11 @@@
  
      private synchronized void loadPreferences() {
          cache = new Hashtable();
+         File rootDir = UIConstants.getIgvDirectory();
+         if (!rootDir.exists()) {
+             rootDir.mkdir();
+         }
+         File prefFile = new File(rootDir, "prefs.properties");
          if (prefFile.exists()) {
              BufferedReader reader = null;
              try {
@@@ -131,10 -133,11 +138,11 @@@
          if (cache != null) {
              PrintWriter pw = null;
              try {
+                 File rootDir = UIConstants.getIgvDirectory();
                  if (!rootDir.exists()) {
                      rootDir.mkdir();
                  }
- 
+                 File prefFile = new File(rootDir, "prefs.properties");
                  pw = new PrintWriter(new BufferedWriter(new FileWriter(prefFile)));
                  for (Map.Entry<String, String> entry : cache.entrySet()) {
                      pw.print(entry.getKey());
diff --combined src/org/broad/igv/PreferenceManager.java
index 3ab4344,5f04568..0322b18
--- a/src/org/broad/igv/PreferenceManager.java
+++ b/src/org/broad/igv/PreferenceManager.java
@@@ -32,6 -32,7 +32,10 @@@ import org.broad.igv.ui.AboutDialog
  import org.broad.igv.ui.UIConstants;
  import org.broad.igv.ui.util.PropertyManager;
  import org.broad.igv.ui.util.ColorTable;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.util.IGVHttpUtils;
++>>>>>>> upstream/1.5.56
  
  import static org.broad.igv.ui.util.UIUtilities.getcommaSeparatedRGBString;
  
@@@ -79,7 -80,7 +83,11 @@@ public class PreferenceManager implemen
      final public static String SHOW_MISSING_DATA_KEY = "IGVMainFrame.track.show.missing.data";
      final public static String SHOW_ATTRIBUTE_VIEWS_KEY = "IGVMainFrame.track.show.attribute.views";
      final public static String SHOW_SINGLE_TRACK_PANE_KEY = "IGVMainFrame.single.track.pane";
++<<<<<<< HEAD
 +    final public static String GENOMES_SEQUENCE_URL = "IGVMainFrame.genome.sequence.dir";
++=======
+ 
++>>>>>>> upstream/1.5.56
      final public static String JOIN_ADJACENT_SEGMENTS_KEY = "IGVMainFrame.join.adjacent.segments";
      final public static String SHOW_REGION_TOOL_KEY = "IGVMainFrame.show.region.tool";
      final public static String SHOW_REGION_BARS = "SHOW_REGION_BARS";
@@@ -105,7 -106,7 +113,7 @@@
      final public static String COLOR_OVERLAY_KEY = "COVER_OVERLAY_KEY";
      final public static String ENABLE_LINKED_SORTING = "ENABLE_LINKED_SORTING";
      final public static String TRACK_ATTRIBUTE_NAME_KEY = "TRACK_ATTRIBUTE_NAME_KEY";
-     final public static String DATA_SERVER_URL_KEY = "MASTER_RESOURCE_FILE_KEY";
+ 
      final public static String CHECKED_RESOURCES_KEY = "CHECKED_RESOURCES_KEY";
      final public static String DEFINE_GENOME_INPUT_DIRECTORY_KEY = "DEFINE_GENOME_INPUT_DIRECTORY_KEY";
      final public static String LAST_CYTOBAND_DIRECTORY_KEY = "LAST_CYTOBAND_DIRECTORY_KEY";
@@@ -132,7 -133,12 +140,16 @@@
  
      final public static String USE_BYTE_RANGE = "UseHttpByteRange";
  
++<<<<<<< HEAD
++    public static String DEFAULT_DATA_SERVER_URL;
++=======
+     final public static String DATA_SERVER_URL_KEY = "MASTER_RESOURCE_FILE_KEY";
+     final public static String GENOMES_SEQUENCE_URL = "IGVMainFrame.genome.sequence.dir";
+ 
      public static String DEFAULT_DATA_SERVER_URL;
+     public static String DEFAULT_GENOME_SERVER_URL;
+ 
++>>>>>>> upstream/1.5.56
  
      static {
          Properties properties = new Properties();
@@@ -142,9 -148,18 +159,24 @@@
              if (DEFAULT_DATA_SERVER_URL.equals("@DEFAULT_MASTER_RESOURCE_URL")) {
                  DEFAULT_DATA_SERVER_URL = "http://www.broadinstitute.org/igvdata/$$_dataServerRegistry.txt";
              }
++<<<<<<< HEAD
++        } catch (IOException e) {
++            DEFAULT_DATA_SERVER_URL = "http://www.broadinstitute.org/igvdata/$$_dataServerRegistry.txt";
++        }
++=======
+ 
+             DEFAULT_GENOME_SERVER_URL = properties.getProperty("master-genome-url", "http://igv.broadinstitute.org/genomes/genomes.txt");
+             if (DEFAULT_GENOME_SERVER_URL.equals("@DEFAULT_MASTER_GENOME_URL")) {
+                 DEFAULT_GENOME_SERVER_URL = "http://igv.broadinstitute.org/genomes/genomes.txt";
+             }
+ 
+             //GENOMES_SEQUENCE_URL
          } catch (IOException e) {
              DEFAULT_DATA_SERVER_URL = "http://www.broadinstitute.org/igvdata/$$_dataServerRegistry.txt";
+             DEFAULT_GENOME_SERVER_URL = "http://igv.broadinstitute.org/genomes/genomes.txt";
          }
+ 
++>>>>>>> upstream/1.5.56
      }
  
      /**
@@@ -284,7 -299,7 +316,7 @@@
  
      public void putAll(Map<String, String> updatedPrefs) {
          for (Map.Entry<String, String> entry : updatedPrefs.entrySet()) {
-             if (entry.getValue() == null) {
+             if (entry.getValue() == null || entry.getValue().trim().length() == 0) {
                  remove(entry.getKey());
  
              } else {
@@@ -292,7 -307,6 +324,6 @@@
              }
          }
          clearCaches();
- 
      }
  
  
@@@ -332,7 -346,7 +363,11 @@@
  
      public String getGenomeListURL() {
          return get(PreferenceManager.GENOMES_SEQUENCE_URL,
++<<<<<<< HEAD
 +                UIConstants.DEFAULT_SERVER_GENOME_ARCHIVE_LIST);
++=======
+                 DEFAULT_GENOME_SERVER_URL);
++>>>>>>> upstream/1.5.56
      }
  
  
@@@ -540,7 -554,7 +575,11 @@@
  
          File directory = null;
  
++<<<<<<< HEAD
 +        String lastFilePath = get(DEFINE_GENOME_INPUT_DIRECTORY_KEY, UIConstants.getDefaultUserDirectory());
++=======
+         String lastFilePath = get(DEFINE_GENOME_INPUT_DIRECTORY_KEY, UIConstants.getUserDirectory().getAbsolutePath());
++>>>>>>> upstream/1.5.56
  
          if (lastFilePath != null) {
              directory = new File(lastFilePath);
@@@ -564,7 -578,7 +603,11 @@@
  
          File genomeImportDirectory = null;
  
++<<<<<<< HEAD
 +        String lastFilePath = get(LAST_GENOME_IMPORT_DIRECTORY, UIConstants.getDefaultUserDirectory());
++=======
+         String lastFilePath = get(LAST_GENOME_IMPORT_DIRECTORY, UIConstants.getUserDirectory().getAbsolutePath());
++>>>>>>> upstream/1.5.56
  
          if (lastFilePath != null) {
              genomeImportDirectory = new File(lastFilePath);
@@@ -590,7 -604,7 +633,11 @@@
  
          File directory = null;
  
++<<<<<<< HEAD
 +        String lastFilePath = get(LAST_CYTOBAND_DIRECTORY_KEY, UIConstants.getDefaultUserDirectory());
++=======
+         String lastFilePath = get(LAST_CYTOBAND_DIRECTORY_KEY, UIConstants.getUserDirectory().getAbsolutePath());
++>>>>>>> upstream/1.5.56
  
          if (lastFilePath != null) {
              directory = new File(lastFilePath);
@@@ -616,7 -630,7 +663,11 @@@
  
          File directory = null;
  
++<<<<<<< HEAD
 +        String lastFilePath = get(LAST_REFFLAT_DIRECTORY_KEY, UIConstants.getDefaultUserDirectory());
++=======
+         String lastFilePath = get(LAST_REFFLAT_DIRECTORY_KEY, UIConstants.getUserDirectory().getAbsolutePath());
++>>>>>>> upstream/1.5.56
  
          if (lastFilePath != null) {
              directory = new File(lastFilePath);
@@@ -642,7 -656,7 +693,11 @@@
  
          File directory = null;
  
++<<<<<<< HEAD
 +        String lastFilePath = get(LAST_FASTA_DIRECTORY_KEY, UIConstants.getDefaultUserDirectory());
++=======
+         String lastFilePath = get(LAST_FASTA_DIRECTORY_KEY, UIConstants.getUserDirectory().getAbsolutePath());
++>>>>>>> upstream/1.5.56
  
          if (lastFilePath != null) {
              directory = new File(lastFilePath);
@@@ -668,7 -682,7 +723,11 @@@
  
          File directory = null;
  
++<<<<<<< HEAD
 +        String lastFilePath = get(LAST_SEQUENCE_DIRECTORY_KEY, UIConstants.getDefaultUserDirectory());
++=======
+         String lastFilePath = get(LAST_SEQUENCE_DIRECTORY_KEY, UIConstants.getUserDirectory().getAbsolutePath());
++>>>>>>> upstream/1.5.56
  
          if (lastFilePath != null) {
              directory = new File(lastFilePath);
@@@ -870,7 -884,7 +929,7 @@@
       */
      public String getDefaultGenome() {
  
-         String genome = get(DEFAULT_GENOME_KEY, "hg18");
+         String genome = get(DEFAULT_GENOME_KEY, null);
          return genome;
      }
  
@@@ -984,7 -998,7 +1043,11 @@@
  
  
      public ContinuousColorScale getColorScale(TrackType type) {
++<<<<<<< HEAD
 +        if(type == null) {
++=======
+         if (type == null) {
++>>>>>>> upstream/1.5.56
              return null;
          }
  
@@@ -1254,6 -1268,18 +1317,21 @@@
          public void setShowDataRange(boolean showDataRange) {
              this.showDataRange = showDataRange;
          }
++<<<<<<< HEAD
++=======
+     }
+ 
+ 
+     public void clearProxySettings() {
+ 
+         remove(PreferenceManager.USE_PROXY);
+         remove(PreferenceManager.PROXY_HOST);
+         remove(PreferenceManager.PROXY_PORT);
+         remove(PreferenceManager.PROXY_AUTHENTICATE);
+         remove(PreferenceManager.PROXY_USER);
+         remove(PreferenceManager.PROXY_PW);
+         IGVHttpUtils.updateProxySettings();
++>>>>>>> upstream/1.5.56
      }
  
      /**
@@@ -1274,7 -1300,7 +1352,11 @@@
              prefs.setShadeCenter(getBooleanPreference(SAMPreferences.SHADE_CENTER, true));
              prefs.setShowRefSequence(getBooleanPreference(SAMPreferences.SHOW_REF_SEQ, false));
              prefs.setShowCoverageTrack(getBooleanPreference(SAMPreferences.SHOW_COV_TRACK, true));
++<<<<<<< HEAD
 +            prefs.setMaxLevels(getIntegerPreference(SAMPreferences.MAX_LEVELS, 500000));
++=======
+             prefs.setMaxLevels(getIntegerPreference(SAMPreferences.MAX_LEVELS, 100));
++>>>>>>> upstream/1.5.56
              prefs.setMaxReads(getIntegerPreference(SAMPreferences.MAX_READS, 500000));
              prefs.setShadeBaseQuality(getBooleanPreference(SAMPreferences.SHADE_BASE_QUALITY, true));
              prefs.setBaseQualityMin(getIntegerPreference(SAMPreferences.BASE_QUALITY_MIN, 5));
@@@ -1334,7 -1360,7 +1416,11 @@@
          private boolean filterFailedReads = true;
          private String filterURL;
          private float maxVisibleRange;
++<<<<<<< HEAD
 +        private int maxLevels;
++=======
+         private int maxLevels = 100;
++>>>>>>> upstream/1.5.56
          private int maxReads = 500000;
          private int qualityThreshold;
          private boolean showDuplicates;
diff --combined src/org/broad/igv/das/DASFeatureSource.java
index fe34968,3f53ef8..b28d17d
--- a/src/org/broad/igv/das/DASFeatureSource.java
+++ b/src/org/broad/igv/das/DASFeatureSource.java
@@@ -18,331 -18,456 +18,779 @@@
  package org.broad.igv.das;
  
  import org.apache.log4j.Logger;
++<<<<<<< HEAD
 +import org.broad.igv.data.DataSource;
 +import org.broad.igv.exceptions.DataLoadException;
 +import org.broad.igv.feature.*;
 +import org.broad.igv.track.FeatureSource;
++=======
+ import org.broad.igv.exceptions.DataLoadException;
+ import org.broad.igv.feature.*;
+ import org.broad.igv.session.ViewContext;
+ import org.broad.igv.track.FeatureSource;
+ import org.broad.igv.track.tribble.CachingFeatureReader;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.ui.WaitCursorManager;
  import org.broad.igv.ui.util.MessageUtils;
  import org.broad.igv.util.IGVHttpUtils;
  import org.broad.igv.util.LRUCache;
  import org.broad.igv.util.ResourceLocator;
++<<<<<<< HEAD
 +import org.w3c.dom.Document;
 +import org.w3c.dom.Element;
 +import org.w3c.dom.NamedNodeMap;
 +import org.w3c.dom.Node;
 +import org.w3c.dom.traversal.DocumentTraversal;
 +import org.w3c.dom.traversal.NodeFilter;
 +import org.w3c.dom.traversal.TreeWalker;
++=======
+ import org.broad.tribble.FeatureReader;
+ import org.broad.tribble.util.CloseableTribbleIterator;
+ import org.w3c.dom.*;
+ import org.w3c.dom.traversal.DocumentTraversal;
+ import org.w3c.dom.traversal.NodeFilter;
+ import org.w3c.dom.traversal.TreeWalker;
+ import org.xml.sax.EntityResolver;
+ import org.xml.sax.InputSource;
++>>>>>>> upstream/1.5.56
  import org.xml.sax.SAXException;
  
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  import javax.xml.parsers.ParserConfigurationException;
++<<<<<<< HEAD
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.net.HttpURLConnection;
++=======
+ import java.io.*;
+ import java.net.HttpURLConnection;
+ import java.net.MalformedURLException;
++>>>>>>> upstream/1.5.56
  import java.net.URL;
  import java.util.*;
  
  
++<<<<<<< HEAD
 +//http://das.sanger.ac.uk/das/cosmic_mutations/
++=======
+ //http://das.sanger.ac.uk/das/cosmic_mutations/features
+ //http://genome.ucsc.edu/cgi-bin/das/hg16/features?segment=1:1,100000;type=refGene
++>>>>>>> upstream/1.5.56
  
  public class DASFeatureSource implements FeatureSource {
  
      private static Logger log = Logger.getLogger(DASFeatureSource.class);
++<<<<<<< HEAD
 +    private LRUCache<String, List<Feature>> featureCache = new LRUCache<String, List<Feature>>(30);
 +    private String serverPath;
 +    private String[] capabilities;
 +    private String label;
 +    private boolean isValid = true;
 +
 +    public DASFeatureSource(ResourceLocator locator) {
 +        validatePath(pathConform(locator.getPath()));
 +    }
 +
 +    public Iterator<Feature> getFeatures(String chr, int start, int end) {
 +        return getFeatures(chrConform(chr)).iterator();
 +    }
 +
 +    private String pathConform(String path) {
 +
 +        if (path.endsWith("/")) {
 +            return path = path.substring(0, path.length() - 1);
 +        }
 +
 +        String[] parts = path.split("/");
 +        if (parts[parts.length - 1].equalsIgnoreCase("feature")) {
 +            return path.replace(parts[parts.length - 1], "");
 +        }
 +
 +        return path;
 +    }
 +
 +    private List<Feature> getFeatures(String chr) {
 +        chr = chrConform(chr);
 +        if (!chr.equals("All")) {
 +            if (!isCapable("feature")) {
 +                throw new DataLoadException("Server is not Feature Capable", serverPath);
 +            }
 +            if (featureCache.containsKey(chr)) {
 +                return featureCache.get(chr);
 +            } else {
 +                if (isValid) {
 +                    WaitCursorManager.CursorToken token = WaitCursorManager.showWaitCursor();
 +                    try {
 +                        List<Feature> features = gatherFeatures(chr, 1, Integer.MAX_VALUE);
 +                        if (features.size() < 1) {
 +                            return Collections.emptyList();
 +                        }
 +                        FeatureUtils.sortFeatureList(features);
 +                        featureCache.put(chr, features);
 +                        return featureCache.get(chr);
 +                    } finally {
 +                        WaitCursorManager.removeWaitCursor(token);
 +                    }
 +                }
 +            }
 +        }
 +        return new ArrayList<Feature>();
 +    }
 +
 +    
 +
 +    public List<LocusScore> getCoverageScores(String chr, int startLocation, int endLocation, int zoom) {
 +        return null;  //To change body of implemented methods use File | Settings | File Templates.
 +    }
 +
 +    public int getBinSize() {
 +        return 0;  //To change body of implemented methods use File | Settings | File Templates.
 +    }
 +
 +    public void setBinSize(int size) {
 +        // ignored
 +    }
 +
 +    public DataSource getCoverageSource() {
 +        return null;  //To change body of implemented methods use File | Settings | File Templates.
 +    }
 +
 +
 +    private String chrConform(String chr) {
 +        if (chr.startsWith("chr")) {
 +            return chr.substring(3, chr.length());
 +        }
 +        return chr;
 +    }
 +
 +    private List<Feature> gatherFeatures(String chr, int start, int stop) {
 +        List<Feature> features = new ArrayList<Feature>();
 +        try {
 +            URL dataQuery = new URL(serverPath + "/features?" + "segment=" + chr + ":" + start + "," + stop);
 +            Document dom = getDocument(dataQuery);
 +            if (dom == null) {
 +                return Collections.emptyList();
 +            }
 +            return parseDocument(dom, chr, features);
 +
 +        } catch (IOException ioe) {
 +            throw new DataLoadException("Failed to reconnect with server", serverPath);
 +        }
 +    }
 +
 +    private void validatePath(String path) {
 +
 +        try {
 +            URL serverURL = new URL(path);
 +            HttpURLConnection connection = IGVHttpUtils.openConnection(serverURL);
 +            String headerCaps = connection.getHeaderField("X-DAS-Capabilities");
 +            if (headerCaps == null) {
 +                throw new DataLoadException("No DAS capabilities found, closing connection.", path);
 +            }
 +
 +            capabilities = headerCaps.split(";");
 +            String[] parts = path.split("//");
 +            if (parts.length > 1)
 +                path = parts[1];
 +            if (path.length() > 15) {
 +                label = path.substring(0, 15) + "..";
 +            } else {
 +                label = path;
 +            }
 +            serverPath = serverURL.toExternalForm();
 +            connection.disconnect();
 +        } catch (IOException ioe) {
 +            throw new DataLoadException("Could not complete connection to server", path);
 +        }
 +    }
 +
 +    private Document getDocument(URL query) {
 +        InputStream is = null;
 +        try {
 +            HttpURLConnection serverConnection = IGVHttpUtils.openConnection(query);
 +            serverConnection.connect();
 +            is = serverConnection.getInputStream();
 +            return createDocument(is);
 +        } catch (Exception e) {
 +            isValid = false;
 +            log.error(e);
 +            MessageUtils.showMessage("<html>The DAS Server: " + serverPath + " has returned an error or invalid data." +
 +                    "<br>" + e.getMessage());
 +            return null;
 +        }
 +        finally {
 +            if (is != null) {
 +                try {
 +                    is.close();
 +                } catch (IOException e) {
 +                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
 +                }
 +            }
 +        }
 +    }
 +
 +    private Document createDocument(InputStream inputStream)
 +            throws ParserConfigurationException, IOException, SAXException {
 +        DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 +        Document dom = documentBuilder.parse(inputStream);
 +        inputStream.close();
 +        return dom;
 +    }
 +
 +    public String getPath() {
 +        return serverPath;
 +    }
 +
 +    public boolean isCapable(String capability) {
 +
 +        if (capabilities != null) {
 +            for (String a : Arrays.asList(capabilities)) {
 +                if (a.toLowerCase().contains(capability.toLowerCase())) {
 +                    return true;
 +                }
 +            }
 +        }
 +        return false;
 +    }
 +
 +    private List<Feature> parseDocument(Document dasDoc, String chr, List<Feature> features) {
 +
 +        try {
 +            DocumentTraversal traversal = (DocumentTraversal) dasDoc;
 +            TreeWalker treewalker = traversal.createTreeWalker(
 +                    dasDoc.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);
 +            return parseTree(treewalker, "FEATURE", chr, features);
 +
 +        } catch (Exception ex) {
 +            log.error(ex);
 +        }
 +        return new ArrayList<Feature>();
 +    }
 +
 +    private List<Feature> parseTree(TreeWalker walker,
 +                                    String tag,
 +                                    String chr, List<Feature> features) {
 +
 +        Node parent = walker.getCurrentNode();
 +        Node n = walker.firstChild();
 +        while (n != null) {
 +            if (((Element) n).getTagName().equalsIgnoreCase(tag)) {
 +                features.add(getFeature(walker, chr));
 +                n = walker.nextSibling();
 +//                if (features.size() > 16384){
 +//                    break;
 +//                }
 +                continue;
 +            }
 +            parseTree(walker, tag, chr, features);
 +            n = walker.nextSibling();
 +        }
 +        walker.setCurrentNode(parent);
 +        return features;
 +    }
 +
 +    private BasicFeature getFeature(TreeWalker walker, String chr) {
 +
 +        String start = "0",
 +                end = "0",
 +                orientation = "",
 +                id = "",
 +                label = "",
 +                description = "",
 +                type = "",
 +                link = "",
 +                method = "";
 +        Strand strand = Strand.NONE;
 +        Node parent = walker.getCurrentNode();
 +
 +        //GET THE FEATURE ATTRIBUTES
 +        NamedNodeMap nnm = parent.getAttributes();
 +        Node tmpNode = nnm.getNamedItem("id");
 +        id = tmpNode.getTextContent();
 +        tmpNode = nnm.getNamedItem("label");
 +        label = tmpNode.getTextContent();
 +
 +        //GO THROUGH FEATURE NODES
 +        for (Node n = walker.firstChild(); n != null;
 +             n = walker.nextSibling()) {
 +
 +            if (((Element) n).getTagName().equalsIgnoreCase("START")) {
 +                start = n.getTextContent();
 +            }
 +            if (((Element) n).getTagName().equalsIgnoreCase("END")) {
 +                end = n.getTextContent();
 +            }
 +            if (((Element) n).getTagName().equalsIgnoreCase("ORIENTATION")) {
 +                orientation = n.getTextContent();
 +                if (orientation.equals("-")) {
 +                    strand = Strand.NEGATIVE;
 +                } else if (orientation.equalsIgnoreCase("+")) {
 +                    strand = Strand.POSITIVE;
 +                }
 +            }
 +            if (((Element) n).getTagName().equalsIgnoreCase("NOTE")) {
 +                description = n.getTextContent();
 +            }
 +            if (((Element) n).getTagName().equalsIgnoreCase("TYPE")) {
 +                type = n.getTextContent();
 +            }
 +            if (((Element) n).getTagName().equalsIgnoreCase("LINK")) {
 +                NamedNodeMap tmpnnm = n.getAttributes();
 +                Node tmpnode = tmpnnm.getNamedItem("href");
 +                link = tmpnode.getTextContent();
 +            }
 +            if (((Element) n).getTagName().equalsIgnoreCase("METHOD")) {
 +                method = n.getTextContent();
 +            }
 +        }
 +
 +        //SET FEATURE ATTRIBUTES
 +
 +        walker.setCurrentNode(parent);
 +
 +        // Convert from Ensemble -> UCSC coordinates
 +        int s = Integer.parseInt(start) - 1;
 +        int e = Math.max(s + 1, Integer.parseInt(end));
 +
 +        BasicFeature feature = new BasicFeature(chr, s, e);
 +        label = label.replace("?", " ");
 +        description = description.replace("&nbsp;", "<br>");
 +        description = description.replace("<br><br><br>", "<br>");
 +        description = description.replace("<br><br>", "<br>");
 +        description = description.replace(":", ":&nbsp;");
 +        description = description.replace("?", " ");
 +        description = description + "<br>TYPE:&nbsp;" + type;
 +        feature.setIdentifier(id);
 +        feature.setName(label);
 +        feature.setDescription(description);
 +        feature.setType(type);
 +        if (link.length() > 0) {
 +            feature.setURL(link);
 +        }
 +
 +
 +        //TODO Make another Color panel on the preferences for the different feature colors
 +        //TODO Would like to base it on one of the kuler panels
 +        //Using Colors from http://kuler.adobe.com/#themeID/659786
 +
 +        return feature;
++=======
+     private static final IteratorWrapper EMPTY__ITERATOR = new IteratorWrapper(new ArrayList<Feature>().iterator());
+ 
+     private String path;
+     private String serverURL;
+     private boolean isValid = true;
+     CachingFeatureReader reader;
+     int binSize = 250000;
+     private String type;
+     String[] parameters;
+     Map<String, BasicFeature> groupFeatureCache = new HashMap(10000);
+ 
+ 
+ 
+     public DASFeatureSource(ResourceLocator locator) throws MalformedURLException {
+         URL url = new URL(locator.getPath());
+         String host = url.getHost();
+         String protocol = url.getProtocol();
+         path = url.getPath();
+         serverURL = protocol + "://" + host + path;
+ 
+         String paramString = url.getQuery();
+         if (paramString != null) {
+             parameters = paramString.split(";");
+ 
+             for (String param : parameters) {
+                 if (param.startsWith("type=")) {
+                     type = param.substring(5);
+                 }
+             }
+         }
+ 
+         if (locator.getPath().contains("genome.ucsc.edu") && type == null) {
+             throw new DataLoadException("<html>Feature type is required for UCSC DAS tracks. <br>" +
+                     "See http://www.broadinstitute.org/igv/LoadData for more details.",
+                     locator.getPath());
+         }
+ 
+         reader = new CachingFeatureReader(new DasReader(), binSize);
+     }
+ 
+     public Iterator<Feature> getFeatures(String chr, int start, int end) throws IOException {
+         return reader.query(chr, start, end);
+     }
+ 
+     public List<LocusScore> getCoverageScores(String chr, int i, int i1, int zoom) {
+         return null;
+     }
+ 
+     public int getBinSize() {
+         return binSize;
+     }
+ 
+     public void setBinSize(int size) {
+         reader.setTileSize(size);
+ 
+     }
+ 
+     public String getPath() {
+         return path;
+     }
+ 
+     public String getType() {
+         return type;
+     }
+ 
+ 
+     class DasReader implements FeatureReader {
+ 
+ 
+         public CloseableTribbleIterator query(String chr, int start, int end, boolean contained) throws IOException {
+             return query(chr, start, end);
+         }
+ 
+         public CloseableTribbleIterator query(String chr, int start, int end) throws IOException {
+ 
+             String dasChr = chr.startsWith("chr") ? chr.substring(3, chr.length()) : chr;
+             int dasStart = start + 1;
+             int dasEnd = end;
+ 
+             if (isValid && !chr.equals("All")) {
+                 WaitCursorManager.CursorToken token = WaitCursorManager.showWaitCursor();
+                 try {
+                     groupFeatureCache.clear();
+                     List<Feature> features = gatherFeatures(dasChr, dasStart, dasEnd);
+                     groupFeatureCache.clear();
+                     if (features.size() < 1) {
+                         return EMPTY__ITERATOR;
+                     }
+                     return new IteratorWrapper(features.iterator());
+                 } finally {
+                     WaitCursorManager.removeWaitCursor(token);
+                 }
+             }
+             return EMPTY__ITERATOR;
+         }
+ 
+         // TODO Iterating not permitted -- throw exception?
+ 
+         public CloseableTribbleIterator iterator() throws IOException {
+             return null;
+         }
+ 
+ 
+         /**
+          * Query for features in the given interval.  The coordinates are translated to DAS conventions.
+          * <p/>
+          * An end value <= 0 will result in a query for features over the whole chromosome.
+          *
+          * @param chr
+          * @param start
+          * @param end
+          * @return
+          */
+         private List<Feature> gatherFeatures(String chr, int start, int end) {
+ 
+             List<Feature> features = new ArrayList<Feature>();
+             try {
+ 
+                 String urlString = serverURL + "?" + "segment=" + chr;
+                 if (end > 0) urlString += ":" + start + "," + end;
+ 
+                 // Add parameters
+                 if (parameters != null) {
+                     for (String param : parameters) {
+                         if (!param.startsWith("segment")) {
+                             urlString += ";" + param;
+                         }
+                     }
+                 }
+ 
+                 URL dataQuery = new URL(urlString);
+                 Document dom = getDocument(dataQuery);
+                 if (dom == null) {
+                     return Collections.emptyList();
+                 }
+                 parseDocument(dom, chr, features);
+                 FeatureUtils.sortFeatureList(features);
+                 return features;
+ 
+             } catch (IOException ioe) {
+                 throw new DataLoadException("Failed to reconnect with server", serverURL);
+             }
+         }
+ 
+ 
+         private Document getDocument(URL query) {
+             InputStream is = null;
+             try {
+                 HttpURLConnection serverConnection = IGVHttpUtils.openConnection(query);
+                 serverConnection.connect();
+                 is = serverConnection.getInputStream();
+                 return createDocument(is);
+             } catch (Exception e) {
+                 isValid = false;
+                 log.error(e);
+                 MessageUtils.showMessage("<html>The DAS Server: " + serverURL + " has returned an error or invalid data." +
+                         "<br>" + e.getMessage());
+                 return null;
+             }
+             finally {
+                 if (is != null) {
+                     try {
+                         is.close();
+                     } catch (IOException e) {
+                         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+                     }
+                 }
+             }
+         }
+ 
+         private Document createDocument(InputStream inputStream)
+                 throws ParserConfigurationException, IOException, SAXException {
+             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+             dbf.setValidating(false);
+             DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
+ 
+             documentBuilder.setEntityResolver(new EntityResolver() {
+                 public InputSource resolveEntity(String publicId, String systemId)
+                         throws SAXException, IOException {
+                     System.out.println("Ignoring " + publicId + ", " + systemId);
+                     return new InputSource(new StringReader(""));
+                 }
+             });
+ 
+             /*BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
+             String nextLine;
+             while((nextLine = br.readLine()) != null) {
+                 System.out.println("** " + nextLine);
+             }
+             */
+ 
+             Document dom = documentBuilder.parse(inputStream);
+             inputStream.close();
+             return dom;
+         }
+ 
+         public String getPath() {
+             return serverURL;
+         }
+ 
+         private void parseDocument(Document dasDoc, String chr, List<Feature> features) {
+ 
+             try {
+                 DocumentTraversal traversal = (DocumentTraversal) dasDoc;
+                 TreeWalker treewalker = traversal.createTreeWalker(
+                         dasDoc.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);
+                 parseTree(treewalker, "FEATURE", chr, features);
+ 
+             } catch (Exception ex) {
+                 log.error(ex);
+                 throw new DataLoadException("Error loading DAS resource (" + ex.toString() + ")", getPath());
+             }
+         }
+ 
+         private List<Feature> parseTree(TreeWalker walker,
+                                         String tag,
+                                         String chr, List<Feature> features) {
+ 
+             Node parent = walker.getCurrentNode();
+             Node n = walker.firstChild();
+             while (n != null) {
+                 if (((Element) n).getTagName().equalsIgnoreCase(tag)) {
+                     Feature f = getFeature(walker, chr);
+                     if (f != null) {
+                         features.add(f);
+                     }
+ 
+                     n = walker.nextSibling();
+ //                if (features.size() > 16384){
+ //                    break;
+ //                }
+                     continue;
+                 }
+                 parseTree(walker, tag, chr, features);
+                 n = walker.nextSibling();
+             }
+             walker.setCurrentNode(parent);
+             return features;
+         }
+ 
+         private BasicFeature getFeature(TreeWalker walker, String chr) {
+ 
+             String id;
+             String label;
+ 
+             String type = "";
+             int start = 0;
+             int end = 0;
+             float score;
+             Strand strand = Strand.NONE;
+ 
+             int phase;
+             String description = null;
+             String link = null;
+             String group = null;
+             String groupLabel = null;
+             String groupLink = null;
+ 
+ 
+             Node featureNode = walker.getCurrentNode();
+ 
+             //GET THE FEATURE ATTRIBUTES
+             NamedNodeMap nnm = featureNode.getAttributes();
+             Node tmpNode = nnm.getNamedItem("id");
+             id = tmpNode.getTextContent();
+             tmpNode = nnm.getNamedItem("label");
+             label = tmpNode == null ? "" : tmpNode.getTextContent();
+ 
+             //GO THROUGH FEATURE NODES
+             for (Node n = walker.firstChild(); n != null;
+                  n = walker.nextSibling()) {
+ 
+                 if (((Element) n).getTagName().equalsIgnoreCase("TYPE")) {
+                     type = n.getTextContent();
+                 } else if (((Element) n).getTagName().equalsIgnoreCase("START")) {
+                     start = Integer.parseInt(n.getTextContent()) - 1;
+                 } else if (((Element) n).getTagName().equalsIgnoreCase("END")) {
+                     end = Math.max(start + 1, Integer.parseInt(n.getTextContent()));
+                 } else if (((Element) n).getTagName().equalsIgnoreCase("SCORE")) {
+                     String scoreString = n.getTextContent();
+                     if (!scoreString.equals("-")) score = Float.parseFloat(scoreString);
+                 } else if (((Element) n).getTagName().equalsIgnoreCase("PHASE")) {
+                     String phaseString = n.getTextContent();
+                     if (!phaseString.equals("-")) phase = Integer.parseInt(n.getTextContent());
+                 } else if (((Element) n).getTagName().equalsIgnoreCase("ORIENTATION")) {
+                     String orientation = n.getTextContent();
+                     if (orientation.equals("-")) {
+                         strand = Strand.NEGATIVE;
+                     } else if (orientation.equalsIgnoreCase("+")) {
+                         strand = Strand.POSITIVE;
+                     }
+                 } else if (((Element) n).getTagName().equalsIgnoreCase("NOTE")) {
+                     if (description == null) {
+                         description = "<html>" + n.getTextContent();
+                     } else {
+                         description += ("<br>" + n.getTextContent());
+                     }
+                 } else if (((Element) n).getTagName().equalsIgnoreCase("GROUP")) {
+                     nnm = n.getAttributes();
+                     tmpNode = nnm.getNamedItem("id");
+                     group = tmpNode.getTextContent();
+ 
+                     tmpNode = nnm.getNamedItem("label");
+                     if (tmpNode != null) {
+                         groupLabel = tmpNode.getTextContent();
+                     }
+ 
+                     NodeList linkNodes = ((Element) n).getElementsByTagName("LINK");
+                     if (linkNodes.getLength() > 0) {
+                         Node ln = linkNodes.item(0);
+                         Node hrefNode = ln.getAttributes().getNamedItem("href");
+                         if (hrefNode != null) {
+                             groupLink = hrefNode.getTextContent();
+                         }
+                     }
+                     // TODO  group Note elements
+ 
+                 } else if (((Element) n).getTagName().equalsIgnoreCase("LINK")) {
+                     NamedNodeMap tmpnnm = n.getAttributes();
+                     Node tmpnode = tmpnnm.getNamedItem("href");
+                     link = tmpnode.getTextContent();
+                 }
+ 
+             }
+ 
+ 
+             walker.setCurrentNode(featureNode);
+ 
+ 
+             BasicFeature feature = null;
+             if (group != null) {
+                 Exon exon = new Exon(chr, start, end, strand);
+ 
+                 feature = groupFeatureCache.get(group);
+                 if (feature == null) {
+                     feature = new BasicFeature(exon.getChr(), exon.getStart(), exon.getEnd(), exon.getStrand());
+                     feature.addExon(exon);
+                     if (groupLink != null) {
+                         feature.setURL(groupLink);
+                     }
+                     if (groupLabel != null) {
+                         feature.setName(groupLabel);
+                     } else {
+                         feature.setName(label);
+                     }
+                     groupFeatureCache.put(group, feature);
+                 } else { // Seen before, just add the exon and exit
+                     feature.addExon(exon);
+                     return null;
+                 }
+ 
+             } else {
+                 feature = new BasicFeature(chr, start, end);
+                 if (link != null) {
+                     feature.setURL(link);
+                 }
+                 feature.setIdentifier(id);
+                 label = label.replace("?", " ");
+                 feature.setName(label);
+                 feature.setType(type);
+                 feature.setStrand(strand);
+             }
+ 
+ 
+             if (description != null) {
+                 description = description.replace("&nbsp;", "<br>");
+                 description = description.replace("<br><br><br>", "<br>");
+                 description = description.replace("<br><br>", "<br>");
+                 description = description.replace(":", ":&nbsp;");
+                 description = description.replace("?", " ");
+                 description = description + "<br>TYPE:&nbsp;" + type;
+                 feature.setDescription(description);
+             }
+ 
+ 
+             return feature;
+         }
+ 
+         public void close() throws IOException {
+             //To change body of implemented methods use File | Settings | File Templates.
+         }
+ 
+         public Set<String> getSequenceNames() {
+             return null;  //To change body of implemented methods use File | Settings | File Templates.
+         }
+     }
+ 
+ 
+     static class IteratorWrapper<Feature> implements CloseableTribbleIterator {
+ 
+         private Iterator<Feature> iterator;
+ 
+         IteratorWrapper(Iterator<Feature> iterator) {
+             this.iterator = iterator;
+         }
+ 
+         public void close() {
+ 
+         }
+ 
+         public Iterator<Feature> iterator() {
+             return iterator;
+         }
+ 
+         public boolean hasNext() {
+             return iterator.hasNext();  //To change body of implemented methods use File | Settings | File Templates.
+         }
+ 
+         public Feature next() {
+             return iterator.next();
+         }
+ 
+         public void remove() {
+             iterator.remove();
+         }
++>>>>>>> upstream/1.5.56
      }
  }
diff --combined src/org/broad/igv/data/AbstractDataSource.java
index 2b39199,d4f70bf..4c4ef66
--- a/src/org/broad/igv/data/AbstractDataSource.java
+++ b/src/org/broad/igv/data/AbstractDataSource.java
@@@ -43,7 -43,7 +43,11 @@@ public abstract class AbstractDataSourc
      // DataManager dataManager;
      boolean cacheSummaryTiles = true;
      WindowFunction windowFunction = WindowFunction.mean;
++<<<<<<< HEAD
 +    LRUCache<String, SummaryTile> summaryTileCache = new LRUCache(20);
++=======
+     LRUCache<String, SummaryTile> summaryTileCache = new LRUCache(this, 10);
++>>>>>>> upstream/1.5.56
  
      // abstract DataManager getDataManager();
  
diff --combined src/org/broad/igv/data/IGVDataset.java
index 760865d,cba01e8..cd01245
--- a/src/org/broad/igv/data/IGVDataset.java
+++ b/src/org/broad/igv/data/IGVDataset.java
@@@ -147,7 -147,8 +147,8 @@@ public class IGVDataset implements Data
      }
  
      public String[] getFeatureNames(String chr) {
-         return null;
+         ChromosomeData cd = getChromosomeData(chr);
+         return cd == null ? null : cd.getProbes();
      }
  
      public int getWindowSpan() {
@@@ -219,7 -220,6 +220,10 @@@
      }
  
  
++<<<<<<< HEAD
 +
++=======
++>>>>>>> upstream/1.5.56
      public Integer getLongestFeature(String chr) {
          return longestFeatureMap == null ? 1000 :
                  longestFeatureMap.containsKey(chr) ? longestFeatureMap.get(chr) : 1;
diff --combined src/org/broad/igv/data/IGVDatasetParser.java
index d6663c9,5a0f146..56bb770
--- a/src/org/broad/igv/data/IGVDatasetParser.java
+++ b/src/org/broad/igv/data/IGVDatasetParser.java
@@@ -59,6 -59,7 +59,7 @@@ public class IGVDatasetParser 
      private int startColumn;
      private int endColumn;
      private int firstDataColumn;
+     private int probeColumn;
      private boolean hasEndLocations;
      private boolean hasCalls;
      private Genome genome;
@@@ -87,10 -88,12 +88,12 @@@
              chrColumn = 0;
              startColumn = 1;
              endColumn = 2;
+             probeColumn = 3;
              firstDataColumn = 4;
              hasEndLocations = true;
              hasCalls = false;
          } else if (tmp.endsWith(".xcn") || tmp.endsWith("cn") || tmp.endsWith(".snp") || tmp.endsWith(".loh")) {
+             probeColumn = 0;
              chrColumn = 1;
              startColumn = 2;
              endColumn = -1;
@@@ -349,7 -352,9 +352,9 @@@
      private float readFloat(String token) {
          float copyNo = Float.NaN;
          try {
-             copyNo = Float.parseFloat(token);
+             if (token != null) {
+                 copyNo = Float.parseFloat(token);
+             }
  
          } catch (NumberFormatException e) {
          }
@@@ -381,6 -386,7 +386,7 @@@
              // Create containers to hold data
              IntArrayList startLocations = new IntArrayList(nRowsEst);
              IntArrayList endLocations = (hasEndLocations ? new IntArrayList(nRowsEst) : null);
+             List<String> probes = new ArrayList(nRowsEst);
  
              Map<String, FloatArrayList> dataMap = new HashMap();
              for (String h : columnHeaders) {
@@@ -402,6 -408,10 +408,10 @@@
  
                          // chromosomeData.setMarkerId(nRows, tokens[0]);
  
+                         // The probe.  A new string is created to prevent holding on to the entire row through a substring reference
+                         String probe = new String(tokens[probeColumn]);
+                         probes.add(probe);
+ 
                          int start = Integer.parseInt(tokens[startColumn].trim());
                          if (hasEndLocations) {
                              endLocations.add(Integer.parseInt(tokens[endColumn].trim()));
@@@ -432,6 -442,7 +442,7 @@@
  
              // Loop complete
              ChromosomeData cd = new ChromosomeData(chrSummary.getName());
+             cd.setProbes(probes.toArray(new String[]{}));
              cd.setStartLocations(startLocations.toArray());
              if (hasEndLocations) {
                  cd.setEndLocations(endLocations.toArray());
@@@ -486,7 -497,7 +497,7 @@@
  
      private boolean isCopyNumberFileExt(String filename) {
          String tmp = (filename.endsWith(".txt") || filename.endsWith(".tab") || filename.endsWith(".xls")
-                 ? filename.substring(0, filename.length() - 4) : filename);
+                 ? filename.substring(0, filename.length() - 4).toLowerCase() : filename).toLowerCase();
          return tmp.endsWith(".cn") || tmp.endsWith(".xcn") || tmp.endsWith(".snp");
      }
  
@@@ -558,8 -569,8 +569,13 @@@
      private void updateWholeGenome(String currentChromosome, IGVDataset dataset, String[] headings,
                                     IGVDatasetParser.WholeGenomeData wgData) {
  
++<<<<<<< HEAD
 +        
 +        if(!genome.getHomeChromosome().equals(Globals.CHR_ALL)) {
++=======
+ 
+         if (!genome.getHomeChromosome().equals(Globals.CHR_ALL)) {
++>>>>>>> upstream/1.5.56
              return;
          }
  
diff --combined src/org/broad/igv/data/seg/SegmentedDataWriter.java
index 6c415af,65f63c5..7b3b687
--- a/src/org/broad/igv/data/seg/SegmentedDataWriter.java
+++ b/src/org/broad/igv/data/seg/SegmentedDataWriter.java
@@@ -199,12 -199,10 +199,14 @@@ public class SegmentedDataWriter 
              }
          }
  
-         System.out.println("Track type=" + trackType.toString());
          //inputFile = "/Users/jrobinso/IGVTestData/Demo/TCGA/broad.seg";
          //outputFile = "test.seg.zip";
  
          // TODO -- remove the need for this hack
++<<<<<<< HEAD:src/org/broad/igv/data/seg/SegmentedDataWriter.java
 +        System.out.println("Setting genome: " + genomeId);
++=======
++>>>>>>> upstream/1.5.56:src/org/broad/igv/data/seg/SegmentedDataWriter.java
          ViewContext.getInstance().setGenomeId(genomeId);
  
          SegmentedAsciiDataSet ds = new SegmentedAsciiDataSet(new ResourceLocator(inputFile));
diff --combined src/org/broad/igv/exceptions/DataLoadException.java
index 4ad25d1,9bfe8cb..1ea92e5
--- a/src/org/broad/igv/exceptions/DataLoadException.java
+++ b/src/org/broad/igv/exceptions/DataLoadException.java
@@@ -19,23 -19,20 +19,24 @@@
  package org.broad.igv.exceptions;
  
  /**
-  * Created by IntelliJ IDEA.
-  * User: nazaire
+  * Author: nazaire
   * Date: Jul 8, 2009
   */
  public class DataLoadException extends RuntimeException {
+ 
+     String message;
      private String fileName;
  
      public DataLoadException(String message, String fileName) {
-         super(message);
+         if(message != null) this.message = message.replace("<html>", "");
          this.fileName = fileName;
      }
  
-     public String getFileName() {
-         return fileName;
-     }
- 
      public String getMessage() {
++<<<<<<< HEAD
 +        return "An error occurred while loading:    " + fileName + "\n[" + super.getMessage() + "]";
++=======
+         return "<html>An error occurred while loading:    " + fileName + "<br>" + message;
++>>>>>>> upstream/1.5.56
      }
  }
diff --combined src/org/broad/igv/feature/Exon.java
index 9ba0d46,e1e7e80..abbb554
--- a/src/org/broad/igv/feature/Exon.java
+++ b/src/org/broad/igv/feature/Exon.java
@@@ -78,14 -78,6 +78,6 @@@ public class Exon extends AbstractFeatu
          }
      }
  
-     /**
-      * Constructs ...
-      *
-      * @param chr
-      * @param start
-      * @param end
-      * @param strand
-      */
      public Exon(String chr, int start, int end, Strand strand) {
          super(chr, start, end, strand);
  
@@@ -240,6 -232,7 +232,7 @@@
          if (aaNumber > 0) {
              msg += "<br>Amino acid number: " + aaNumber;
          }
+         if (description != null) msg +=  description;
          return msg;
      }
  
@@@ -254,4 -247,8 +247,11 @@@
      public String getURL() {
          return null;  //To change body of implemented methods use File | Settings | File Templates.
      }
++<<<<<<< HEAD
++=======
+ 
+     public boolean isUTR() {
+         return utr;
+     }
++>>>>>>> upstream/1.5.56
  }
diff --combined src/org/broad/igv/feature/GFFParser.java
index 189ba90,75c8a99..7c49073
--- a/src/org/broad/igv/feature/GFFParser.java
+++ b/src/org/broad/igv/feature/GFFParser.java
@@@ -47,6 -47,7 +47,10 @@@ public class GFFParser implements Featu
      static Logger log = Logger.getLogger(GFFParser.class);
  
      static HashSet exonTerms = new HashSet();
++<<<<<<< HEAD
++=======
+     static HashSet utrTerms = new HashSet();
++>>>>>>> upstream/1.5.56
      //static Set<String> ignoreAttributes = new HashSet();
      static HashSet<String> geneParts = new HashSet();
      static HashSet<String> ignoredTypes = new HashSet();
@@@ -57,19 -58,22 +61,22 @@@
      static String[] tokens = new String[200];
  
      static {
-         exonTerms.add("five_prime_UTR");
-         exonTerms.add("three_prime_UTR");
-         exonTerms.add("5'-utr");
-         exonTerms.add("3'-utr");
-         exonTerms.add("3'-UTR");
-         exonTerms.add("5'-UTR");
-         exonTerms.add("5utr");
-         exonTerms.add("3utr");
+         utrTerms.add("five_prime_UTR");
+         utrTerms.add("three_prime_UTR");
+         utrTerms.add("5'-utr");
+         utrTerms.add("3'-utr");
+         utrTerms.add("3'-UTR");
+         utrTerms.add("5'-UTR");
+         utrTerms.add("5utr");
+         utrTerms.add("3utr");
+     }
+ 
+     static {
+         exonTerms.addAll(utrTerms);
          exonTerms.add("exon");
          exonTerms.add("coding_exon");
          exonTerms.add("CDS");
          exonTerms.add("cds");
- 
      }
  
  
@@@ -274,14 -278,15 +281,15 @@@
                      for (String pid : parentIds) {
                          getGFF3Transcript(pid).addCDSParts(chromosome, start, end, description);
                      }
-                 } else if (exonTerms.contains(featureType) && parentIds != null && parentIds.length > 0) {
+                 } else if (exonTerms.contains(featureType) && parentIds != null && parentIds.length > 0 &&
+                         parentIds[0] != null && parentIds[0].length() > 0 && !parentIds[0].equals(".")) {
  
-                     Exon exon = new Exon(chromosome, start, end, strand);
-                     exon.setDescription(description);
+                     String name = getName(attributes);
+                     int phase = -1;
                      String phaseString = tokens[7].trim();
                      if (!phaseString.equals(".")) {
                          try {
-                             exon.setPhase(Integer.parseInt(phaseString));
+                             phase = Integer.parseInt(phaseString);
  
                          } catch (NumberFormatException numberFormatException) {
  
@@@ -290,10 -295,19 +298,19 @@@
                          }
                      }
  
-                     exon.setName(getName(attributes));
+                     // Make a copy of the exon record for each parent
+                     for (String pid : parentIds) {
  
+                         Exon exon = new Exon(chromosome, start, end, strand);
+                         exon.setDescription(description);
+                         exon.setUTR(utrTerms.contains(featureType));
+ 
+                         if (phase >= 0) {
+                             exon.setPhase(phase);
+ 
+                         }
+                         exon.setName(name);
  
-                     for (String pid : parentIds) {
                          if (featureType.equals("exon")) {
                              getGFF3Transcript(pid).addExon(exon);
                          } else if (featureType.equals("CDS")) {
@@@ -683,7 -697,7 +700,7 @@@
  
      class GFF2Helper implements Helper {
  
-         String[] idFields = {"systematic_id", "ID", "Name", "name", "primary_name", "gene", "Locus", "locus", "alias"};
+         String[] idFields = {"systematic_id", "ID", "transcript_id", "Name", "name", "primary_name", "gene", "Locus", "locus", "alias"};
  
  
          public void setUrlDecoding(boolean b) {
diff --combined src/org/broad/igv/feature/GeneManager.java
index c7256c1,8a7e704..929253d
--- a/src/org/broad/igv/feature/GeneManager.java
+++ b/src/org/broad/igv/feature/GeneManager.java
@@@ -57,13 -57,9 +57,11 @@@ public class GeneManager 
       * Map of chromosome -> longest gene
       */
      Map<String, Feature> longestGeneMap;
-     /**
-      * Set of loaded gene variants.  Used to prevent loading of duplicates.
-      */
-     Set<String> loadedGeneKeys;
+ 
+     private TrackProperties trackProperties;
  
 +    private TrackProperties trackProperties;
 +
      public GeneManager(String genomeId) {
          this(genomeId, "Gene");
      }
@@@ -82,7 -78,6 +80,6 @@@
          geneMap = new HashMap<String, Feature>();
          maxLocationMap = new HashMap<String, Integer>();
          longestGeneMap = new HashMap<String, Feature>();
-         loadedGeneKeys = new HashSet();
          this.geneTrackName = geneTrackName;
      }
  
@@@ -97,63 -92,57 +94,81 @@@
       */
      public void addGene(Feature gene) {
  
-         String key = gene.getIdentifier();
- 
-         if (!loadedGeneKeys.contains(key)) {
-             loadedGeneKeys.add(key);
+         // If there is a genome associated with this manager only include
+         // genes whose chromosome is contained in the genome.
  
++<<<<<<< HEAD
 +            // If there is a genome associated with this manager only include
 +            // genes whose chromosome is contained in the genome.
 +
 +            if (genome != null) {
 +                if (genome.getChromosome(gene.getChr()) == null) {
 +                    return;
 +                }
++=======
+         if (genome != null) {
+             if (genome.getChromosome(gene.getChr()) == null) {
+                 return;
++>>>>>>> upstream/1.5.56
              }
+         }
  
-             // If there are multiple variant of a gene, use the longest
-             Feature currentGene = geneMap.get(gene.getName());
-             if (gene.getIdentifier() != null) {
-                 geneMap.put(gene.getIdentifier().trim().toUpperCase(), gene);
+         // If there are multiple variant of a gene, use the longest
+         Feature currentGene = geneMap.get(gene.getName());
+         if (gene.getIdentifier() != null) {
+             geneMap.put(gene.getIdentifier().trim().toUpperCase(), gene);
+         }
+         if (currentGene == null) {
+             if (gene.getName() != null) {
+                 geneMap.put(gene.getName().trim().toUpperCase(), gene);
              }
-             if (currentGene == null) {
+         } else {
+             int w1 = currentGene.getEnd() - currentGene.getStart();
+             int w2 = gene.getEnd() - gene.getStart();
+             if (w2 > w1) {
                  if (gene.getName() != null) {
                      geneMap.put(gene.getName().trim().toUpperCase(), gene);
                  }
-             } else {
-                 int w1 = currentGene.getEnd() - currentGene.getStart();
-                 int w2 = gene.getEnd() - gene.getStart();
-                 if (w2 > w1) {
-                     if (gene.getName() != null) {
-                         geneMap.put(gene.getName().trim().toUpperCase(), gene);
-                     }
-                 }
              }
+         }
  
  
++<<<<<<< HEAD
 +            // Update "longest gene" for this chromosome
 +            String chr = gene.getChr();
 +            List<Feature> geneDataList = chromosomeGeneMap.get(chr);
 +            if (geneDataList == null) {
 +                geneDataList = new ArrayList<Feature>();
 +                chromosomeGeneMap.put(chr, geneDataList);
 +                maxLocationMap.put(chr, (int) gene.getEnd());
 +            }
 +            if (gene.getEnd() > maxLocationMap.get(chr)) {
 +                maxLocationMap.put(chr, (int) gene.getEnd());
 +            }
++=======
+         // Update "longest gene" for this chromosome
+         String chr = gene.getChr();
+         List<Feature> geneDataList = chromosomeGeneMap.get(chr);
+         if (geneDataList == null) {
+             geneDataList = new ArrayList<Feature>();
+             chromosomeGeneMap.put(chr, geneDataList);
+             maxLocationMap.put(chr, (int) gene.getEnd());
+         }
+         if (gene.getEnd() > maxLocationMap.get(chr)) {
+             maxLocationMap.put(chr, (int) gene.getEnd());
+         }
++>>>>>>> upstream/1.5.56
  
-             if (longestGeneMap.get(chr) == null) {
+         if (longestGeneMap.get(chr) == null) {
+             longestGeneMap.put(chr, gene);
+         } else {
+             if (gene.getLength() > longestGeneMap.get(chr).getLength()) {
                  longestGeneMap.put(chr, gene);
-             } else {
-                 if (gene.getLength() > longestGeneMap.get(chr).getLength()) {
-                     longestGeneMap.put(chr, gene);
-                 }
              }
- 
-             geneDataList.add((Feature) gene);
          }
  
+         geneDataList.add(gene);
+ 
      }
  
      /**
@@@ -275,8 -264,8 +290,13 @@@
                          String geneFilename = genomeDescriptor.getGeneFileName();
                          FeatureParser parser = AbstractFeatureParser.getInstanceFor(new ResourceLocator(geneFilename));
                          if (parser == null) {
++<<<<<<< HEAD
 +                           MessageUtils.showMessage("ERROR: Unrecognized annotation file format: " + geneFilename + 
 +                           "<br>Annotations for genome: " + genomeId + " will not be loaded.");
++=======
+                             MessageUtils.showMessage("ERROR: Unrecognized annotation file format: " + geneFilename +
+                                     "<br>Annotations for genome: " + genomeId + " will not be loaded.");
++>>>>>>> upstream/1.5.56
                          } else {
                              List<Feature> genes = parser.loadFeatures(reader);
                              for (Feature gene : genes) {
diff --combined src/org/broad/igv/feature/Genome.java
index c2b5a2d,355c59b..d145518
--- a/src/org/broad/igv/feature/Genome.java
+++ b/src/org/broad/igv/feature/Genome.java
@@@ -46,6 -46,7 +46,10 @@@ public class Genome 
      private long length = -1;
      private String annotationURL;
      private Map<String, Long> cumulativeOffsets = new HashMap();
++<<<<<<< HEAD
++=======
+     public static final int MAX_WHOLE_GENOME = 10000;
++>>>>>>> upstream/1.5.56
  
  
      public Genome(String id) {
@@@ -78,33 -79,25 +82,55 @@@
          chrAliasTable = GenomeManager.getInstance().getChromosomeAliasTable(id);
  
          if (chrAliasTable == null) {
++<<<<<<< HEAD
 +
 +            chrAliasTable = new HashMap(100);
 +            if (id.startsWith("hg") || id.equalsIgnoreCase("1kg_ref")) {
 +
 +                for (int i = 0; i < 23; i++) {
 +                    chrAliasTable.put(String.valueOf(i), "chr" + i);
 +                    //chrLookupTable.put("Chr" + i, "chr" + i);
 +                }
 +                chrAliasTable.put("23", "chrX");
 +                chrAliasTable.put("24", "chrY");
 +                chrAliasTable.put("X", "chrX");
 +                chrAliasTable.put("Y", "chrY");
 +                chrAliasTable.put("M", "chrM");
 +                chrAliasTable.put("MT", "chrM");
 +            } else if (id.startsWith("mm")) {
 +
 +                for (int i = 0; i < 21; i++) {
 +                    chrAliasTable.put(String.valueOf(i), "chr" + i);
 +                    //chrLookupTable.put("Chr" + i, "chr" + i);
 +                }
 +                chrAliasTable.put("21", "chrX");
 +                chrAliasTable.put("22", "chrY");
 +                chrAliasTable.put("X", "chrX");
 +                chrAliasTable.put("Y", "chrY");
 +                chrAliasTable.put("M", "chrM");
 +                chrAliasTable.put("MT", "chrM");
 +            }
++=======
+             chrAliasTable = new HashMap(100);
+         }
+         if (id.startsWith("hg") || id.equalsIgnoreCase("1kg_ref")) {
+             chrAliasTable.put("23", "chrX");
+             chrAliasTable.put("24", "chrY");
+             chrAliasTable.put("chr23", "chrX");
+             chrAliasTable.put("chr24", "chrY");
+             chrAliasTable.put("MT", "chrM");
+         } else if (id.startsWith("mm")) {
+             chrAliasTable.put("21", "chrX");
+             chrAliasTable.put("22", "chrY");
+             chrAliasTable.put("chr21", "chrX");
+             chrAliasTable.put("chr22", "chrY");
+             chrAliasTable.put("MT", "chrM");
+         } else if (id.equals("b37")) {
+             chrAliasTable.put("chrM", "MT");
+             chrAliasTable.put("chrX", "23");
+             chrAliasTable.put("chrY", "24");
+ 
++>>>>>>> upstream/1.5.56
          }
      }
  
@@@ -112,19 -105,12 +138,26 @@@
      public String getChromosomeAlias(String str) {
          if (chrAliasTable == null) {
              return str;
++<<<<<<< HEAD
 +        }
 +
 +        String chr = chrAliasTable.get(str);
 +        if (chr == null) {
 +            if (ucscGenomes.contains(id) && !str.startsWith("chr")) {
 +                chr = "chr" + str;
 +            } else {
 +                chr = str;
 +            }
 +
 +            chrAliasTable.put(str, chr);
++=======
+         } else {
+             if (chrAliasTable.containsKey(str)) {
+                 return chrAliasTable.get(str);
+             }
++>>>>>>> upstream/1.5.56
          }
-         return chr;
+         return str;
      }
  
  
@@@ -134,11 -120,24 +167,28 @@@
          if (!chromosomesAreOrdered) {
              Collections.sort(chromosomeNames, new ChromosomeComparator());
          }
+         // Update the chromosome alias table with common variations -- don't do for genomes with large #s of scallfolds
+         if (chromosomeNames.size() < 1000) {
+             if (chrAliasTable == null) {
+                 chrAliasTable = new HashMap();
+             }
+             for (String name : chromosomeNames) {
+                 if (name.startsWith("chr") || name.startsWith("Chr")) {
+                     chrAliasTable.put(name.substring(3), name);
+                 } else {
+                     chrAliasTable.put("chr" + name, name);
+                 }
+             }
+         }
      }
  
  
      public String getHomeChromosome() {
++<<<<<<< HEAD
 +        if (getChromosomeNames().size() == 1 || chromosomeNames.size() > 500) {
++=======
+         if (getChromosomeNames().size() == 1 || chromosomeNames.size() > MAX_WHOLE_GENOME) {
++>>>>>>> upstream/1.5.56
              return getChromosomeNames().get(0);
          } else {
              return Globals.CHR_ALL;
@@@ -209,7 -208,7 +259,11 @@@
          for (String c : chromosomeNames) {
              int chrLen = getChromosome(c).getLength();
              if ((cumOffset + chrLen) / 1000 > genomeKBP) {
++<<<<<<< HEAD
 +                int bp = (int) (genomeKBP*1000 - cumOffset);
++=======
+                 int bp = (int) (genomeKBP * 1000 - cumOffset);
++>>>>>>> upstream/1.5.56
                  return new ChromosomeCoordinate(c, bp);
              }
              cumOffset += chrLen;
diff --combined src/org/broad/igv/feature/GenomeImporter.java
index 23c71e7,d2f3f3d..0c0e4aa
--- a/src/org/broad/igv/feature/GenomeImporter.java
+++ b/src/org/broad/igv/feature/GenomeImporter.java
@@@ -25,8 -25,7 +25,12 @@@ package org.broad.igv.feature
  import org.apache.log4j.Logger;
  import org.broad.igv.Globals;
  
++<<<<<<< HEAD
 +import static org.broad.igv.ui.UIConstants.IGV_TEMP_DIRECTORY;
 +
++=======
+ import org.broad.igv.ui.UIConstants;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.ui.util.ProgressMonitor;
  import org.broad.igv.util.AsciiLineReader;
  import org.broad.igv.util.FileUtils;
@@@ -162,6 -161,7 +166,7 @@@ public class GenomeImporter 
  
                  // Create Cytoband file
                  if (autoGeneratedCytobandFile) {
+                     File IGV_TEMP_DIRECTORY = UIConstants.getTmpDirectory();
                      // Construct a cytoband file
                      String cytobandFileName = genomeId + "_cytoband.txt";
                      cytobandFile = new File(IGV_TEMP_DIRECTORY, cytobandFileName);
@@@ -263,7 -263,7 +268,7 @@@
  
          PrintWriter propertyFileWriter = null;
          try {
- 
+             File IGV_TEMP_DIRECTORY = UIConstants.getTmpDirectory();
              File propertyFile = new File(IGV_TEMP_DIRECTORY, "property.txt");
              propertyFile.createNewFile();
  
diff --combined src/org/broad/igv/feature/GenomeManager.java
index 156726a,3d6aaaa..276ca4b
--- a/src/org/broad/igv/feature/GenomeManager.java
+++ b/src/org/broad/igv/feature/GenomeManager.java
@@@ -30,7 -30,6 +30,10 @@@ import org.broad.igv.Globals
  import org.broad.igv.PreferenceManager;
  import org.broad.igv.ui.UIConstants;
  
++<<<<<<< HEAD
 +import static org.broad.igv.ui.UIConstants.GENOME_CACHE_DIRECTORY;
++=======
++>>>>>>> upstream/1.5.56
  
  import org.broad.igv.ui.util.ConfirmDialog;
  import org.broad.igv.ui.util.MessageUtils;
@@@ -67,14 -66,12 +70,12 @@@ public class GenomeManager 
  
      final public static String ALIAS_URL = "http://www.broadinstitute.org/igvdata/genomes/alias.txt";
      final public static String USER_DEFINED_GENOME_LIST_FILE = "user-defined-genomes.txt";
-     final public static String GENOME_ID_KEY = "id";
-     final public static String GENOME_NAME_KEY = "name";
-     final public static String GENOME_CYTOBAND_FILE_KEY = "cytobandFile";
-     final public static String GENOME_GENE_FILE_KEY = "geneFile";
-     final public static String GENOME_SEQUENCE_URL_KEY = "sequenceURL";
  
-     final public static String DEFAULT_GENOME_ID = "hg18";
-     private static GenomeDescriptor DEFAULT;
+     private static GenomeDescriptor DEFAULT_GENOME;
+     File GENOME_CACHE_DIRECTORY;
+     private LinkedHashSet<GenomeListItem> userDefinedGenomeArchiveList;
+     private LinkedHashSet<GenomeListItem> cachedGenomeArchiveList;
+     private LinkedHashSet<GenomeListItem> serverGenomeArchiveList;
  
  
      /**
@@@ -83,6 -80,7 +84,7 @@@
      private GenomeManager() {
          genomeDescriptorMap = new HashMap();
          genomes = new Hashtable();
+         GENOME_CACHE_DIRECTORY = UIConstants.getGenomeCacheDirectory();
      }
  
      /**
@@@ -117,6 -115,7 +119,10 @@@
                  return null;
              } else {
                  genome = loadGenome(genomeDescriptor);
++<<<<<<< HEAD
++=======
+                 log.info("Genome loaded");
++>>>>>>> upstream/1.5.56
                  genomes.put(id, genome);
  
              }
@@@ -206,8 -205,7 +212,7 @@@
  
      /**
       * Locates a genome in the set of known genome archive locations -
-      * then loads it. This method is used ONLY for command line loading
-      * of genomes.
+      * then loads it.
       *
       * @param genome The genome to load.
       */
@@@ -218,7 -216,7 +223,7 @@@
          }
  
  
-         LinkedHashSet<GenomeListItem> genomes = getAllGenomeArchives(null);
+         LinkedHashSet<GenomeListItem> genomes = getAllGenomeArchives();
          for (GenomeListItem item : genomes) {
              if (item.getId().equalsIgnoreCase(genome)) {
                  String url = item.getLocation();
@@@ -580,156 -578,166 +585,221 @@@
      public LinkedHashSet<GenomeListItem> getServerGenomeArchiveList(Set excludedArchivesUrls)
              throws IOException {
  
++<<<<<<< HEAD
 +        if (serverGenomeListUnreachable) {
 +            return null;
 +        }
 +
 +        LinkedHashSet<GenomeListItem> genomeItemList = new LinkedHashSet();
 +        BufferedReader dataReader = null;
 +        InputStream inputStream = null;
 +        HttpURLConnection conn = null;
 +        try {
 +            String genomeListURL = PreferenceManager.getInstance().getGenomeListURL();
 +            URL serverGenomeArchiveList = new URL(genomeListURL);
 +
 +            if (genomeListURL.startsWith("ftp:")) {
 +                MessageUtils.showMessage("FTP protocol not supported for genome URL");
 +
 +            } else if (genomeListURL.startsWith("http:") || genomeListURL.startsWith("https:")) {
 +                conn = IGVHttpUtils.openConnection(serverGenomeArchiveList);
 +                conn.setReadTimeout(10000);
 +                conn.setConnectTimeout(10000);
 +                inputStream = IGVHttpUtils.openConnectionStream(serverGenomeArchiveList);
 +                inputStream = IGVHttpUtils.openHttpStream(serverGenomeArchiveList, conn);
 +            } else {
 +                File file = new File(genomeListURL.startsWith("file:") ? serverGenomeArchiveList.getFile() : genomeListURL);
 +                inputStream = new FileInputStream(file);
 +            }
++=======
+         if (serverGenomeArchiveList == null) {
+             if (serverGenomeListUnreachable) {
+                 return null;
+             }
+ 
+             serverGenomeArchiveList = new LinkedHashSet();
+             BufferedReader dataReader = null;
+             InputStream inputStream = null;
+             HttpURLConnection conn = null;
+             try {
+                 String genomeListURLString = PreferenceManager.getInstance().getGenomeListURL();
+                 URL serverGenomeURL = new URL(genomeListURLString);
+ 
+                 if (genomeListURLString.startsWith("ftp:")) {
+                     MessageUtils.showMessage("FTP protocol not supported for genome URL");
+ 
+                 } else if (genomeListURLString.startsWith("http:") || genomeListURLString.startsWith("https:")) {
+                     conn = IGVHttpUtils.openConnection(serverGenomeURL);
+                     conn.setReadTimeout(10000);
+                     conn.setConnectTimeout(10000);
+                     inputStream = IGVHttpUtils.openConnectionStream(serverGenomeURL);
+                     inputStream = IGVHttpUtils.openHttpStream(serverGenomeURL, conn);
+                 } else {
+                     File file = new File(genomeListURLString.startsWith("file:") ? serverGenomeURL.getFile() : genomeListURLString);
+                     inputStream = new FileInputStream(file);
+                 }
++>>>>>>> upstream/1.5.56
  
  
-             dataReader = new BufferedReader(new InputStreamReader(inputStream));
+                 dataReader = new BufferedReader(new InputStreamReader(inputStream));
  
-             boolean wasHeaderRead = false;
-             String genomeRecord;
-             while ((genomeRecord = dataReader.readLine()) != null) {
+                 boolean wasHeaderRead = false;
+                 String genomeRecord;
+                 while ((genomeRecord = dataReader.readLine()) != null) {
  
++<<<<<<< HEAD
 +                if (genomeRecord.startsWith("<") || genomeRecord.startsWith("(#")) {
 +                    continue;
 +                }
++=======
+                     if (genomeRecord.startsWith("<") || genomeRecord.startsWith("(#")) {
+                         continue;
+                     }
++>>>>>>> upstream/1.5.56
  
-                 if (genomeRecord != null) {
-                     genomeRecord = genomeRecord.trim();
+                     if (genomeRecord != null) {
+                         genomeRecord = genomeRecord.trim();
  
-                     String[] fields = genomeRecord.split("\t");
+                         String[] fields = genomeRecord.split("\t");
  
-                     if ((fields != null) && (fields.length >= 3)) {
+                         if ((fields != null) && (fields.length >= 3)) {
  
-                         // Throw away records we don't want to see
-                         if (excludedArchivesUrls != null) {
-                             if (excludedArchivesUrls.contains(fields[1])) {
-                                 continue;
+                             // Throw away records we don't want to see
+                             if (excludedArchivesUrls != null) {
+                                 if (excludedArchivesUrls.contains(fields[1])) {
+                                     continue;
+                                 }
                              }
-                         }
-                         int version = 0;
-                         if (fields.length > 3) {
-                             try {
-                                 version = Integer.parseInt(fields[3]);
-                             } catch (Exception e) {
-                                 log.error("Error parsing genome version: " + fields[0], e);
+                             int version = 0;
+                             if (fields.length > 3) {
+                                 try {
+                                     version = Integer.parseInt(fields[3]);
+                                 } catch (Exception e) {
+                                     log.error("Error parsing genome version: " + fields[0], e);
+                                 }
                              }
-                         }
  
-                         try {
-                             GenomeListItem item = new GenomeListItem(fields[0], fields[1], fields[2], version, false);
-                             genomeItemList.add(item);
-                         } catch (Exception e) {
-                             log.error(
-                                     "Error reading a line from server genome list" + " line was: [" + genomeRecord + "]",
-                                     e);
+                             //String displayableName, String url, String id, int version, boolean isUserDefined
+                             String name = fields[0];
+                             String url = fields[1];
+                             String id = fields[2];
+ 
+                             boolean valid = true;
+                             if (url.length() == 0) {
+                                 log.error("Genome entry : " + name + " has an empty URL string.  Check for extra tabs in the definition file: " +
+                                         PreferenceManager.getInstance().getGenomeListURL());
+                                 valid = false;
+                             }
+                             // TODO -- more validation
+ 
+ 
+                             if (valid) {
+                                 try {
+                                     GenomeListItem item = new GenomeListItem(fields[0], fields[1], fields[2], version, false);
+                                     serverGenomeArchiveList.add(item);
+                                 } catch (Exception e) {
+                                     log.error(
+                                             "Error reading a line from server genome list" + " line was: [" + genomeRecord + "]",
+                                             e);
+                                 }
+                             }
+                         } else {
+                             log.error("Found invalid server genome list record: " + genomeRecord);
                          }
-                     } else {
-                         log.error("Found invalid server genome list record: " + genomeRecord);
                      }
                  }
++<<<<<<< HEAD
 +            }
 +        } catch (Exception e) {
 +            serverGenomeListUnreachable = true;
 +            log.error("Error fetching genome list: ", e);
 +            ConfirmDialog.optionallyShowInfoDialog("Warning: There was an error connecting to the genome server (" +
 +                    e.toString() + ").    Only locally defined genomes will be available.",
 +                    PreferenceManager.SHOW_GENOME_SERVER_WARNING);
 +        } finally {
 +            if (dataReader != null) {
 +                dataReader.close();
 +            }
 +            if (inputStream != null) {
 +                inputStream.close();
++=======
+             } catch (Exception e) {
+                 serverGenomeListUnreachable = true;
+                 log.error("Error fetching genome list: ", e);
+                 ConfirmDialog.optionallyShowInfoDialog("Warning: There was an error connecting to the genome server (" +
+                         e.toString() + ").    Only locally defined genomes will be available.",
+                         PreferenceManager.SHOW_GENOME_SERVER_WARNING);
+             } finally {
+                 if (dataReader != null) {
+                     dataReader.close();
+                 }
+                 if (inputStream != null) {
+                     inputStream.close();
+                 }
++>>>>>>> upstream/1.5.56
              }
          }
-         return genomeItemList;
+         return serverGenomeArchiveList;
      }
  
      /**
       * Gets a list of all the user-defined genome archive files that
       * IGV knows about.
       *
-      * @param excludedArchivesUrls The set of file location to exclude in the
-      *                             return list.
       * @return LinkedHashSet<GenomeListItem>
       * @throws IOException
       * @see GenomeListItem
       */
-     public LinkedHashSet<GenomeListItem> getUserDefinedGenomeArchiveList(Set excludedArchivesUrls)
+     public LinkedHashSet<GenomeListItem> getUserDefinedGenomeArchiveList()
              throws IOException {
  
-         boolean clientGenomeListNeedsRebuilding = false;
-         LinkedHashSet<GenomeListItem> genomeItemList = new LinkedHashSet();
+         if (userDefinedGenomeArchiveList == null) {
  
-         File listFile = new File(GENOME_CACHE_DIRECTORY, USER_DEFINED_GENOME_LIST_FILE);
+             userDefinedGenomeArchiveList = new LinkedHashSet();
  
-         Properties listProperties = retrieveUserDefinedGenomeListFromFile(listFile);
+             File listFile = new File(GENOME_CACHE_DIRECTORY, USER_DEFINED_GENOME_LIST_FILE);
+             boolean clientGenomeListNeedsRebuilding = false;
+             Properties listProperties = retrieveUserDefinedGenomeListFromFile(listFile);
  
-         if (listProperties != null) {
+             if (listProperties != null) {
  
-             Collection records = listProperties.values();
+                 Collection records = listProperties.values();
  
-             for (Object value : records) {
+                 for (Object value : records) {
  
-                 String record = (String) value;
-                 if (record.trim().equals("")) {
-                     continue;
-                 }
+                     String record = (String) value;
+                     if (record.trim().equals("")) {
+                         continue;
+                     }
  
-                 String[] fields = record.split("\t");
+                     String[] fields = record.split("\t");
  
-                 // Throw away records we don't want to see
-                 if (excludedArchivesUrls != null) {
-                     if (excludedArchivesUrls.contains(fields[1])) {
+                     File file = new File(fields[1]);
+                     if (file.isDirectory()) {
+                         continue;
+                     }
+                     if (!file.exists()) {
+                         clientGenomeListNeedsRebuilding = true;
                          continue;
                      }
-                 }
- 
-                 File file = new File(fields[1]);
-                 if (file.isDirectory()) {
-                     continue;
-                 }
-                 if (!file.exists()) {
-                     clientGenomeListNeedsRebuilding = true;
-                     continue;
-                 }
  
++<<<<<<< HEAD
 +                if (!file.getName().toLowerCase().endsWith(Globals.GENOME_FILE_EXTENSION)) {
 +                    continue;
++=======
+                     if (!file.getName().toLowerCase().endsWith(Globals.GENOME_FILE_EXTENSION)) {
+                         continue;
+                     }
+                     GenomeListItem item = new GenomeListItem(fields[0], file.getAbsolutePath(), fields[2], 0, true);
+                     userDefinedGenomeArchiveList.add(item);
++>>>>>>> upstream/1.5.56
                  }
-                 GenomeListItem item = new GenomeListItem(fields[0], file.getAbsolutePath(),
-                         fields[2], 0, true);
-                 genomeItemList.add(item);
+             }
+             if (clientGenomeListNeedsRebuilding) {
+                 rebuildClientGenomeList(userDefinedGenomeArchiveList);
              }
          }
-         if (clientGenomeListNeedsRebuilding) {
-             rebuildClientGenomeList(genomeItemList);
-         }
-         return genomeItemList;
+         return userDefinedGenomeArchiveList;
      }
  
      /**
@@@ -750,130 -758,116 +820,161 @@@
       * Gets a list of all the locally cached genome archive files that
       * IGV knows about.
       *
-      * @param excludedArchivesUrls The set of file location to exclude in the
-      *                             return list.
       * @return LinkedHashSet<GenomeListItem>
       * @throws IOException
       * @see GenomeListItem
       */
-     public LinkedHashSet<GenomeListItem> getCachedGenomeArchiveList(Set excludedArchivesUrls)
+     public LinkedHashSet<GenomeListItem> getCachedGenomeArchiveList()
              throws IOException {
  
-         LinkedHashSet<GenomeListItem> genomeItemList = new LinkedHashSet();
- 
-         if (!GENOME_CACHE_DIRECTORY.exists()) {
-             return genomeItemList;
-         }
- 
-         File[] files = GENOME_CACHE_DIRECTORY.listFiles();
-         for (File file : files) {
  
-             if (file.isDirectory()) {
-                 continue;
-             }
+         if (cachedGenomeArchiveList == null) {
+             cachedGenomeArchiveList = new LinkedHashSet();
  
++<<<<<<< HEAD
 +            if (!file.getName().toLowerCase().endsWith(Globals.GENOME_FILE_EXTENSION)) {
 +                continue;
++=======
+             if (!GENOME_CACHE_DIRECTORY.exists()) {
+                 return cachedGenomeArchiveList;
++>>>>>>> upstream/1.5.56
              }
  
-             URL zipUrl = file.toURI().toURL();
+             File[] files = GENOME_CACHE_DIRECTORY.listFiles();
+             for (File file : files) {
  
-             // Throw away records we don't want to see
-             if (excludedArchivesUrls != null) {
-                 if (excludedArchivesUrls.contains(URLDecoder.decode(zipUrl.getFile(), "UTF-8"))) {
+                 if (file.isDirectory()) {
                      continue;
                  }
-             }
  
-             ZipFile zipFile = null;
-             FileInputStream fis = null;
-             ZipInputStream zipInputStream = null;
-             try {
+                 if (!file.getName().toLowerCase().endsWith(Globals.GENOME_FILE_EXTENSION)) {
+                     continue;
+                 }
  
-                 zipFile = new ZipFile(file);
-                 fis = new FileInputStream(file);
-                 zipInputStream = new ZipInputStream(new BufferedInputStream(fis));
+                 URL zipUrl = file.toURI().toURL();
  
++<<<<<<< HEAD
 +                ZipEntry zipEntry = zipFile.getEntry(Globals.GENOME_ARCHIVE_PROPERTY_FILE_NAME);
 +                if (zipEntry == null) {
 +                    continue;    // Should never happen
 +                }
++=======
+                 ZipFile zipFile = null;
+                 FileInputStream fis = null;
+                 ZipInputStream zipInputStream = null;
+                 try {
++>>>>>>> upstream/1.5.56
  
-                 InputStream inputStream = zipFile.getInputStream(zipEntry);
-                 Properties properties = new Properties();
-                 properties.load(inputStream);
+                     zipFile = new ZipFile(file);
+                     fis = new FileInputStream(file);
+                     zipInputStream = new ZipInputStream(new BufferedInputStream(fis));
  
++<<<<<<< HEAD
 +                int version = 0;
 +                if (properties.containsKey(Globals.GENOME_ARCHIVE_VERSION_KEY)) {
 +                    try {
 +                        version = Integer.parseInt(
 +                                properties.getProperty(Globals.GENOME_ARCHIVE_VERSION_KEY));
 +                    } catch (Exception e) {
 +                        log.error("Error parsing genome version: " + version, e);
++=======
+                     ZipEntry zipEntry = zipFile.getEntry(Globals.GENOME_ARCHIVE_PROPERTY_FILE_NAME);
+                     if (zipEntry == null) {
+                         continue;    // Should never happen
++>>>>>>> upstream/1.5.56
                      }
-                 }
  
++<<<<<<< HEAD
 +                GenomeListItem item =
 +                        new GenomeListItem(properties.getProperty(Globals.GENOME_ARCHIVE_NAME_KEY),
 +                                file.getAbsolutePath(),
 +                                properties.getProperty(Globals.GENOME_ARCHIVE_ID_KEY),
 +                                version,
 +                                false);
 +                genomeItemList.add(item);
 +            } catch (ZipException ex) {
 +                log.error("\nZip error unzipping cached genome.", ex);
 +                JOptionPane.showMessageDialog(null, "Fatal error loading genome file: " + file.getAbsolutePath() +
 +                        "\n     *** " + ex.getMessage() + " ***" +
 +                        "\nIGV must exit.  If this problem persists contact igv-help at broadinstitute.org");
 +                try {
 +                    file.deleteOnExit();
 +                    zipInputStream.close();
 +                }
 +                catch (Exception e) {
 +                    //ignore exception when trying to delete file
 +                }
 +                System.exit(-1);
++=======
+                     InputStream inputStream = zipFile.getInputStream(zipEntry);
+                     Properties properties = new Properties();
+                     properties.load(inputStream);
++>>>>>>> upstream/1.5.56
  
+                     int version = 0;
+                     if (properties.containsKey(Globals.GENOME_ARCHIVE_VERSION_KEY)) {
+                         try {
+                             version = Integer.parseInt(
+                                     properties.getProperty(Globals.GENOME_ARCHIVE_VERSION_KEY));
+                         } catch (Exception e) {
+                             log.error("Error parsing genome version: " + version, e);
+                         }
+                     }
  
-             } catch (IOException ex) {
-                 log.warn("\nIO error unzipping cached genome.", ex);
-                 try {
-                     file.delete();
-                 }
-                 catch (Exception e) {
-                     //ignore exception when trying to delete file
-                 }
-             } finally {
-                 try {
-                     if (zipInputStream != null) {
+                     GenomeListItem item =
+                             new GenomeListItem(properties.getProperty(Globals.GENOME_ARCHIVE_NAME_KEY),
+                                     file.getAbsolutePath(),
+                                     properties.getProperty(Globals.GENOME_ARCHIVE_ID_KEY),
+                                     version,
+                                     false);
+                     cachedGenomeArchiveList.add(item);
+                 } catch (ZipException ex) {
+                     log.error("\nZip error unzipping cached genome.", ex);
+                     try {
+                         file.delete();
                          zipInputStream.close();
                      }
-                     if (zipFile != null) {
-                         zipFile.close();
-                     }
-                     if (fis != null) {
-                         fis.close();
+                     catch (Exception e) {
+                         //ignore exception when trying to delete file
                      }
                  } catch (IOException ex) {
-                     log.warn("Error closing genome zip stream!", ex);
+                     log.warn("\nIO error unzipping cached genome.", ex);
+                     try {
+                         file.delete();
+                     }
+                     catch (Exception e) {
+                         //ignore exception when trying to delete file
+                     }
+                 } finally {
+                     try {
+                         if (zipInputStream != null) {
+                             zipInputStream.close();
+                         }
+                         if (zipFile != null) {
+                             zipFile.close();
+                         }
+                         if (fis != null) {
+                             fis.close();
+                         }
+                     } catch (IOException ex) {
+                         log.warn("Error closing genome zip stream!", ex);
+                     }
                  }
              }
          }
  
-         return genomeItemList;
+         return cachedGenomeArchiveList;
      }
  
      /**
       * Gets a list of all the server and client-side genome archive files that
       * IGV knows about.
       *
-      * @param excludedArchivesUrls The set of file location to exclude in the
-      *                             return list.
       * @return LinkedHashSet<GenomeListItem>
       * @throws IOException
       * @see GenomeListItem
       */
-     public LinkedHashSet<GenomeListItem> getAllGenomeArchives(Set excludedArchivesUrls)
+     public LinkedHashSet<GenomeListItem> getAllGenomeArchives()
              throws IOException {
  
          LinkedHashSet<GenomeListItem> genomeListItems = new LinkedHashSet();
@@@ -890,9 -884,9 +991,9 @@@
              log.error(UIConstants.CANNOT_ACCESS_SERVER_GENOME_LIST, e);
          }
  
-         LinkedHashSet<GenomeListItem> cacheGenomeItemList = getCachedGenomeArchiveList(excludedArchivesUrls);
+         LinkedHashSet<GenomeListItem> cacheGenomeItemList = getCachedGenomeArchiveList();
  
-         LinkedHashSet<GenomeListItem> userDefinedItemList = getUserDefinedGenomeArchiveList(excludedArchivesUrls);
+         LinkedHashSet<GenomeListItem> userDefinedItemList = getUserDefinedGenomeArchiveList();
  
  
          if (serverSideItemList != null) {
@@@ -907,7 -901,7 +1008,11 @@@
  
          if (genomeListItems.isEmpty()) {
              GenomeDescriptor defaultDes = getDefaultGenomeDescriptor();
++<<<<<<< HEAD
 +            GenomeListItem defaultItem = getDefaultGenomeListItem();
++=======
+             GenomeListItem defaultItem = new GenomeListItem(defaultDes.getName(), null, defaultDes.getId(), 0, false);
++>>>>>>> upstream/1.5.56
              genomeListItems.add(defaultItem);
              Genome genome = loadGenome(defaultDes);
              genomes.put(defaultDes.getId(), genome);
@@@ -1130,12 -1124,17 +1235,24 @@@
          return text;
      }
  
++<<<<<<< HEAD
 +    public GenomeDescriptor getDefaultGenomeDescriptor() {
 +        if (DEFAULT == null) {
 +            DEFAULT = new GenomeResourceDescriptor("Human hg18", 0, "hg18",
 +                    "/resources/hg18_cytoBand.txt", null, null, "http://www.broadinstitute.org/igv/sequence/hg18", false);
++=======
+ 
+     public GenomeListItem getTopGenomeListItem() {
+         try {
+             LinkedHashSet<GenomeListItem> allItems = getAllGenomeArchives();
+             if(allItems.size() > 0) {
+                 return allItems.iterator().next();
+             }
+         } catch (IOException e) {
+             log.error("Error loading genome list: ", e);
++>>>>>>> upstream/1.5.56
          }
-         return DEFAULT;
+         return getDefaultGenomeListItem();
      }
  
      public GenomeListItem getDefaultGenomeListItem() {
@@@ -1143,6 -1142,15 +1260,15 @@@
          return new GenomeListItem(desc.getName(), null, desc.getId(), 0, false);
      }
  
+ 
+     private GenomeDescriptor getDefaultGenomeDescriptor() {
+         if (DEFAULT_GENOME == null) {
+             DEFAULT_GENOME = new GenomeResourceDescriptor("Human hg18", 0, "hg18",
+                     "/resources/hg18_cytoBand.txt", null, null, "http://www.broadinstitute.org/igv/sequence/hg18", false);
+         }
+         return DEFAULT_GENOME;
+     }
+ 
      /**
       * A container for specific genome information which can be used to
       * manage loaded genomes.
@@@ -1260,11 -1268,13 +1386,21 @@@
  
      public Map<String, String> getChromosomeAliasTable(String genomeId) {
  
++<<<<<<< HEAD
 +        File aliasFile = new File(Globals.GENOME_CACHE_FOLDER_NAME, genomeId + "_alias.tab");
 +
 +        if (aliasFile.exists()) {
 +            BufferedReader br = null;
 +
++=======
+         File aliasFile = new File(GENOME_CACHE_DIRECTORY, genomeId + "_alias.tab");
+         log.debug("Looking for chromosome alias file: " + aliasFile.getAbsolutePath());
+ 
+         if (aliasFile.exists()) {
+             log.debug("Loading chromosome alias table ");
+ 
+             BufferedReader br = null;
++>>>>>>> upstream/1.5.56
              Map<String, String> chrAliasTable = new HashMap();
              try {
                  br = new BufferedReader(new FileReader(aliasFile));
@@@ -1272,6 -1282,7 +1408,10 @@@
                  while ((nextLine = br.readLine()) != null) {
                      String[] kv = nextLine.split("\t");
                      if (kv.length > 1) {
++<<<<<<< HEAD
++=======
+                         log.debug(kv[0] + " -> " + kv[1]);
++>>>>>>> upstream/1.5.56
                          chrAliasTable.put(kv[0], kv[1]);
                      }
                  }
diff --combined src/org/broad/igv/feature/dranger/DRangerFeature.java
index 5ca704f,7642f34..3166436
--- a/src/org/broad/igv/feature/dranger/DRangerFeature.java
+++ b/src/org/broad/igv/feature/dranger/DRangerFeature.java
@@@ -44,18 -44,23 +44,38 @@@ public class DRangerFeature extends Abs
      String chr2;
      int pos2;
      Strand str2;
++<<<<<<< HEAD
 +
 +    private int tumreads;
 +    private int normreads;
 +    private String featureClass;
 +    private int span;
 +    private String site1;
 +    private String site2;
 +    private int quality;
 +    private int score;
 +
 +    /**
 +     * Construct a new dRanger feature.  Arbitrarily sized at 10 bases so they are easier to see
++=======
+ 
+     private int tumreads;
+     private int normreads;
+     private String featureClass;
+     private int span;
+     private String site1;
+     private String site2;
+     private int quality;
+     private int score;
+ 
+     public DRangerFeature() {
+ 
+     }
+ 
+     /**
+      * Construct a new dRanger feature.  Arbitrarily sized at 10 bases so they are easier to see
+      *
++>>>>>>> upstream/1.5.56
       * @param chr
       * @param pos1
       * @param strand1
@@@ -63,8 -68,9 +83,14 @@@
       * @param pos2
       * @param str2
       */
++<<<<<<< HEAD
 +    public DRangerFeature(String chr, int pos1, Strand strand1, String chr2, int pos2, Strand str2) {
 +        super(chr, pos1-5, pos1 + 5, strand1);
++=======
+ 
+     public DRangerFeature(String chr, int pos1, Strand strand1, String chr2, int pos2, Strand str2) {
+         super(chr, pos1 - 5, pos1 + 5, strand1);
++>>>>>>> upstream/1.5.56
          this.chr2 = chr2;
          this.pos2 = pos2;
          this.str2 = str2;
@@@ -80,6 -86,7 +106,7 @@@
      }
  
      // Score calibrated to = ~ 1,000 if 1/2 the reads support the rearrangment
+ 
      @Override
      public float getScore() {
          return score;
@@@ -87,7 -94,23 +114,27 @@@
      }
  
      public LocusScore copy() {
++<<<<<<< HEAD
 +        return this;
++=======
+         DRangerFeature newFeat = new DRangerFeature();
+         newFeat.setChr(getChr());
+         newFeat.setStart(getStart());
+         newFeat.setEnd(getEnd());
+         newFeat.chr2 = chr2;
+         newFeat.pos2 = pos2;
+         newFeat.str2 = str2;
+         newFeat.tumreads = tumreads;
+         newFeat.normreads = normreads;
+         newFeat.featureClass = featureClass;
+         ;
+         newFeat.span = span;
+         newFeat.site1 = site1;
+         newFeat.site2 = site2;
+         newFeat.quality = quality;
+         newFeat.score = score;
+         return newFeat;
++>>>>>>> upstream/1.5.56
      }
  
      public String positionString() {
@@@ -178,6 -201,7 +225,10 @@@
  
      float[] defaultColor = Color.blue.getComponents(null);
      static Map<String, float[]> colorMap;
++<<<<<<< HEAD
++=======
+ 
++>>>>>>> upstream/1.5.56
      static {
          colorMap = new HashMap();
          colorMap.put("deletion", Color.red.getComponents(null));
@@@ -189,8 -213,8 +240,13 @@@
  
      @Override
      public Color getColor() {
++<<<<<<< HEAD
 +        float [] baseColor = defaultColor;
 +        if(featureClass != null  && colorMap.containsKey(featureClass)) {
++=======
+         float[] baseColor = defaultColor;
+         if (featureClass != null && colorMap.containsKey(featureClass)) {
++>>>>>>> upstream/1.5.56
              baseColor = colorMap.get(featureClass);
          }
          float alpha = Math.min(1.0f, Math.max(0.15f, .15f + (.85f / 3) * score));
diff --combined src/org/broad/igv/h5/HDF5ReaderFactory.java
index 5f8ce19,f9f1854..37d4c4c
--- a/src/org/broad/igv/h5/HDF5ReaderFactory.java
+++ b/src/org/broad/igv/h5/HDF5ReaderFactory.java
@@@ -22,6 -22,7 +22,7 @@@
   */
  package org.broad.igv.h5;
  
+ import org.broad.igv.exceptions.DataLoadException;
  import org.broad.igv.util.ResourceLocator;
  
  import java.io.File;
@@@ -39,7 -40,8 +40,12 @@@ public class HDF5ReaderFactory 
       */
      public static HDF5Reader getReader(ResourceLocator locator) {
          if (locator.isLocal()) {
++<<<<<<< HEAD
 +            return new HDF5LocalReader(locator.getPath());
++=======
+             throw new DataLoadException("HDF5 files are no longer supported.  " +
+                     "Contact igv-help at broadinstitute.org for more information.", locator.getPath());
++>>>>>>> upstream/1.5.56
          } else {
              return new HDF5RemoteReader(locator);
          }
diff --combined src/org/broad/igv/maf/MAFRemoteReader.java
index 77c0cb2,9d18f6d..6a9b6c9
--- a/src/org/broad/igv/maf/MAFRemoteReader.java
+++ b/src/org/broad/igv/maf/MAFRemoteReader.java
@@@ -54,8 -54,7 +54,12 @@@ public class MAFRemoteReader implement
                              List<String> species) {
          DataInputStream is = null;
          try {
++<<<<<<< HEAD
 +            URL url = new URL(serverURL + "?method=maf&chr=" +
 +                    chr + "&start=" + start + "&end=" + end);
++=======
+             URL url = new URL(serverURL + "?method=maf&chr=" + chr + "&start=" + start + "&end=" + end);
++>>>>>>> upstream/1.5.56
              URLConnection connection = IGVHttpUtils.openConnection(url);
              is = new DataInputStream(new GZIPInputStream(new BufferedInputStream(connection.getInputStream())));
              MAFTile tile = codec.decode(is);
diff --combined src/org/broad/igv/main/BatchRunner.java
index ad204cf,4720c7b..67df83a
--- a/src/org/broad/igv/main/BatchRunner.java
+++ b/src/org/broad/igv/main/BatchRunner.java
@@@ -23,6 -23,7 +23,10 @@@ import org.broad.igv.Globals
  import org.broad.igv.exceptions.DataLoadException;
  import org.broad.igv.ui.WaitCursorManager;
  import org.broad.igv.util.NamedRunnable;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.util.ParsingUtils;
++>>>>>>> upstream/1.5.56
  
  import java.io.BufferedReader;
  import java.io.File;
@@@ -50,28 -51,34 +54,56 @@@ public class BatchRunner implements Nam
          Globals.setSuppress(true);
          Globals.batch = true;
  
++<<<<<<< HEAD
 +        WaitCursorManager.CursorToken cursorToken = null;
 +        try {
 +            cursorToken = WaitCursorManager.showWaitCursor();
 +            File inFile = new File(inputFile);
 +            if (inFile.isFile()) {
 +                BufferedReader bfr = new BufferedReader(new FileReader(inputFile));
 +
 +                while ((inLine = bfr.readLine()) != null) {
 +                    if (!(inLine.startsWith("#") || inLine.startsWith("//"))) {
 +                        log.info("Executing Command: " + inLine);
 +                        cmdExe.execute(inLine);
 +                    }
 +                }
 +                bfr.close();
 +            }
++=======
+        WaitCursorManager.CursorToken cursorToken = null;
+         BufferedReader reader = null;
+         try {
+             cursorToken = WaitCursorManager.showWaitCursor();
+             reader = ParsingUtils.openBufferedReader(inputFile);
+ 
+             while ((inLine = reader.readLine()) != null) {
+                 if (!(inLine.startsWith("#") || inLine.startsWith("//"))) {
+                     log.info("Executing Command: " + inLine);
+                     cmdExe.execute(inLine);
+                 }
+             }
+ 
+ 
++>>>>>>> upstream/1.5.56
          } catch (IOException ioe) {
              throw new DataLoadException(ioe.getMessage(), inputFile);
          } finally {
              Globals.setSuppress(false);
              Globals.batch = false;
              if (cursorToken != null) WaitCursorManager.removeWaitCursor(cursorToken);
++<<<<<<< HEAD
 +        }//To change body of implemented methods use File | Settings | File Templates.
++=======
+             if (reader != null) {
+                 try {
+                     reader.close();
+                 } catch (IOException e) {
+                     e.printStackTrace();
+                 }
+             }
+         }
++>>>>>>> upstream/1.5.56
      }
  
  }
diff --combined src/org/broad/igv/main/CommandExecutor.java
index 833b94c,1d2513c..af9b0f1
--- a/src/org/broad/igv/main/CommandExecutor.java
+++ b/src/org/broad/igv/main/CommandExecutor.java
@@@ -91,13 -91,17 +91,27 @@@ public class CommandExecutor 
                  } else if (cmd.equals("new") || cmd.equals("reset") || cmd.equals("clear")) {
                      mainFrame.createNewSession(null);
                  } else if (cmd.equals("sort")) {
++<<<<<<< HEAD
 +                    sort(param1, param2);
 +                } else if (cmd.equals("collapse")) {
 +                    collapse(param1);
 +                } else if (cmd.equals("expand")) {
 +                    expand(param1);
 +                } else if (cmd.equals("tweakdivider")) {
 +                    IGVMainFrame.getInstance().tweakPanelDivider();
++=======
+                     sort(param1, param2, param3);
+                 } else if (cmd.equals("collapse")) {
+                     String trackName = param1 == null ? null : param1.replace("\"", "").replace("'", "");
+                     collapse(trackName);
+                 } else if (cmd.equals("expand")) {
+                     String trackName = param1 == null ? null : param1.replace("\"", "").replace("'", "");
+                     expand(trackName);
+                 } else if (cmd.equals("tweakdivider")) {
+                     IGVMainFrame.getInstance().tweakPanelDivider();
+                 } else if (cmd.equals("exit")) {
+                     System.exit(0);
++>>>>>>> upstream/1.5.56
                  } else {
                      log.error("UNKOWN COMMAND: " + command);
                      return "UNKOWN COMMAND: " + command;
@@@ -125,7 -129,7 +139,11 @@@
      }
  
      private String genome(String param1) {
++<<<<<<< HEAD
 +        if(param1 == null) {
++=======
+         if (param1 == null) {
++>>>>>>> upstream/1.5.56
              return "ERROR missing genome parameter";
          }
          String result;
@@@ -146,15 -150,15 +164,27 @@@
      }
  
      private String load(String param1) {
++<<<<<<< HEAD
 +        if(param1 == null) {
 +           return "ERROR: missing path parameter"; 
 +        }
 +        String fileString = param1.replace("\"", "").replace("'", "");
 +        return   loadFiles(fileString, null, true);
 +    }
 +
 +    private String setSnapshotDirectory(String param1) {
 +        if(param1 == null) {
++=======
+         if (param1 == null) {
+             return "ERROR: missing path parameter";
+         }
+         String fileString = param1.replace("\"", "").replace("'", "");
+         return loadFiles(fileString, null, true);
+     }
+ 
+     private String setSnapshotDirectory(String param1) {
+         if (param1 == null) {
++>>>>>>> upstream/1.5.56
              return "ERROR: missing directory parameter";
          }
  
@@@ -164,13 -168,13 +194,21 @@@
              MacroSnapshotAction.setOutputDirectory(param1);
              result = "OK";
          } else {
++<<<<<<< HEAD
 +            result =  "ERROR: directory: " + param1 + " does not exist";
++=======
+             result = "ERROR: directory: " + param1 + " does not exist";
++>>>>>>> upstream/1.5.56
          }
          return result;
      }
  
      private String goto1(String param1) {
++<<<<<<< HEAD
 +        if(param1 == null) {
++=======
+         if (param1 == null) {
++>>>>>>> upstream/1.5.56
              return "ERROR: missing locus parameter";
          }
          String locus = param1;
@@@ -198,7 -202,7 +236,11 @@@
      }
  
  
++<<<<<<< HEAD
 +    private void sort(String sortArg, String locusString) {
++=======
+     private void sort(String sortArg, String locusString, String param3) {
++>>>>>>> upstream/1.5.56
          TrackManager tm = IGVMainFrame.getInstance().getTrackManager();
          RegionScoreType regionSortOption = getRegionSortOption(sortArg);
          if (regionSortOption != null) {
@@@ -212,7 -216,20 +254,24 @@@
              tm.sortByRegionScore(roi, regionSortOption);
  
          } else {
++<<<<<<< HEAD
 +            tm.sortAlignmentTracks(getAlignmentSortOption(sortArg));
++=======
+             Double location = null;
+             if (param3 != null) {
+                 try {
+                     location = new Double(param3);
+                 }
+                 catch (NumberFormatException e) {
+                     log.info("Unexpected sort location argument: " + param3);
+                 }
+             }
+             if (location == null) {
+                 tm.sortAlignmentTracks(getAlignmentSortOption(sortArg));
+             } else {
+                 tm.sortAlignmentTracks(getAlignmentSortOption(sortArg), location);
+             }
++>>>>>>> upstream/1.5.56
          }
          IGVMainFrame.getInstance().repaintDataPanels();
      }
@@@ -241,11 -258,11 +300,19 @@@
                  }
              }
  
++<<<<<<< HEAD
 +            for (String session : sessionPaths) {
 +                InputStream is = null;
 +                try {
 +                    is = ParsingUtils.openInputStream(new ResourceLocator(session));
 +                    IGVMainFrame.getInstance().doRestoreSession(is, session, locus, merge);
++=======
+             for (String sessionPath : sessionPaths) {
+                 InputStream is = null;
+                 try {
+                     is = ParsingUtils.openInputStream(new ResourceLocator(sessionPath));
+                     IGVMainFrame.getInstance().doRestoreSession(is, sessionPath, locus, merge);
++>>>>>>> upstream/1.5.56
                  }
                  catch (IOException e) {
                      log.error(e.getMessage(), e);
@@@ -277,7 -294,7 +344,11 @@@
      }
  
      private static RegionScoreType getRegionSortOption(String str) {
++<<<<<<< HEAD
 +        if(str == null) return null;
++=======
+         if (str == null) return null;
++>>>>>>> upstream/1.5.56
          String option = str.toUpperCase();
          try {
              return RegionScoreType.valueOf(option);
diff --combined src/org/broad/igv/renderer/BasicFeatureRenderer.java
index 000d9bd,9486ea5..fa47fed
--- a/src/org/broad/igv/renderer/BasicFeatureRenderer.java
+++ b/src/org/broad/igv/renderer/BasicFeatureRenderer.java
@@@ -171,7 -171,7 +171,11 @@@ public class BasicFeatureRenderer exten
                          pixelThickEnd = (int) Math.min(trackRectangleMaxX, (bf.getThickEnd() - origin) / locScale);
                      }
  
++<<<<<<< HEAD
 +                    drawFeatureBlock(pixelStart, pixelEnd, pixelThickStart, pixelThickEnd,  trackRectangle, strand, hasRegions, g2D);
++=======
+                     drawFeatureBlock(pixelStart, pixelEnd, pixelThickStart, pixelThickEnd, trackRectangle, strand, hasRegions, g2D);
++>>>>>>> upstream/1.5.56
  
                      // Determine the y offset of features based on strand type
  
@@@ -327,8 -327,8 +331,13 @@@
          for (Exon exon : gene.getExons()) {
              int pStart = getPixelFromChromosomeLocation(exon.getChr(), exon.getStart(), theOrigin, locationScale);
              int pEnd = getPixelFromChromosomeLocation(exon.getChr(), exon.getEnd(), theOrigin, locationScale);
++<<<<<<< HEAD
  
  
++=======
++
++
++>>>>>>> upstream/1.5.56
              if ((pEnd >= trackRectangle.getX()) && (pStart <= trackRectangle.getMaxX())) {
                  int pCdStart =
                          Math.min(pEnd, Math.max(pStart,
@@@ -338,31 -338,39 +347,67 @@@
                          getPixelFromChromosomeLocation(exon.getChr(),
                                  exon.getCdEnd(), theOrigin, locationScale)));
  
++<<<<<<< HEAD
 +
 +                // Exon contains 5' UTR -- draw non-coding part
 +                if (pCdStart > pStart) {
 +                    int pClippedStart = (int) Math.max(pStart, trackRectangle.getX());
 +                    int pClippedEnd = (int) Math.min(pCdStart, trackRectangle.getMaxX());
 +                    int pClippedWidth = pClippedEnd - pClippedStart;
 +                    g2D.fillRect(pClippedStart, yOffset - NON_CODING_HEIGHT / 2, pClippedWidth, NON_CODING_HEIGHT);
 +                    pStart = pCdStart;
 +                }
 +                //  Exon contains 3' UTR  -- draw non-coding part
 +                if (pCdEnd < pEnd) {
 +                    int pClippedStart = (int) Math.max(pCdEnd, trackRectangle.getX());
 +                    int pClippedEnd = (int) Math.min(pEnd, trackRectangle.getMaxX());
 +                    int pClippedWidth = pClippedEnd - pClippedStart;
 +                    g2D.fillRect(pClippedStart, yOffset - NON_CODING_HEIGHT / 2, pClippedWidth, NON_CODING_HEIGHT);
 +                    pEnd = pCdEnd;
 +                }
 +
 +                // At least part of this exon is coding.  Draw the coding part.
 +                if ((exon.getCdStart() < exon.getEnd()) && (exon.getCdEnd() > exon.getStart())) {
 +                    int pClippedStart = (int) Math.max(pStart, trackRectangle.getX());
 +                    int pClippedEnd = (int) Math.min(pEnd, trackRectangle.getMaxX());
 +                    int pClippedWidth = Math.max(2, pClippedEnd - pClippedStart);
 +                    g2D.fillRect(pClippedStart, yOffset - BLOCK_HEIGHT / 2, pClippedWidth, BLOCK_HEIGHT);
 +
++=======
+                 // Entire exon is UTR
+                 if (exon.isUTR()) {
+                     int pClippedStart = (int) Math.max(pStart, trackRectangle.getX());
+                     int pClippedEnd = (int) Math.min(pEnd, trackRectangle.getMaxX());
+                     int pClippedWidth = pClippedEnd - pClippedStart;
+                     g2D.fillRect(pClippedStart, yOffset - NON_CODING_HEIGHT / 2, pClippedWidth, NON_CODING_HEIGHT);
+ 
+                 } else {
+                     // Exon contains 5' UTR -- draw non-coding part
+                     if (pCdStart > pStart) {
+                         int pClippedStart = (int) Math.max(pStart, trackRectangle.getX());
+                         int pClippedEnd = (int) Math.min(pCdStart, trackRectangle.getMaxX());
+                         int pClippedWidth = pClippedEnd - pClippedStart;
+                         g2D.fillRect(pClippedStart, yOffset - NON_CODING_HEIGHT / 2, pClippedWidth, NON_CODING_HEIGHT);
+                         pStart = pCdStart;
+                     }
+                     //  Exon contains 3' UTR  -- draw non-coding part
+                     if (pCdEnd < pEnd) {
+                         int pClippedStart = (int) Math.max(pCdEnd, trackRectangle.getX());
+                         int pClippedEnd = (int) Math.min(pEnd, trackRectangle.getMaxX());
+                         int pClippedWidth = pClippedEnd - pClippedStart;
+                         g2D.fillRect(pClippedStart, yOffset - NON_CODING_HEIGHT / 2, pClippedWidth, NON_CODING_HEIGHT);
+                         pEnd = pCdEnd;
+                     }
+ 
+                     // At least part of this exon is coding.  Draw the coding part.
+                     if ((exon.getCdStart() < exon.getEnd()) && (exon.getCdEnd() > exon.getStart())) {
+                         int pClippedStart = (int) Math.max(pStart, trackRectangle.getX());
+                         int pClippedEnd = (int) Math.min(pEnd, trackRectangle.getMaxX());
+                         int pClippedWidth = Math.max(2, pClippedEnd - pClippedStart);
+                         g2D.fillRect(pClippedStart, yOffset - BLOCK_HEIGHT / 2, pClippedWidth, BLOCK_HEIGHT);
+ 
+                     }
++>>>>>>> upstream/1.5.56
                  }
  
                  Graphics2D arrowGraphics = context.getGraphic2DForColor(Color.white);
@@@ -576,7 -584,8 +621,12 @@@
          if (track.isUseScore()) {
              float min = getViewLimitMin(track);
              float max = getViewLimitMax(track);
++<<<<<<< HEAD
 +            float alpha = getAlpha(min, max, feature.getScore());
++=======
+             float score = feature.getScore();
+             float alpha = Float.isNaN(score) ? 1 : getAlpha(min, max, score);
++>>>>>>> upstream/1.5.56
              color.getColorComponents(colorComps);
              color = ColorUtilities.getCompositeColor(colorComps, alpha);
          }
diff --combined src/org/broad/igv/sam/AbstractAlignment.java
index 0388912,78f9480..7250e04
--- a/src/org/broad/igv/sam/AbstractAlignment.java
+++ b/src/org/broad/igv/sam/AbstractAlignment.java
@@@ -25,6 -25,8 +25,8 @@@ package org.broad.igv.sam
  import org.broad.igv.feature.Strand;
  import org.broad.igv.track.WindowFunction;
  
+ import java.awt.*;
+ 
  /**
   * @author jrobinso
   */
@@@ -268,5 -270,10 +270,13 @@@ public abstract class AbstractAlignmen
      public boolean isVendorFailedRead() {
          return false;
      }
++<<<<<<< HEAD
++=======
+ 
+ 
+     public Color getDefaultColor() {
+         return AlignmentRenderer.grey1;
+     }
++>>>>>>> upstream/1.5.56
  
  }
diff --combined src/org/broad/igv/sam/Alignment.java
index e406837,c9745cd..fe8eb7c
--- a/src/org/broad/igv/sam/Alignment.java
+++ b/src/org/broad/igv/sam/Alignment.java
@@@ -24,6 -24,8 +24,11 @@@ package org.broad.igv.sam
  
  import org.broad.igv.feature.LocusScore;
  import org.broad.igv.feature.Strand;
++<<<<<<< HEAD
++=======
+ 
+ import java.awt.*;
++>>>>>>> upstream/1.5.56
  
  /**
   * @author jrobinso
@@@ -91,4 -93,7 +96,10 @@@ public interface Alignment extends Locu
      boolean isSmallInsert();
  
      boolean isVendorFailedRead();
++<<<<<<< HEAD
++=======
+ 
+     Color getDefaultColor();
+ 
++>>>>>>> upstream/1.5.56
  }
diff --combined src/org/broad/igv/sam/AlignmentDataManager.java
index cd101c4,3476b70..01162e0
--- a/src/org/broad/igv/sam/AlignmentDataManager.java
+++ b/src/org/broad/igv/sam/AlignmentDataManager.java
@@@ -23,7 -23,7 +23,7 @@@ import org.broad.igv.Globals
  import org.broad.igv.PreferenceManager;
  import org.broad.igv.feature.Genome;
  import org.broad.igv.sam.AlignmentTrack.SortOption;
- import org.broad.igv.sam.reader.AlignmentQueryReader;
+ import org.broad.igv.sam.reader.CachingQueryReader;
  import org.broad.igv.sam.reader.SamListReader;
  import org.broad.igv.sam.reader.SamQueryReaderFactory;
  import org.broad.igv.session.ViewContext;
@@@ -41,48 -41,51 +41,86 @@@ public class AlignmentDataManager 
  
      private static Logger log = Logger.getLogger(AlignmentDataManager.class);
      private AlignmentInterval loadedInterval = null;
++<<<<<<< HEAD
 +    HashMap<String, String> chrMappings = new HashMap();
 +    boolean isLoading = false;
 +    AlignmentQueryReader reader;
 +
 +    CoverageTrack coverageTrack;
 +
 +    private static final int DEFAULT_DEPTH = 10;
 +
 +
 +    public static AlignmentDataManager getDataManager(ResourceLocator locator) {
++=======
+     private HashMap<String, String> chrMappings = new HashMap();
+     private boolean isLoading = false;
+     private CachingQueryReader reader;
+     private CoverageTrack coverageTrack;
+     private int maxLevels;
+ 
+     private static final int DEFAULT_DEPTH = 10;
+ 
+ 
+     public static AlignmentDataManager getDataManager(ResourceLocator locator) throws IOException {
++>>>>>>> upstream/1.5.56
          return new AlignmentDataManager(locator);
      }
  
-     public AlignmentQueryReader getReader() {
-         return reader;
-     }
  
-     private AlignmentDataManager(ResourceLocator locator) {
+     public AlignmentDataManager(ResourceLocator locator) throws IOException {
+ 
++<<<<<<< HEAD
++=======
+         PreferenceManager.SAMPreferences prefs = PreferenceManager.getInstance().getSAMPreferences();
+         maxLevels = prefs.getMaxLevels();
  
++>>>>>>> upstream/1.5.56
          if (locator.getPath().endsWith(".sam.list")) {
              MultiFileWrapper mfw = MultiFileWrapper.parse(locator);
-             reader = new SamListReader(mfw.getLocators());
+             reader = new CachingQueryReader(new SamListReader(mfw.getLocators()));
          } else {
-             reader = SamQueryReaderFactory.getReader(locator);
+             reader = new CachingQueryReader(SamQueryReaderFactory.getReader(locator));
          }
          initChrMap();
++<<<<<<< HEAD
 +    }
 +
 +    private void initChrMap() {
 +        Genome genome = ViewContext.getInstance().getGenome();
 +        if (genome != null) {
 +            Set<String> seqNames = reader.getSequenceNames();
 +            if (seqNames != null) {
 +                for (String chr : seqNames) {
 +                    String alias = genome.getChromosomeAlias(chr);
 +                    chrMappings.put(alias, chr);
 +                }
 +
 +            }
 +        }
 +    }
 +
++=======
+     }
+ 
+     private void initChrMap() {
+         Genome genome = ViewContext.getInstance().getGenome();
+         if (genome != null) {
+             Set<String> seqNames = reader.getSequenceNames();
+             if (seqNames != null) {
+                 for (String chr : seqNames) {
+                     String alias = genome.getChromosomeAlias(chr);
+                     chrMappings.put(alias, chr);
+                 }
+             }
+         }
+     }
+ 
+     public CachingQueryReader getReader() {
+         return reader;
+     }
+ 
++>>>>>>> upstream/1.5.56
  
      public boolean hasIndex() {
          return reader.hasIndex();
@@@ -90,7 -93,7 +128,7 @@@
  
      public int getMaxDepth() {
          return loadedInterval == null ? DEFAULT_DEPTH :
-                 (loadedInterval.getMaxCount() == 0 ? DEFAULT_DEPTH : loadedInterval.getMaxCount());
+                 (loadedInterval.getDepth() == 0 ? DEFAULT_DEPTH : loadedInterval.getDepth());
      }
  
      public void setCoverageTrack(CoverageTrack coverageTrack) {
@@@ -110,58 -113,58 +148,103 @@@
          if (loadedInterval != null) {
              loadedInterval.sortRows(option);
          }
+     }
  
++<<<<<<< HEAD
 +    }
 +
 +    public void packAlignments() {
 +        if(loadedInterval == null) {
++=======
+     public void sortRows(SortOption option, double location) {
+         if (loadedInterval != null) {
+             loadedInterval.sortRows(option, location);
+         }
+     }
+ 
+     public void packAlignments() {
+         if (loadedInterval == null) {
++>>>>>>> upstream/1.5.56
              return;
          }
          RowIterator iter = new RowIterator();
-         final PreferenceManager.SAMPreferences prefs = PreferenceManager.getInstance().getSAMPreferences();
-         final int maxLevels = prefs.getMaxLevels();
-         final int qualityThreshold = prefs.getQualityThreshold();
  
++<<<<<<< HEAD
 +        List<AlignmentInterval.Row> alignmentRows = AlignmentLoader.loadAndPackAlignments(
++=======
+         List<AlignmentInterval.Row> alignmentRows = AlignmentLoader.packAlignments(
++>>>>>>> upstream/1.5.56
                  iter,
-                 prefs.isShowDuplicates(),
-                 qualityThreshold,
                  maxLevels,
                  getLoadedInterval().getEnd());
++<<<<<<< HEAD
 +
++=======
++>>>>>>> upstream/1.5.56
          loadedInterval.setAlignmentRows(alignmentRows);
      }
  
  
      public synchronized List<AlignmentInterval.Row> getAlignmentRows(String genomeId, final String chr, final int start, final int end) {
          log.debug("Enter getAlignmentRows: " + chr + ":" + start + "-" + end);
++<<<<<<< HEAD
 +
 +        // If we've moved out of the loaded interval start a new load.
 +        if (loadedInterval == null || !loadedInterval.contains(genomeId, chr, start, end)) {
 +            loadAlignments(genomeId, chr, start, end);
 +        }
 +
 +        // If there is any overlap in the loaded interval and the requested interval return it.
 +        if (loadedInterval != null && loadedInterval.overlaps(genomeId, chr, start, end)) {
 +            return loadedInterval.getAlignmentRows();
 +        } else {
 +            return null;
 +        }
 +    }
 +
 +    public void reload() {
 +        if (loadedInterval != null) {
 +            String genomeId = loadedInterval.genomeId;
 +            String chr = loadedInterval.chr;
 +            int start = loadedInterval.getStart();
 +            int end = loadedInterval.getEnd();
 +            loadedInterval = null;
 +            loadAlignments(genomeId, chr, start, end);
 +        }
 +    }
 +
 +    public void loadAlignments(final String genomeId, final String chr, final int start, final int end) {
 +
++=======
+ 
+         // If we've moved out of the loaded interval start a new load.
+         if (loadedInterval == null || !loadedInterval.contains(genomeId, chr, start, end)) {
+             loadAlignments(genomeId, chr, start, end);
+         }
+ 
+         // If there is any overlap in the loaded interval and the requested interval return it.
+         if (loadedInterval != null && loadedInterval.overlaps(genomeId, chr, start, end)) {
+             return loadedInterval.getAlignmentRows();
+         } else {
+             return null;
+         }
+     }
+ 
+     public void reload() {
+         reader.clearCache();
+         if (loadedInterval != null) {
+             String genomeId = loadedInterval.genomeId;
+             String chr = loadedInterval.getChr();
+             int start = loadedInterval.getStart();
+             int end = loadedInterval.getEnd();
+             loadedInterval = null;
+             loadAlignments(genomeId, chr, start, end);
+         }
+     }
+ 
+     public void loadAlignments(final String genomeId, final String chr, final int start, final int end) {
+ 
++>>>>>>> upstream/1.5.56
          if (isLoading || chr.equals(Globals.CHR_ALL)) {
              return;
          }
@@@ -178,17 -181,14 +261,26 @@@
  
                  public void run() {
  
++<<<<<<< HEAD
 +                    log.debug("Preloading " + chr + ":" + start + "-" + end);
 +                    final PreferenceManager.SAMPreferences prefs = PreferenceManager.getInstance().getSAMPreferences();
 +                    final int maxLevels = prefs.getMaxLevels();
 +                    final int qualityThreshold = prefs.getQualityThreshold();
 +
++=======
+                     log.debug("Loading " + chr + ":" + start + "-" + end);
+                     final PreferenceManager.SAMPreferences prefs = PreferenceManager.getInstance().getSAMPreferences();
++>>>>>>> upstream/1.5.56
  
                      // Expand start and end to facilitate panning, but by no more than
                      // 1 screen or 8kb, whichever is less
                      // DON'T expand mitochondria
  
++<<<<<<< HEAD
 +                    int expandLength = isMitochondria(chr) ? 0 : Math.min(8000, end - start) / 2;
++=======
+                     int expandLength = reader.getTileSize(chr) / 2;                    
++>>>>>>> upstream/1.5.56
                      int intervalStart = Math.max(0, start - expandLength);
                      int intervalEnd = end + expandLength;
                      CloseableIterator<Alignment> iter = null;
@@@ -196,23 -196,17 +288,37 @@@
  
                          String sequence = chrMappings.containsKey(chr) ? chrMappings.get(chr) : chr;
  
++<<<<<<< HEAD
 +                        iter = reader.query(sequence, intervalStart, intervalEnd, false);
 +
 +                        List<AlignmentInterval.Row> alignmentRows = AlignmentLoader.loadAndPackAlignments(iter,
 +                                prefs.isShowDuplicates(),
 +                                qualityThreshold,
 +                                maxLevels,
 +                                intervalEnd);
 +
 +                        loadedInterval = new AlignmentInterval(genomeId, chr, intervalStart, intervalEnd, alignmentRows);
 +
 +                        // Caclulate coverage.  TODO -- refactor/move this
 +                        for (AlignmentInterval.Row row : alignmentRows) {
 +                            for (Alignment a : row.alignments) {
 +                                getLoadedInterval().incCounts(a);
 +                            }
 +                        }
++=======
+                         List<CachingQueryReader.AlignmentCounts> counts = new ArrayList();
+ 
+                         iter = reader.query(sequence, intervalStart, intervalEnd, counts);
+ 
+                         List<AlignmentInterval.Row> alignmentRows = AlignmentLoader.packAlignments(iter,
+                                 maxLevels,
+                                 intervalEnd);
+ 
+                         loadedInterval = new AlignmentInterval(genomeId, chr, intervalStart, intervalEnd,
+                                 alignmentRows, counts);
+ 
++>>>>>>> upstream/1.5.56
 +
  
                          if (coverageTrack != null) {
                              coverageTrack.rescale();
@@@ -266,6 -260,15 +372,18 @@@
  
      }
  
++<<<<<<< HEAD
++=======
+     public int getMaxLevels() {
+         return maxLevels;
+     }
+ 
+     public void setMaxLevels(int maxLevels) {
+         reader.clearCache();
+         this.maxLevels = maxLevels;
+     }
++>>>>>>> upstream/1.5.56
+ 
  
      /**
       * An alignment iterator that iterates over packed rows.  Used for
diff --combined src/org/broad/igv/sam/AlignmentInterval.java
index c5fddcb,d4e9438..dc9e2cf
--- a/src/org/broad/igv/sam/AlignmentInterval.java
+++ b/src/org/broad/igv/sam/AlignmentInterval.java
@@@ -23,7 -23,9 +23,12 @@@
  package org.broad.igv.sam;
  
  import org.apache.log4j.Logger;
+ import org.broad.igv.feature.Locus;
  import org.broad.igv.feature.SequenceManager;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.sam.reader.CachingQueryReader;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.session.ViewContext;
  
  import java.util.ArrayList;
@@@ -34,144 -36,119 +39,176 @@@ import java.util.List
  /**
   * @author jrobinso
   */
- public class AlignmentInterval {
+ public class AlignmentInterval extends Locus {
  
      private static Logger log = Logger.getLogger(AlignmentInterval.class);
  
      private List<AlignmentInterval.Row> alignmentRows;
++<<<<<<< HEAD
 +
++=======
+     List<CachingQueryReader.AlignmentCounts> counts;
++>>>>>>> upstream/1.5.56
      String genomeId;
-     String chr;
-     private int start;
-     private int end;
      byte[] reference;
++<<<<<<< HEAD
 +    // counts
 +    int[] posA;
 +    int[] posT;
 +    int[] posC;
 +    int[] posG;
 +    int[] posN;
 +    int[] negA;
 +    int[] negT;
 +    int[] negC;
 +    int[] negG;
 +    int[] negN;
 +    int[] qA;
 +    int[] qT;
 +    int[] qC;
 +    int[] qG;
 +    int[] qN;
 +    int[] posTotal;
 +    int[] negTotal;
 +    private int[] totalQ;
 +    private int maxCount = 0;
 +
 +    public AlignmentInterval(String genomeId, String chr, int start, int end, List<Row> rows) {
 +        this.genomeId = genomeId;
 +        this.chr = chr;
 +        this.start = start;
 +        this.end = end;
++=======
+     int maxCount = 0;
+ 
+     public AlignmentInterval(String genomeId, String chr, int start, int end, List<Row> rows,
+                              List<CachingQueryReader.AlignmentCounts> counts) {
+         super(chr, start, end);
+         this.genomeId = genomeId;
++>>>>>>> upstream/1.5.56
          this.alignmentRows = rows;
          reference = SequenceManager.readSequence(this.genomeId, chr, start, end);
- 
- 
-         int nPts = end - start;
-         posA = new int[nPts];
-         posT = new int[nPts];
-         posC = new int[nPts];
-         posG = new int[nPts];
-         posN = new int[nPts];
-         posTotal = new int[nPts];
-         negA = new int[nPts];
-         negT = new int[nPts];
-         negC = new int[nPts];
-         negG = new int[nPts];
-         negN = new int[nPts];
-         negTotal = new int[nPts];
-         qA = new int[nPts];
-         qT = new int[nPts];
-         qC = new int[nPts];
-         qG = new int[nPts];
-         qN = new int[nPts];
-         totalQ = new int[nPts];
+         this.counts = counts;
+         for(CachingQueryReader.AlignmentCounts c : counts) {
+             maxCount = Math.max(maxCount, c.getMaxCount());
+         }
      }
  
      boolean contains(String genomeId, String chr, int start, int end) {
-         return this.genomeId.equals(genomeId) && this.chr.equals(chr) && this.start <= start && this.end >= end;
+         return this.genomeId.equals(genomeId) && super.contains(chr, start, end);
      }
  
++<<<<<<< HEAD
 +    boolean overlaps(String genomeId, String chr, int start, int end) {
 +        return this.genomeId.equals(genomeId) && this.chr.equals(chr) && this.start <= end && this.end >= start;
 +    }
 +
 +    /**
 +     * Weak version of contains, does not check genome
 +     *
 +     * @param chr
 +     * @param start
 +     * @param end
 +     * @return
 +     */
 +    boolean contains(String chr, int start, int end) {
 +        return this.chr.equals(chr) && this.start <= start && this.end >= end;
++=======
+ 
+     boolean overlaps(String genomeId, String chr, int start, int end) {
+         return this.genomeId.equals(genomeId) && overlaps(chr, start, end);
++>>>>>>> upstream/1.5.56
      }
  
-     public int getTotalCount(int pos) {
-         int offset = pos - start;
-         if (offset < 0 || offset >= posA.length) {
-             if (log.isDebugEnabled()) {
-                 log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
+     public int getDepth() {
+         return alignmentRows.size();
+     }
+ 
+     static Alignment getFeatureContaining(List<Alignment> features, int right) {
+ 
+         int leftBounds = 0;
+         int rightBounds = features.size() - 1;
+         int idx = features.size() / 2;
+         int lastIdx = -1;
+ 
+         while (idx != lastIdx) {
+             lastIdx = idx;
+             Alignment f = features.get(idx);
+             if (f.contains(right)) {
+                 return f;
              }
-             return 0;
-         } else {
-             return posTotal[offset] + negTotal[offset];
  
-         }
-     }
+             if (f.getStart() > right) {
+                 rightBounds = idx;
+                 idx = (leftBounds + idx) / 2;
+             } else {
+                 leftBounds = idx;
+                 idx = (rightBounds + idx) / 2;
  
-     public int getNegTotal(int pos) {
-         int offset = pos - start;
-         if (offset < 0 || offset >= posA.length) {
-             if (log.isDebugEnabled()) {
-                 log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
              }
-             return 0;
-         } else {
-             return negTotal[offset];
  
          }
+         // Check the extremes
+         if (features.get(0).contains(right)) {
+             return features.get(0);
+         }
+ 
+         if (features.get(rightBounds).contains(right)) {
+             return features.get(rightBounds);
+         }
+ 
+         return null;
      }
  
-     public int getPosTotal(int pos) {
-         int offset = pos - start;
-         if (offset < 0 || offset >= posA.length) {
-             if (log.isDebugEnabled()) {
-                 log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
-             }
-             return 0;
-         } else {
-             return posTotal[offset];
+     /**
+      * The "packed" alignments in this interval
+      */
+     public List<Row> getAlignmentRows() {
+         return alignmentRows;
+     }
  
-         }
+     public void setAlignmentRows(List<Row> alignmentRows) {
+         this.alignmentRows = alignmentRows;
      }
  
-     public int getTotalQuality(int pos) {
-         int offset = pos - start;
-         if (offset < 0 || offset >= posA.length) {
-             if (log.isDebugEnabled()) {
-                 log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
-             }
-             return 0;
-         } else {
-             return totalQ[offset];
  
+     public void sortRows(AlignmentTrack.SortOption option) {
+         double center = ViewContext.getInstance().getCenter();
+         sortRows(option, center);
+     }
+ 
+ 
+     public void sortRows(AlignmentTrack.SortOption option, double location) {
+         if (alignmentRows == null) {
+             return;
+         }
+         for (AlignmentInterval.Row row : alignmentRows) {
+             if (option == AlignmentTrack.SortOption.NUCELOTIDE) {
+ 
+             }
+             row.updateScore(option, location, this);
          }
+ 
+         Collections.sort(alignmentRows, new Comparator<Row>() {
+ 
+             public int compare(AlignmentInterval.Row arg0, AlignmentInterval.Row arg1) {
+                 if (arg0.getScore() > arg1.getScore()) {
+                     return 1;
+                 } else if (arg0.getScore() > arg1.getScore()) {
+                     return -1;
+                 }
+                 return 0;
+             }
+         });
      }
  
++<<<<<<< HEAD
 +    public int getAvgQuality(int pos) {
 +        int count = getTotalCount(pos);
 +        return count == 0 ? 0 : getTotalQuality(pos) / count;
 +    }
++=======
++>>>>>>> upstream/1.5.56
  
      public byte getReference(int pos) {
          if (reference == null) {
@@@ -188,393 -165,113 +225,342 @@@
          }
      }
  
+ 
      public int getCount(int pos, byte b) {
-         int offset = pos - start;
-         if (offset < 0 || offset >= posA.length) {
-             if (log.isDebugEnabled()) {
-                 log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
+         for (CachingQueryReader.AlignmentCounts c : counts) {
+             if (pos >= c.getStart() && pos < c.getEnd()) {
+                 return c.getCount(pos, b);
              }
-             return 0;
-         } else {
-             switch (b) {
-                 case 'a':
-                 case 'A':
-                     return posA[offset] + negA[offset];
-                 case 't':
-                 case 'T':
-                     return posT[offset] + negT[offset];
-                 case 'c':
-                 case 'C':
-                     return posC[offset] + negC[offset];
-                 case 'g':
-                 case 'G':
-                     return posG[offset] + negG[offset];
-                 case 'n':
-                 case 'N':
-                     return posN[offset] + negN[offset];
-             }
-             log.error("Unknown nucleotide: " + b);
-             return 0;
          }
+         return 0;
      }
  
-     public int getNegCount(int pos, byte b) {
-         int offset = pos - start;
-         if (offset < 0 || offset >= posA.length) {
-             if (log.isDebugEnabled()) {
-                 log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
-             }
-             return 0;
-         } else {
-             switch (b) {
-                 case 'a':
-                 case 'A':
-                     return negA[offset];
-                 case 't':
-                 case 'T':
-                     return negT[offset];
-                 case 'c':
-                 case 'C':
-                     return negC[offset];
-                 case 'g':
-                 case 'G':
-                     return negG[offset];
-                 case 'n':
-                 case 'N':
-                     return negN[offset];
+     public int getMaxCount() {
+         return maxCount;
+     }
+ 
+     public int getTotalCount(int pos) {
+         for (CachingQueryReader.AlignmentCounts c : counts) {
+             if (pos >= c.getStart() && pos < c.getEnd()) {
+                 return c.getTotalCount(pos);
              }
-             log.error("Unknown nucleotide: " + b);
-             return 0;
          }
+         return 0;
      }
  
-     public int getPosCount(int pos, byte b) {
-         int offset = pos - start;
-         if (offset < 0 || offset >= posA.length) {
-             if (log.isDebugEnabled()) {
-                 log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
-             }
-             return 0;
-         } else {
-             switch (b) {
-                 case 'a':
-                 case 'A':
-                     return posA[offset];
-                 case 't':
-                 case 'T':
-                     return posT[offset];
-                 case 'c':
-                 case 'C':
-                     return posC[offset];
-                 case 'g':
-                 case 'G':
-                     return posG[offset];
-                 case 'n':
-                 case 'N':
-                     return posN[offset];
+     public int getNegCount(int pos, byte b) {
+         for (CachingQueryReader.AlignmentCounts c : counts) {
+             if (pos >= c.getStart() && pos < c.getEnd()) {
+                 return c.getNegCount(pos, b);
              }
-             log.error("Unknown nucleotide: " + b);
-             return 0;
          }
-     }
+         return 0;
+      }
  
-     public int getQuality(int pos, byte b) {
-         int offset = pos - start;
-         if (offset < 0 || offset >= posA.length) {
-             log.error("Position out of range: " + pos + " (valid range - " + start + "-" + end);
-             return 0;
-         } else {
-             switch (b) {
-                 case 'a':
-                 case 'A':
-                     return qA[offset];
-                 case 't':
-                 case 'T':
-                     return qT[offset];
-                 case 'c':
-                 case 'C':
-                     return qC[offset];
-                 case 'g':
-                 case 'G':
-                     return qG[offset];
-                 case 'n':
-                 case 'N':
-                     return qN[offset];
+     public int getPosCount(int pos, byte b) {
+         for (CachingQueryReader.AlignmentCounts c : counts) {
+             if (pos >= c.getStart() && pos < c.getEnd()) {
+                 return c.getPosCount(pos, b);
              }
-             log.error("Unknown nucleotide: " + posN);
-             return 0;
          }
-     }
+         return 0;
+      }
+ 
+     public static class Row {
+         int nextIdx;
+         private double score = 0;
+         List<Alignment> alignments;
+         private int start;
+         private int lastEnd;
+ 
+         public Row() {
+             nextIdx = 0;
+             this.alignments = new ArrayList(100);
+         }
  
++<<<<<<< HEAD
 +    public int getAvgQuality(int pos, byte b) {
 +        int count = getCount(pos, b);
 +        return count == 0 ? 0 : getQuality(pos, b) / count;
 +    }
 +
 +    private void incCounts(AlignmentBlock block, boolean isNegativeStrand) {
 +        int start = block.getStart();
 +        byte[] bases = block.getBases();
 +        if (bases != null) {
 +            for (int i = 0; i < bases.length; i++) {
 +                int pos = start + i;
 +                byte q = block.getQuality(i);
 +                // TODO -- handle "="
 +                byte n = bases[i];
 +                incCount(pos, n, q, isNegativeStrand);
++=======
+         public void addAlignment(Alignment alignment) {
+             if (alignments.isEmpty()) {
+                 this.start = alignment.getStart();
++>>>>>>> upstream/1.5.56
              }
+             alignments.add(alignment);
+             lastEnd = alignment.getEnd();
+ 
          }
-     }
  
++<<<<<<< HEAD
 +    // For alignments without blocks -- TODO refactor, this is ugly
 +
 +    void incCounts(Alignment alignment) {
 +        int start = alignment.getAlignmentStart();
 +        int end = alignment.getAlignmentEnd();
 +
 +        AlignmentBlock[] blocks = alignment.getAlignmentBlocks();
 +        if (blocks != null) {
 +            for (AlignmentBlock b : blocks) {
 +                // Don't count softclips
 +                if (!b.isSoftClipped())
 +                    incCounts(b, alignment.isNegativeStrand());
 +            }
 +        } else {
 +            for (int pos = start; pos < end; pos++) {
 +                byte q = 0;
 +                incCount(pos, (byte) 'n', q, alignment.isNegativeStrand());
++=======
+         public void updateScore(AlignmentTrack.SortOption option, double center, AlignmentInterval interval) {
+ 
+             int adjustedCenter = (int) center;
+             Alignment centerAlignment = getFeatureContaining(alignments, adjustedCenter);
+             if (centerAlignment == null) {
+                 setScore(Double.MAX_VALUE);
+             } else {
+                 switch (option) {
+                     case START:
+                         setScore(centerAlignment.getStart());
+                         break;
+                     case STRAND:
+                         setScore(centerAlignment.isNegativeStrand() ? -1 : 1);
+                         break;
+                     case NUCELOTIDE:
+                         byte base = centerAlignment.getBase(adjustedCenter);
+                         byte ref = interval.getReference(adjustedCenter);
+                         if (base == 'N' || base == 'n') {
+                             setScore(Integer.MAX_VALUE - 1);
+                         } else if (base == ref) {
+                             setScore(Integer.MAX_VALUE);
+                         } else {
+                             int count = interval.getCount(adjustedCenter, base);
+                             byte phred = centerAlignment.getPhred(adjustedCenter);
+                             float score = -(count + (phred / 100.0f));
+                             setScore(score);
+                         }
+                         break;
+                     case QUALITY:
+                         setScore(-centerAlignment.getMappingQuality());
+                         break;
+                     case SAMPLE:
+                         String sample = centerAlignment.getSample();
+                         score = sample == null ? 0 : sample.hashCode();
+                         setScore(score);
+                         break;
+                     case READ_GROUP:
+                         String readGroup = centerAlignment.getReadGroup();
+                         score = readGroup == null ? 0 : readGroup.hashCode();
+                         setScore(score);
+                         break;
+                 }
++>>>>>>> upstream/1.5.56
 +            }
 +        }
-     }
 +
-     void incCount(int pos, byte b, byte q, boolean isNegativeStrand) {
 +
-         int offset = pos - start;
-         if (offset > 0 && offset < posA.length) {
-             switch (b) {
-                 case 'a':
-                 case 'A':
-                     if (isNegativeStrand) {
-                         negA[offset] = negA[offset] + 1;
-                     } else {
-                         posA[offset] = posA[offset] + 1;
-                     }
-                     qA[offset] = qA[offset] + q;
-                     break;
-                 case 't':
-                 case 'T':
-                     if (isNegativeStrand) {
-                         negT[offset] = negT[offset] + 1;
-                     } else {
-                         posT[offset] = posT[offset] + 1;
-                     }
-                     qT[offset] = qT[offset] + q;
-                     break;
-                 case 'c':
-                 case 'C':
-                     if (isNegativeStrand) {
-                         negC[offset] = negC[offset] + 1;
-                     } else {
-                         posC[offset] = posC[offset] + 1;
-                     }
-                     qC[offset] = qC[offset] + q;
-                     break;
-                 case 'g':
-                 case 'G':
-                     if (isNegativeStrand) {
-                         negG[offset] = negG[offset] + 1;
-                     } else {
-                         posG[offset] = posG[offset] + 1;
-                     }
-                     qG[offset] = qG[offset] + q;
-                     break;
-                 case 'n':
-                 case 'N':
-                     if (isNegativeStrand) {
-                         negN[offset] = negN[offset] + 1;
-                     } else {
-                         posN[offset] = posN[offset] + 1;
-                     }
-                     qN[offset] = qN[offset] + q;
++        // Used for iterating over all alignments, e.g. for packing
 +
++        public Alignment nextAlignment() {
++            if (nextIdx < alignments.size()) {
++                Alignment tmp = alignments.get(nextIdx);
++                nextIdx++;
++                return tmp;
++            } else {
++                return null;
 +            }
-             if (isNegativeStrand) {
-                 negTotal[offset] = negTotal[offset] + 1;
++        }
++
++        public int getNextStartPos() {
++            if (nextIdx < alignments.size()) {
++                return alignments.get(nextIdx).getStart();
 +            } else {
-                 posTotal[offset] = posTotal[offset] + 1;
++                return Integer.MAX_VALUE;
 +            }
-             totalQ[offset] = totalQ[offset] + q;
++        }
 +
-             maxCount = Math.max(posTotal[offset] + negTotal[offset], maxCount);
++        public boolean hasNext() {
++            return nextIdx < alignments.size();
 +        }
-     }
 +
-     /**
-      * @return the start
-      */
-     public int getStart() {
-         return start;
-     }
++        public void resetIdx() {
++            nextIdx = 0;
++        }
 +
-     /**
-      * @return the end
-      */
-     public int getEnd() {
-         return end;
-     }
++        /**
++         * @return the score
++         */
++        public double getScore() {
++            return score;
++        }
 +
-     /**
-      * @return the totalQ
-      */
-     public int[] getTotalQ() {
-         return totalQ;
-     }
++        /**
++         * @param score the score to set
++         */
++        public void setScore(double score) {
++            this.score = score;
++        }
 +
-     /**
-      * @return the maxCount
-      */
-     public int getMaxCount() {
-         return maxCount;
++        public int getStart() {
++            return start;
++        }
++
++        public int getLastEnd() {
++            return lastEnd;
++        }
 +    }
 +
 +    static Alignment getFeatureContaining(List<Alignment> features, int right) {
 +
 +        int leftBounds = 0;
 +        int rightBounds = features.size() - 1;
 +        int idx = features.size() / 2;
 +        int lastIdx = -1;
 +
 +        while (idx != lastIdx) {
 +            lastIdx = idx;
 +            Alignment f = features.get(idx);
 +            if (f.contains(right)) {
 +                return f;
 +            }
 +
 +            if (f.getStart() > right) {
 +                rightBounds = idx;
 +                idx = (leftBounds + idx) / 2;
 +            } else {
 +                leftBounds = idx;
 +                idx = (rightBounds + idx) / 2;
 +
 +            }
 +
 +        }
 +        // Check the extremes
 +        if (features.get(0).contains(right)) {
 +            return features.get(0);
 +        }
 +
 +        if (features.get(rightBounds).contains(right)) {
 +            return features.get(rightBounds);
 +        }
 +
 +        return null;
 +    }
 +
 +    /**
 +     * The "packed" alignments in this interval
 +     */
 +    public List<Row> getAlignmentRows() {
 +        return alignmentRows;
 +    }
 +
 +    public void setAlignmentRows(List<Row> alignmentRows) {
 +        this.alignmentRows = alignmentRows;
 +    }
 +
 +    public void sortRows(AlignmentTrack.SortOption option) {
 +        if (alignmentRows == null) {
 +            return;
 +        }
 +
 +
 +        double center = ViewContext.getInstance().getCenter();
 +        for (AlignmentInterval.Row row : alignmentRows) {
 +            if (option == AlignmentTrack.SortOption.NUCELOTIDE) {
 +
 +            }
 +            row.updateScore(option, center, this);
 +        }
 +
 +        Collections.sort(alignmentRows, new Comparator<Row>() {
 +
 +            public int compare(AlignmentInterval.Row arg0, AlignmentInterval.Row arg1) {
 +                if (arg0.getScore() > arg1.getScore()) {
 +                    return 1;
 +                } else if (arg0.getScore() > arg1.getScore()) {
 +                    return -1;
 +                }
 +                return 0;
 +            }
 +        });
 +    }
 +
 +    public static class Row {
 +        int nextIdx;
 +        private double score = 0;
 +        List<Alignment> alignments;
 +        private int start;
 +        private int lastEnd;
 +
 +        public Row() {
 +            nextIdx = 0;
 +            this.alignments = new ArrayList(100);
 +        }
 +
 +        public void addAlignment(Alignment alignment) {
 +            if (alignments.isEmpty()) {
 +                this.start = alignment.getStart();
              }
 +            alignments.add(alignment);
 +            lastEnd = alignment.getEnd();
 +
          }
  
 +        public void updateScore(AlignmentTrack.SortOption option, double center, AlignmentInterval interval) {
 +
 +            int adjustedCenter = (int) center;
 +            Alignment centerAlignment = getFeatureContaining(alignments, adjustedCenter);
 +            if (centerAlignment == null) {
 +                setScore(Double.MAX_VALUE);
 +            } else {
 +                switch (option) {
 +                    case START:
 +                        setScore(centerAlignment.getStart());
 +                        break;
 +                    case STRAND:
 +                        setScore(centerAlignment.isNegativeStrand() ? -1 : 1);
 +                        break;
 +                    case NUCELOTIDE:
 +                        byte base = centerAlignment.getBase(adjustedCenter);
 +                        byte ref = interval.getReference(adjustedCenter);
 +                        if (base == 'N' || base == 'n') {
 +                            setScore(Integer.MAX_VALUE - 1);
 +                        } else if (base == ref) {
 +                            setScore(Integer.MAX_VALUE);
 +                        } else {
 +                            int count = interval.getCount(adjustedCenter, base);
 +                            byte phred = centerAlignment.getPhred(adjustedCenter);
 +                            float score = -(count + (phred / 100.0f));
 +                            setScore(score);
 +                        }
 +                        break;
 +                    case QUALITY:
 +                        setScore(-centerAlignment.getMappingQuality());
 +                        break;
 +                    case SAMPLE:
 +                        String sample = centerAlignment.getSample();
 +                        score = sample == null ? 0 : sample.hashCode();
 +                        setScore(score);
 +                        break;
 +                    case READ_GROUP:
 +                        String readGroup = centerAlignment.getReadGroup();
 +                        score = readGroup == null ? 0 : readGroup.hashCode();
 +                        setScore(score);
 +                        break;
 +                }
 +            }
 +        }
  
          // Used for iterating over all alignments, e.g. for packing
  
diff --combined src/org/broad/igv/sam/AlignmentLoader.java
index 5e4c05a,2006b89..6944b59
--- a/src/org/broad/igv/sam/AlignmentLoader.java
+++ b/src/org/broad/igv/sam/AlignmentLoader.java
@@@ -72,22 -72,15 +72,27 @@@ public class AlignmentLoader 
       * Allocates each alignment to the rows such that there is no overlap.
       *
       * @param iter             Iterator wrapping the collection of alignments
-      * @param showDuplicates   indicates alignments marked "duplicate" are shown
-      * @param qualityThreshold alignment mapQ threshold.  Alignments with lower values are not shown
+ 
       * @param maxLevels        the maximum number of levels (rows) to create
       */
++<<<<<<< HEAD:src/org/broad/igv/sam/AlignmentLoader.java
 +    public static List<AlignmentInterval.Row> loadAndPackAlignments(
++=======
+     public static List<AlignmentInterval.Row> packAlignments(
++>>>>>>> upstream/1.5.56:src/org/broad/igv/sam/AlignmentLoader.java
              CloseableIterator<Alignment> iter,
              int maxLevels,
              int end) {
  
++<<<<<<< HEAD:src/org/broad/igv/sam/AlignmentLoader.java
 +        boolean filterFailedReads = PreferenceManager.getInstance().getSAMPreferences().isFilterFailedReads();
 +
 +        // TODO -- the filter should be generalized, and passed in as a parameter
 +        ReadGroupFilter filter = ReadGroupFilter.getFilter();
 +
++=======
+  
++>>>>>>> upstream/1.5.56:src/org/broad/igv/sam/AlignmentLoader.java
          List<Row> alignmentRows = new ArrayList(maxLevels);
          if (iter == null || !iter.hasNext()) {
              return alignmentRows;
@@@ -124,17 -117,14 +129,29 @@@
  
          while (iter.hasNext()) {
              Alignment alignment = iter.next();
++<<<<<<< HEAD:src/org/broad/igv/sam/AlignmentLoader.java
 +
 +            // Store unmapped reads in a hache, to be used later to fetch sequence
 +            if (!alignment.isMapped()) {
 +                unmappedReads.put(alignment.getReadName(), alignment);
 +
 +            } else if ((showDuplicates || !alignment.isDuplicate()) &&
 +                    (!filterFailedReads || !alignment.isVendorFailedRead()) && 
 +                    alignment.getMappingQuality() >= qualityThreshold &&
 +                    (filter == null || filter.filterAlignment(alignment) == false)) {
++=======
++>>>>>>> upstream/1.5.56:src/org/broad/igv/sam/AlignmentLoader.java
+ 
+             // Store unmapped reads in a hache, to be used later to fetch sequence
+             if (!alignment.isMapped()) {
+                 unmappedReads.put(alignment.getReadName(), alignment);
  
+             } else  {
  
++<<<<<<< HEAD:src/org/broad/igv/sam/AlignmentLoader.java
++=======
+ 
++>>>>>>> upstream/1.5.56:src/org/broad/igv/sam/AlignmentLoader.java
                  // We can get negative buckets if softclipping is on as the alignments are only approximately
                  // sorted.  Throw all alignments < start in the first bucket.
                  int bucketNumber = Math.max(0, alignment.getStart() - start);
@@@ -148,29 -138,29 +165,51 @@@
                      totalCount++;
                  } else {
                      log.debug("Alignment out of bounds: " + alignment.getStart() + " (> " + end);
++<<<<<<< HEAD:src/org/broad/igv/sam/AlignmentLoader.java
+                 }
+ 
+                 if (alignment.getMate() != null && !alignment.getMate().isMapped()) {
+                     matesUnmapped.add(alignment);
++=======
++>>>>>>> upstream/1.5.56:src/org/broad/igv/sam/AlignmentLoader.java
                  }
 +
 +                if (alignment.getMate() != null && !alignment.getMate().isMapped()) {
 +                    matesUnmapped.add(alignment);
 +                }
 +            }
 +        }
 +
 +        // Get unmapped mate sequences
 +        for (Alignment a : matesUnmapped) {
 +            Alignment mate = unmappedReads.get(a.getReadName());
 +            if (mate != null) {
 +                a.setMateSequence(mate.getReadSequence());
              }
          }
  
+         // Get unmapped mate sequences
+         for (Alignment a : matesUnmapped) {
+             Alignment mate = unmappedReads.get(a.getReadName());
+             if (mate != null) {
+                 a.setMateSequence(mate.getReadSequence());
+             }
+         }
+ 
++<<<<<<< HEAD:src/org/broad/igv/sam/AlignmentLoader.java
  
++=======
++>>>>>>> upstream/1.5.56:src/org/broad/igv/sam/AlignmentLoader.java
          // Allocate alignments to rows
          long t0 = System.currentTimeMillis();
          int allocatedCount = 0;
          int nextStart = start;
          AlignmentInterval.Row currentRow = new Row();
++<<<<<<< HEAD:src/org/broad/igv/sam/AlignmentLoader.java
 +        while (allocatedCount < totalCount && alignmentRows.size() < maxLevels) {
++=======
+         while (allocatedCount < totalCount) { // && alignmentRows.size() < maxLevels) {
++>>>>>>> upstream/1.5.56:src/org/broad/igv/sam/AlignmentLoader.java
  
              // Loop through alignments until we reach the end of the interval
              while (nextStart <= end) {
@@@ -201,6 -191,10 +240,10 @@@
              if (currentRow.alignments.size() > 0) {
                  alignmentRows.add(currentRow);
              }
+ 
+             if(alignmentRows.size() >= maxLevels) {
+                 break;
+             }
              currentRow = new Row();
              nextStart = start;
          }
@@@ -210,7 -204,7 +253,11 @@@
          }
  
          // Add the last row
++<<<<<<< HEAD:src/org/broad/igv/sam/AlignmentLoader.java
 +        if (currentRow.alignments.size() > 0) {
++=======
+         if (currentRow.alignments.size() > 0 && alignmentRows.size() < maxLevels) {
++>>>>>>> upstream/1.5.56:src/org/broad/igv/sam/AlignmentLoader.java
              alignmentRows.add(currentRow);
          }
  
diff --combined src/org/broad/igv/sam/AlignmentRenderer.java
index ff963b9,8f32048..17f95d9
--- a/src/org/broad/igv/sam/AlignmentRenderer.java
+++ b/src/org/broad/igv/sam/AlignmentRenderer.java
@@@ -37,7 -37,8 +37,12 @@@ import java.util.Map
   */
  public class AlignmentRenderer implements FeatureRenderer {
  
++<<<<<<< HEAD
 +    public static Map<Character, Color> nucleotideColors;
++=======
+     private static Map<Character, Color> nucleotideColors;
+ 
++>>>>>>> upstream/1.5.56
      // Static because all alignment tracks are in color space, or none are
      public static boolean colorSpace;
  
@@@ -51,6 -52,7 +56,10 @@@
      private static Color grey2 = new Color(165, 165, 165);
      public static Color grey1 = new Color(200, 200, 200);
  
++<<<<<<< HEAD
++=======
+     private static HashMap<String, Color> readGroupColors = new HashMap();
++>>>>>>> upstream/1.5.56
  
      static Font font = FontManager.getScalableFont(10);
      private ViewContext viewContext;
@@@ -79,9 -81,6 +88,6 @@@
      }
  
  
-     /**
-      * Constructs ...
-      */
      public AlignmentRenderer() {
          this.viewContext = ViewContext.getInstance();
          this.prefs = PreferenceManager.getInstance().getSAMPreferences();
@@@ -91,6 -90,14 +97,14 @@@
  
      }
  
+ 
+     public static Map<Character, Color> getNucleotideColors() {
+         if (nucleotideColors == null) {
+             initColorMap();
+         }
+         return nucleotideColors;
+     }
+ 
      /**
       * Render a list of alignments in the given rectangle.
       */
@@@ -116,8 -123,14 +130,19 @@@
                  double pixelStart = ((alignment.getStart() - origin) / locScale);
                  double pixelEnd = ((alignment.getEnd() - origin) / locScale);
  
++<<<<<<< HEAD
 +                // If the any part of the feature fits in the track rectangle draw  it
 +
++=======
+                 // If the any part of the feature fits in the track rectangle draw it.  If we've passed the end of
+                 // the rect break
+                 if (pixelEnd < rect.getX()) {
+                     continue;
+                 }
+                 else if(pixelStart > (rect.getMaxX() + 100)) {
+                     break;
+                 }
++>>>>>>> upstream/1.5.56
  
                  if ((pixelEnd >= rect.getX()) && (pixelStart <= rect.getMaxX())) {
                      Color alignmentColor = getAlignmentColor(alignment, locScale, viewContext.getCenter(), renderOptions);
@@@ -140,7 -153,7 +165,7 @@@
              }
  
              // Draw posA border around the center base
-             if (locScale < 5 && renderOptions.shadeCenters) {
+             if (locScale < 5 && renderOptions.isShadeCenters()) {
                  // Calculate center lines
                  double center = (int) (viewContext.getCenter() - origin);
                  int centerLeftP = (int) (center / locScale);
@@@ -240,7 -253,7 +265,7 @@@
          AlignmentBlock[] blocks = alignment.getAlignmentBlocks();
  
          if (blocks == null) {
-             drawSimpleAlignment(alignment, rect, g, context, renderOptions.flagUnmappedPairs);
+             drawSimpleAlignment(alignment, rect, g, context, renderOptions.isFlagUnmappedPairs());
              return;
          }
  
@@@ -269,97 -282,105 +294,153 @@@
                  w -= 2;
              }
  
++<<<<<<< HEAD
 +
 +            if (w <= 10 || h <= 10 || aBlock != terminalBlock) {
 +                g.fillRect(x, y, w, h);
 +                if (isZeroQuality) {
 +                    greyGraphics.drawRect(x, y, w - 1, h);
 +                }
++=======
+             // If block is out of view skip
+             if (x + w >= rect.x && x <= rect.getMaxX()) {
+                 if (w <= 10 || h <= 10 || aBlock != terminalBlock) {
+                     g.fillRect(x, y, w, h);
+                     if (isZeroQuality) {
+                         greyGraphics.drawRect(x, y, w - 1, h);
+                     }
++>>>>>>> upstream/1.5.56
  
-                 if (renderOptions.flagUnmappedPairs && alignment.isPaired() && !alignment.getMate().isMapped()) {
-                     Graphics2D cRed = context.getGraphic2DForColor(Color.red);
-                     cRed.drawRect(x, y, w, h);
-                 }
+                     if (renderOptions.isFlagUnmappedPairs() && alignment.isPaired() && !alignment.getMate().isMapped()) {
+                         Graphics2D cRed = context.getGraphic2DForColor(Color.red);
+                         cRed.drawRect(x, y, w, h);
+                     }
  
-                 if (selectedReadNames.containsKey(alignment.getReadName())) {
-                     Color c = selectedReadNames.get(alignment.getReadName());
-                     if (c == null) {
-                         c = Color.blue;
+                     if (selectedReadNames.containsKey(alignment.getReadName())) {
+                         Color c = selectedReadNames.get(alignment.getReadName());
+                         if (c == null) {
+                             c = Color.blue;
+                         }
+                         Graphics2D cBlue = context.getGraphic2DForColor(c);
+                         Stroke s = cBlue.getStroke();
+                         cBlue.setStroke(thickStroke);
+                         cBlue.drawRect(x, y, w, h);
+                         cBlue.setStroke(s);
                      }
-                     Graphics2D cBlue = context.getGraphic2DForColor(c);
-                     Stroke s = cBlue.getStroke();
-                     cBlue.setStroke(thickStroke);
-                     cBlue.drawRect(x, y, w, h);
-                     cBlue.setStroke(s);
-                 }
  
++<<<<<<< HEAD
 +            } else {
 +                int arrowLength = Math.min(5, w / 6);
 +
 +                // Don't draw off edge of clipping rect
 +                if (x < rect.x && (x + w) > (rect.x + rect.width)) {
 +                    x = rect.x;
 +                    w = rect.width;
 +                    arrowLength = 0;
 +                } else if (x < rect.x) {
 +                    int delta = rect.x - x;
 +                    x = rect.x;
 +                    w -= delta;
 +                    if (alignment.isNegativeStrand()) {
 +                        arrowLength = 0;
 +                    }
 +                } else if ((x + w) > (rect.x + rect.width)) {
 +                    w -= ((x + w) - (rect.x + rect.width));
 +                    if (!alignment.isNegativeStrand()) {
 +                        arrowLength = 0;
 +                    }
 +                }
 +
 +                int[] xPoly = null;
 +                int[] yPoly = {y, y, y + h / 2, y + h, y + h};
 +
 +                if (alignment.isNegativeStrand()) {
 +                    xPoly = new int[]{x + w, x, x - arrowLength, x, x + w};
 +                } else {
 +                    xPoly = new int[]{x, x + w, x + w + arrowLength, x + w, x};
 +                }
 +                g.fillPolygon(xPoly, yPoly, xPoly.length);
 +
 +
 +                if (isZeroQuality) {
 +                    greyGraphics.drawPolygon(xPoly, yPoly, xPoly.length);
 +                }
++=======
+                 } else {
+                     int arrowLength = Math.min(5, w / 6);
  
-                 if (renderOptions.flagUnmappedPairs && alignment.isPaired() && !alignment.getMate().isMapped()) {
-                     Graphics2D cRed = context.getGraphic2DForColor(Color.red);
-                     cRed.drawPolygon(xPoly, yPoly, xPoly.length);
-                 }
+                     // Don't draw off edge of clipping rect
+                     if (x < rect.x && (x + w) > (rect.x + rect.width)) {
+                         x = rect.x;
+                         w = rect.width;
+                         arrowLength = 0;
+                     } else if (x < rect.x) {
+                         int delta = rect.x - x;
+                         x = rect.x;
+                         w -= delta;
+                         if (alignment.isNegativeStrand()) {
+                             arrowLength = 0;
+                         }
+                     } else if ((x + w) > (rect.x + rect.width)) {
+                         w -= ((x + w) - (rect.x + rect.width));
+                         if (!alignment.isNegativeStrand()) {
+                             arrowLength = 0;
+                         }
+                     }
++>>>>>>> upstream/1.5.56
  
-                 if (selectedReadNames.containsKey(alignment.getReadName())) {
-                     Color c = selectedReadNames.get(alignment.getReadName());
-                     if (c == null) {
-                         c = Color.blue;
+                     int[] xPoly = null;
+                     int[] yPoly = {y, y, y + h / 2, y + h, y + h};
+ 
+                     if (alignment.isNegativeStrand()) {
+                         xPoly = new int[]{x + w, x, x - arrowLength, x, x + w};
+                     } else {
+                         xPoly = new int[]{x, x + w, x + w + arrowLength, x + w, x};
+                     }
+                     g.fillPolygon(xPoly, yPoly, xPoly.length);
+ 
+ 
+                     if (isZeroQuality) {
+                         greyGraphics.drawPolygon(xPoly, yPoly, xPoly.length);
+                     }
+ 
+                 if (renderOptions.isFlagUnmappedPairs() && alignment.isPaired() && !alignment.getMate().isMapped()) {
+                         Graphics2D cRed = context.getGraphic2DForColor(Color.red);
+                         cRed.drawPolygon(xPoly, yPoly, xPoly.length);
+                     }
+ 
+                     if (selectedReadNames.containsKey(alignment.getReadName())) {
+                         Color c = selectedReadNames.get(alignment.getReadName());
+                         if (c == null) {
+                             c = Color.blue;
+                         }
+                         Graphics2D cBlue = context.getGraphic2DForColor(c);
+                         Stroke s = cBlue.getStroke();
+                         cBlue.setStroke(thickStroke);
+                         cBlue.drawPolygon(xPoly, yPoly, xPoly.length);
+                         cBlue.setStroke(s);
                      }
                  }
              }
  
-             if (lastBlockEnd > Integer.MIN_VALUE) {
+ 
+             if (locScale < 5) {
+                 drawBases(context, rect, aBlock, alignmentColor, renderOptions.isShadeBases(), renderOptions.isShowAllBases());
+             }
+ 
+             // Draw connecting lines between blocks, if in view
+             if (lastBlockEnd > Integer.MIN_VALUE && x > rect.x) {
                  Graphics2D gLine;
                  Stroke stroke;
                  int gapIdx = blockNumber - 1;
-                 Color gapLineColor = deletionColor;
                  if (gapTypes != null && gapIdx < gapTypes.length && gapTypes[gapIdx] == SamAlignment.SKIPPED_REGION) {
                      gLine = context.getGraphic2DForColor(skippedColor);
                      stroke = gLine.getStroke();
                  } else {
-                     gLine = context.getGraphic2DForColor(gapLineColor);
+                     gLine = context.getGraphic2DForColor(deletionColor);
                      stroke = gLine.getStroke();
-                     gLine.setStroke(dashedStroke);
+                     //gLine.setStroke(dashedStroke);
+                     gLine.setStroke(thickStroke);
                  }
  
                  int startX = Math.max(rect.x, lastBlockEnd);
@@@ -370,9 -391,11 +451,11 @@@
              }
              lastBlockEnd = x + w;
  
-             if (locScale < 5) {
-                 drawBases(context, rect, aBlock, alignmentColor, renderOptions.shadeBases, renderOptions.showAllBases);
+             // Next block cannot start before lastBlockEnd.  If its out of view we are done.
+             if(lastBlockEnd > rect.getMaxX()) {
+                 break;
              }
+ 
          }
  
          // Render insertions if locScale ~ 0.25 (base level)
@@@ -434,11 -457,11 +517,19 @@@
                  // bases are considered mismatched by definition
                  boolean misMatch =
                          isSoftClipped ||
++<<<<<<< HEAD
 +                        (read[idx] != '=' &&
 +                                reference != null &&
 +                                idx < reference.length &&
 +                                reference[idx] != 0 &&
 +                                reference[idx] != read[idx]);
++=======
+                                 (read[idx] != '=' &&
+                                         reference != null &&
+                                         idx < reference.length &&
+                                         reference[idx] != 0 &&
+                                         reference[idx] != read[idx]);
++>>>>>>> upstream/1.5.56
  
                  if (misMatch || showAllBases) {
                      char c = (char) read[loc - start];
@@@ -561,14 -584,16 +652,25 @@@
          // Set color used to draw the feature.  Highlight features that intersect the
          // center line.  Also restorePersistentState row "score" if alignment intersects center line
  
++<<<<<<< HEAD
 +        Color c = grey1;
 +        switch (renderOptions.colorOption) {
++=======
+         Color c = alignment.getDefaultColor();
+ 
+ 
+         switch (renderOptions.getColorOption()) {
++>>>>>>> upstream/1.5.56
              case INSERT_SIZE:
                  if (alignment.isPaired() && alignment.getMate().isMapped()) {
                      boolean sameChr = alignment.getMate().mateChr.equals(alignment.getChr());
                      if (sameChr) {
                          int readDistance = Math.abs(alignment.getInferredInsertSize());
++<<<<<<< HEAD
 +                        if (readDistance > renderOptions.insertSizeThreshold) {
++=======
+                         if (readDistance > renderOptions.getInsertSizeThreshold()) {
++>>>>>>> upstream/1.5.56
                              c = ChromosomeColors.getColor(alignment.getMate().mateChr);
                              //c = getDistanceColor(readDistance);
                          }
@@@ -597,12 -622,32 +699,41 @@@
                      c = posStrandColor;
                  }
                  break;
++<<<<<<< HEAD
 +            default:
 +                if (renderOptions.shadeCenters && center >= alignment.getStart() && center <= alignment.getEnd()) {
 +                    if (locScale < 1) {
 +                        c = grey2;
 +                    }
 +                }
++=======
+             case READ_GROUP:
+                 String rg = alignment.getReadGroup();
+                 if (rg != null) {
+                     c = readGroupColors.get(rg);
+                     if (c == null) {
+                         c = ColorUtilities.randomColor(readGroupColors.size() + 1);
+                         readGroupColors.put(rg, c);
+                     }
+                 }
+                 break;
+             case SAMPLE:
+                 String sample = alignment.getSample();
+                 if (sample != null) {
+                     c = readGroupColors.get(sample);
+                     if (c == null) {
+                         c = ColorUtilities.randomColor(readGroupColors.size() + 1);
+                         readGroupColors.put(sample, c);
+                     }
+                 }
+                 break;
+             default:
+                 if (renderOptions.isShadeCenters() && center >= alignment.getStart() && center <= alignment.getEnd()) {
+                     if (locScale < 1) {
+                         c = grey2;
+                     }
+                 }
++>>>>>>> upstream/1.5.56
          }
  
          if (alignment.getMappingQuality() == 0) {
@@@ -636,6 -681,6 +767,37 @@@
  
          return c == null ? grey1 : c;
  
++<<<<<<< HEAD
++    }
++
++    private static final Color LR_COLOR = grey1; // "Normal" alignment color
++    private static final Color RL_COLOR = new Color(0, 150, 0);
++    private static final Color RR_COLOR = new Color(0, 0, 150);
++    private static final Color LL_COLOR = new Color(0, 150, 150);
++
++    Map<String, Color> illuminaScheme;
++    Map<String, Color> solidScheme;
++
++    private Map<String, Color> getIlluminaScheme() {
++        if (illuminaScheme == null) {
++            illuminaScheme = new HashMap();
++            //LR
++            illuminaScheme.put("F1R2", LR_COLOR);
++            illuminaScheme.put("F2R1", LR_COLOR);
++            //LL
++            illuminaScheme.put("F1F2", LL_COLOR);
++            illuminaScheme.put("F2F1", LL_COLOR);
++            //RR
++            illuminaScheme.put("R1R2", RR_COLOR);
++            illuminaScheme.put("R2R1", RR_COLOR);
++            //RL
++            illuminaScheme.put("R1F2", RL_COLOR);
++            illuminaScheme.put("R2F1", RL_COLOR);
++        }
++        return illuminaScheme;
++    }
++
++=======
      }
  
      private static final Color LR_COLOR = grey1; // "Normal" alignment color
@@@ -652,19 -697,27 +814,28 @@@
              //LR
              illuminaScheme.put("F1R2", LR_COLOR);
              illuminaScheme.put("F2R1", LR_COLOR);
+             illuminaScheme.put("F R ", LR_COLOR);
+             illuminaScheme.put("FR", LR_COLOR);
              //LL
              illuminaScheme.put("F1F2", LL_COLOR);
              illuminaScheme.put("F2F1", LL_COLOR);
+             illuminaScheme.put("F F ", LL_COLOR);
+             illuminaScheme.put("FF", LL_COLOR);
              //RR
              illuminaScheme.put("R1R2", RR_COLOR);
              illuminaScheme.put("R2R1", RR_COLOR);
+             illuminaScheme.put("R R ", RR_COLOR);
+             illuminaScheme.put("RR", RR_COLOR);
              //RL
              illuminaScheme.put("R1F2", RL_COLOR);
              illuminaScheme.put("R2F1", RL_COLOR);
+             illuminaScheme.put("R F ", RL_COLOR);
+             illuminaScheme.put("RF", RR_COLOR);
          }
          return illuminaScheme;
      }
  
++>>>>>>> upstream/1.5.56
  
      private Map<String, Color> getSolidScheme() {
          if (solidScheme == null) {
@@@ -685,5 -738,4 +856,8 @@@
          return solidScheme;
      }
  
++<<<<<<< HEAD
 +
++=======
++>>>>>>> upstream/1.5.56
  }
diff --combined src/org/broad/igv/sam/AlignmentTrack.java
index 0c59ff4,a5fe7fb..b33902e
--- a/src/org/broad/igv/sam/AlignmentTrack.java
+++ b/src/org/broad/igv/sam/AlignmentTrack.java
@@@ -55,49 -55,51 +55,86 @@@ import java.util.List
   */
  public class AlignmentTrack extends AbstractTrack implements DragListener {
  
+     public enum SortOption {
+         START, STRAND, NUCELOTIDE, QUALITY, SAMPLE, READ_GROUP
+     }
+ 
+     public enum ColorOption {
+         INSERT_SIZE, READ_STRAND, FRAGMENT_STRAND, PAIR_ORIENTATION, SAMPLE, READ_GROUP;
+     }
+ 
      public static final int MIN_ALIGNMENT_SPACING = 10;
      static final ColorOption DEFAULT_COLOR_OPTION = ColorOption.INSERT_SIZE;
      static final boolean DEFAULT_SHOWALLBASES = false;
  
      private static ColorOption colorByOption = null;
++<<<<<<< HEAD
 +
 +    SequenceTrack sequenceTrack;
++=======
++>>>>>>> upstream/1.5.56
  
+     private SequenceTrack sequenceTrack;
  
      private CoverageTrack coverageTrack;
  
-     RenderOptions renderOptions;
+     private RenderOptions renderOptions;
  
      private static Logger log = Logger.getLogger(AlignmentTrack.class);
      private int expandedHeight = 14;
      private int collapsedHeight = 2;
++<<<<<<< HEAD
 +    FeatureRenderer renderer;
 +    double minVisibleScale = 25;
 +    Rectangle renderedRect;
 +    HashMap<String, Color> selectedReadNames = new HashMap();
++=======
+     private FeatureRenderer renderer;
+     private double minVisibleScale = 25;
+     private Rectangle renderedRect;
++>>>>>>> upstream/1.5.56
      private int minHeight = 100;
-     AlignmentDataManager dataManager;
+     private AlignmentDataManager dataManager;
  
++<<<<<<< HEAD
 +    public CoverageTrack getCoverageTrack() {
 +        return coverageTrack;
 +    }
 +
 +
 +    public enum SortOption {
 +        START, STRAND, NUCELOTIDE, QUALITY, SAMPLE, READ_GROUP
 +    }
 +
 +    public enum ColorOption {
 +        INSERT_SIZE, READ_STRAND, FRAGMENT_STRAND, PAIR_ORIENTATION;
 +    }
 +
 +    public static class RenderOptions {
 +        boolean shadeBases;
 +        boolean shadeCenters;
 +        boolean flagUnmappedPairs;
 +        boolean showAllBases;
 +        int insertSizeThreshold;
 +        ColorOption colorOption;
++=======
+     private HashMap<String, Color> selectedReadNames = new HashMap();
+     int selectionColorIndex = 0;
+ 
+     public CoverageTrack getCoverageTrack() {
+         return coverageTrack;
+     }
+ 
+ 
+     public static class RenderOptions {
+         private boolean changedByUser = false;
+         private boolean shadeBases;
+         private boolean shadeCenters;
+         private boolean flagUnmappedPairs;
+         private boolean showAllBases;
+         private int insertSizeThreshold;
+         private ColorOption colorOption;
++>>>>>>> upstream/1.5.56
  
          RenderOptions() {
              PreferenceManager.SAMPreferences prefs = PreferenceManager.getInstance().getSAMPreferences();
@@@ -118,22 -120,22 +155,41 @@@
          public Map<String, String> getPersistentState() {
              Map<String, String> attributes = new HashMap();
              PreferenceManager.SAMPreferences prefs = PreferenceManager.getInstance().getSAMPreferences();
++<<<<<<< HEAD
 +            if (shadeBases != prefs.isShadeBaseQuality()) {
 +                attributes.put("shadeBases", String.valueOf(shadeBases));
 +            }
 +            if (shadeCenters != prefs.isShadeCenter()) {
 +                attributes.put("shadeCenters", String.valueOf(shadeBases));
 +            }
 +            if (flagUnmappedPairs != prefs.isFlagUnmappedPair()) {
 +                attributes.put("flagUnmappedPairs", String.valueOf(flagUnmappedPairs));
 +            }
 +            if (insertSizeThreshold != prefs.getInsertSizeThreshold()) {
 +                attributes.put("insertSizeThreshold", String.valueOf(insertSizeThreshold));
 +            }
 +            if (showAllBases != DEFAULT_SHOWALLBASES) {
 +                attributes.put("showAllBases", String.valueOf(showAllBases));
 +            }
 +            if (colorOption != DEFAULT_COLOR_OPTION) {
++=======
+             if (isShadeBases() != prefs.isShadeBaseQuality()) {
+                 attributes.put("shadeBases", String.valueOf(isShadeBases()));
+             }
+             if (isShadeCenters() != prefs.isShadeCenter()) {
+                 attributes.put("shadeCenters", String.valueOf(isShadeBases()));
+             }
+             if (isFlagUnmappedPairs() != prefs.isFlagUnmappedPair()) {
+                 attributes.put("flagUnmappedPairs", String.valueOf(isFlagUnmappedPairs()));
+             }
+             if (getInsertSizeThreshold() != prefs.getInsertSizeThreshold()) {
+                 attributes.put("insertSizeThreshold", String.valueOf(getInsertSizeThreshold()));
+             }
+             if (isShowAllBases() != DEFAULT_SHOWALLBASES) {
+                 attributes.put("showAllBases", String.valueOf(isShowAllBases()));
+             }
+             if (getColorOption() != DEFAULT_COLOR_OPTION) {
++>>>>>>> upstream/1.5.56
                  attributes.put("colorOption", colorByOption.toString());
              }
  
@@@ -150,40 -152,93 +206,119 @@@
              String value;
              value = attributes.get("insertSizeThreshold");
              if (value != null) {
++<<<<<<< HEAD
 +                insertSizeThreshold = Integer.parseInt(value);
 +            }
 +            value = attributes.get("shadeBases");
 +            if (value != null) {
 +                shadeBases = Boolean.parseBoolean(value);
 +            }
 +            value = attributes.get("shadeCenters");
 +            if (value != null) {
 +                shadeCenters = Boolean.parseBoolean(value);
 +            }
 +            value = attributes.get("flagUnmappedPairs");
 +            if (value != null) {
 +                flagUnmappedPairs = Boolean.parseBoolean(value);
 +            }
 +            value = attributes.get("showAllBases");
 +            if (value != null) {
 +                showAllBases = Boolean.parseBoolean(value);
 +            }
 +            value = attributes.get("colorOption");
 +            if (value != null) {
 +                colorOption = ColorOption.valueOf(value);
 +                colorByOption = colorOption;
 +            }
++=======
+                 setInsertSizeThreshold(Integer.parseInt(value));
+             }
+             value = attributes.get("shadeBases");
+             if (value != null) {
+                 setShadeBases(Boolean.parseBoolean(value));
+             }
+             value = attributes.get("shadeCenters");
+             if (value != null) {
+                 setShadeCenters(Boolean.parseBoolean(value));
+             }
+             value = attributes.get("flagUnmappedPairs");
+             if (value != null) {
+                 setFlagUnmappedPairs(Boolean.parseBoolean(value));
+             }
+             value = attributes.get("showAllBases");
+             if (value != null) {
+                 setShowAllBases(Boolean.parseBoolean(value));
+             }
+             value = attributes.get("colorOption");
+             if (value != null) {
+                 setColorOption(ColorOption.valueOf(value));
+                 colorByOption = getColorOption();
+             }
+         }
+ 
+         public boolean isShadeBases() {
+             return shadeBases;
+         }
+ 
+         public void setShadeBases(boolean shadeBases) {
+             changedByUser = true;
+             this.shadeBases = shadeBases;
+         }
+ 
+         public boolean isShadeCenters() {
+             return shadeCenters;
+         }
+ 
+         public void setShadeCenters(boolean shadeCenters) {
+             changedByUser = true;
+             this.shadeCenters = shadeCenters;
+         }
+ 
+         public boolean isFlagUnmappedPairs() {
+             return flagUnmappedPairs;
+         }
+ 
+         public void setFlagUnmappedPairs(boolean flagUnmappedPairs) {
+             changedByUser = true;
+             this.flagUnmappedPairs = flagUnmappedPairs;
+         }
+ 
+         public boolean isShowAllBases() {
+             return showAllBases;
+         }
+ 
+         public void setShowAllBases(boolean showAllBases) {
+             changedByUser = true;
+             this.showAllBases = showAllBases;
+         }
+ 
+         public int getInsertSizeThreshold() {
+             return insertSizeThreshold;
+         }
+ 
+         public void setInsertSizeThreshold(int insertSizeThreshold) {
+             changedByUser = true;
+             this.insertSizeThreshold = insertSizeThreshold;
+         }
+ 
+         public ColorOption getColorOption() {
+             return colorOption;
++>>>>>>> upstream/1.5.56
          }
  
+         public void setColorOption(ColorOption colorOption) {
+             changedByUser = true;
+             this.colorOption = colorOption;
+         }
      }
  
  
      public AlignmentTrack(ResourceLocator locator, AlignmentDataManager dataManager) {
          super(locator);
  
-         //AlignmentQueryReader reader = SamQueryReaderFactory.getReader(locator);
          this.dataManager = dataManager;
  
+ 
          float maxRange = PreferenceManager.getInstance().getSAMPreferences().getMaxVisibleRange();
          minVisibleScale = (maxRange * 1000) / 700;
  
@@@ -246,8 -301,6 +381,6 @@@
      }
  
      private int getNLevels() {
- 
- 
          return (dataManager.getAlignmentRows() == null ? 1 : dataManager.getAlignmentRows().size());
      }
  
@@@ -291,26 -344,13 +424,33 @@@
              final String chr = context.getChr();
              final int start = (int) context.getOrigin();
              final int end = (int) context.getEndLocation() + 1;
++<<<<<<< HEAD
++=======
+ 
++>>>>>>> upstream/1.5.56
              List<AlignmentInterval.Row> tmp = dataManager.getAlignmentRows(genomeId, chr, start, end);
  
              if (tmp == null) {
                  return;
              }
  
++<<<<<<< HEAD
 +            // Check currently loaded interval.  If out of range null it.  This probably isn't the best place
 +            // to check this.
 +            //AlignmentInterval interval = dataManager.getLoadedInterval();
 +            //if (interval != null &&
 +            //        (!interval.chr.equals(context.getChr()) ||
 +            //        interval.getStart() > context.getEndLocation() ||
 +            //        interval.getEnd() < context.getOrigin())) {
 +            //    dataManager.setLoadedInterval(null);
 +            // return;
 +            //}
 +
 +            PreferenceManager.SAMPreferences prefs = PreferenceManager.getInstance().getSAMPreferences();
 +            int maxLevels = prefs.getMaxLevels();
 +
++=======
++>>>>>>> upstream/1.5.56
              Rectangle visibleRect = context.getVisibleRect();
  
              // Divide rectangle into equal height levels
@@@ -326,17 -366,16 +466,25 @@@
              int levelNumber = 0;
              // levelList is copied to prevent concurrent modification exception
              //List<AlignmentDataManager.Row> tmp = new ArrayList(dataManager.getAlignmentRows());
++<<<<<<< HEAD
++
++            for (AlignmentInterval.Row row : tmp) {
++=======
++>>>>>>> upstream/1.5.56
  
              for (AlignmentInterval.Row row : tmp) {
  
-                 if ((visibleRect != null && y > visibleRect.getMaxY()) ||
-                         levelNumber > maxLevels) {
+                 if ((visibleRect != null && y > visibleRect.getMaxY()) || levelNumber > dataManager.getMaxLevels()) {
                      return;
                  }
  
                  if (y + h > visibleRect.getY()) {
                      Rectangle rect = new Rectangle(inputRect.x, (int) y, inputRect.width, (int) h);
++<<<<<<< HEAD
 +                    renderOptions.colorOption = colorByOption;
++=======
+                     renderOptions.setColorOption(colorByOption);
++>>>>>>> upstream/1.5.56
                      renderer.renderAlignments(row.alignments,
                              context,
                              rect,
@@@ -357,6 -396,9 +505,12 @@@
      }
  
      public void reloadData() {
++<<<<<<< HEAD
++=======
+         float maxRange = PreferenceManager.getInstance().getSAMPreferences().getMaxVisibleRange();
+         minVisibleScale = (maxRange * 1000) / 700;
+         renderOptions = new RenderOptions();
++>>>>>>> upstream/1.5.56
          dataManager.reload();
      }
  
@@@ -369,6 -411,10 +523,10 @@@
          dataManager.sortRows(option);
      }
  
+     public void sortRows(SortOption option, double location) {
+         dataManager.sortRows(option, location);
+     }
+ 
      public void packAlignments() {
          dataManager.packAlignments();
      }
@@@ -408,8 -454,6 +566,11 @@@
              if (mate != null && mate.isMapped()) {
                  String chr = mate.mateChr;
                  int start = mate.mateStart - 1;
++<<<<<<< HEAD
 +                selectedReadNames.clear();
 +                selectedReadNames.put(alignment.getReadName(), Color.black);
++=======
++>>>>>>> upstream/1.5.56
                  ViewContext.getInstance().centerOnLocation(chr, start);
                  ViewContext.getInstance().recordHistory();
              }
@@@ -539,9 -583,14 +700,14 @@@
                      if (selectedReadNames.containsKey(alignment.getReadName())) {
                          selectedReadNames.remove(alignment.getReadName());
                      } else {
-                         Color c = alignment.isPaired() && alignment.getMate() != null && alignment.getMate().isMapped() ? ColorUtilities.randomColor(selectedReadNames.size() + 1) : Color.black;
+                         Color c = alignment.isPaired() && alignment.getMate() != null && alignment.getMate().isMapped() ?
+                                 ColorUtilities.randomColor(selectionColorIndex++) : Color.black;
                          selectedReadNames.put(alignment.getReadName(), c);
                      }
+                     Object source = e.getSource();
+                     if (source instanceof JComponent) {
+                         ((JComponent) source).repaint();
+                     }
                  }
                  return true;
              }
@@@ -563,6 -612,7 +729,7 @@@
  
          addSortMenuItem(popupMenu);
          addPackMenuItem(popupMenu);
+         addCoverageDepthMenuItem(popupMenu);
          popupMenu.addSeparator();
          addColorByMenuItem(popupMenu);
  
@@@ -688,6 -738,7 +855,10 @@@
              }
          });
  
++<<<<<<< HEAD
++=======
+ 
++>>>>>>> upstream/1.5.56
          if (ViewContext.getInstance().getScale() >= MIN_ALIGNMENT_SPACING) {
              item.setEnabled(false);
          }
@@@ -751,15 -802,38 +922,48 @@@
              }
          });
  
++<<<<<<< HEAD
++=======
+         JRadioButtonMenuItem m4 = new JRadioButtonMenuItem("by read group");
+         m4.setSelected(colorByOption == ColorOption.READ_GROUP);
+         m4.addActionListener(new ActionListener() {
+             public void actionPerformed(ActionEvent e) {
+                 setColorOption(ColorOption.READ_GROUP);
+                 refresh();
+             }
+         });
+ 
+         JRadioButtonMenuItem m5 = new JRadioButtonMenuItem("by sample");
+         m5.setSelected(colorByOption == ColorOption.SAMPLE);
+         m5.addActionListener(new ActionListener() {
+             public void actionPerformed(ActionEvent e) {
+                 setColorOption(ColorOption.SAMPLE);
+                 refresh();
+             }
+         });
+ 
++>>>>>>> upstream/1.5.56
          item.add(m1);
          item.add(m1a);
          item.add(m2);
          item.add(m3);
++<<<<<<< HEAD
++=======
+         item.add(m5);
+         item.add(m4);
++>>>>>>> upstream/1.5.56
          group.add(m1);
          group.add(m1a);
          group.add(m2);
          group.add(m3);
++<<<<<<< HEAD
++        menu.add(item);
++=======
+         group.add(m5);
+         group.add(m4);
          menu.add(item);
+ 
++>>>>>>> upstream/1.5.56
      }
  
  
@@@ -826,6 -900,7 +1030,10 @@@
  
                      public void run() {
                          AlignmentTrack.this.selectedReadNames.clear();
++<<<<<<< HEAD
++=======
+                         selectionColorIndex = 0;
++>>>>>>> upstream/1.5.56
                          refresh();
                      }
                  });
@@@ -838,14 -913,14 +1046,18 @@@
      public void addShowAllBasesMenuItem(JPopupMenu menu) {
          // Change track height by attribute
          final JMenuItem item = new JCheckBoxMenuItem("Show all bases");
-         item.setSelected(renderOptions.showAllBases);
+         item.setSelected(renderOptions.isShowAllBases());
          item.addActionListener(new ActionListener() {
  
              public void actionPerformed(ActionEvent e) {
                  UIUtilities.invokeOnEventThread(new Runnable() {
  
                      public void run() {
++<<<<<<< HEAD
 +                        renderOptions.showAllBases = item.isSelected();
++=======
+                         renderOptions.setShowAllBases(item.isSelected());
++>>>>>>> upstream/1.5.56
                          refresh();
                      }
                  });
@@@ -855,18 -930,19 +1067,28 @@@
          menu.add(item);
      }
  
-     public void addInsertSizeMenuItem(JPopupMenu menu) {
+     public void addCoverageDepthMenuItem(JPopupMenu menu) {
          // Change track height by attribute
-         final JMenuItem item = new JCheckBoxMenuItem("Set insert size threshold ...");
+         final JMenuItem item = new JCheckBoxMenuItem("Set maximum coverage depth ...");
          item.addActionListener(new ActionListener() {
  
              public void actionPerformed(ActionEvent e) {
++<<<<<<< HEAD
 +                int threshold = renderOptions.insertSizeThreshold;
 +                String val = MessageUtils.showInputDialog("insert size threshold", String.valueOf(threshold));
 +                try {
 +                    int newThreshold = Integer.parseInt(val);
 +                    if (newThreshold != threshold) {
 +                        renderOptions.insertSizeThreshold = newThreshold;
++=======
+                 int maxLevels = dataManager.getMaxLevels();
+                 String val = MessageUtils.showInputDialog("Maximum coverage depth", String.valueOf(maxLevels));
+                 try {
+                     int newMaxLevels = Integer.parseInt(val);
+                     if (newMaxLevels != maxLevels) {
+                         dataManager.setMaxLevels(newMaxLevels);
+                         dataManager.reload();
++>>>>>>> upstream/1.5.56
                          refresh();
                      }
                  }
@@@ -881,21 -957,47 +1103,67 @@@
          menu.add(item);
      }
  
++<<<<<<< HEAD
 +    private void refresh() {
 +        IGVMainFrame.getInstance().repaintDataPanels();
 +    }
 +
 +    public void addShadeBaseMenuItem(JPopupMenu menu) {
++=======
+     public void addInsertSizeMenuItem(JPopupMenu menu) {
++>>>>>>> upstream/1.5.56
          // Change track height by attribute
-         final JMenuItem item = new JCheckBoxMenuItem("Shade base by quality");
-         item.setSelected(renderOptions.shadeBases);
+         final JMenuItem item = new JCheckBoxMenuItem("Set insert size threshold ...");
          item.addActionListener(new ActionListener() {
  
              public void actionPerformed(ActionEvent e) {
++<<<<<<< HEAD
 +                UIUtilities.invokeOnEventThread(new Runnable() {
 +
 +                    public void run() {
 +                        renderOptions.shadeBases = item.isSelected();
++=======
+                 int threshold = renderOptions.getInsertSizeThreshold();
+                 String val = MessageUtils.showInputDialog("insert size threshold", String.valueOf(threshold));
+                 try {
+                     int newThreshold = Integer.parseInt(val);
+                     if (newThreshold != threshold) {
+                         renderOptions.setInsertSizeThreshold(newThreshold);
++>>>>>>> upstream/1.5.56
+                         refresh();
+                     }
+                 }
+                 catch (NumberFormatException ex) {
+                     MessageUtils.showMessage("Insert size must be an integer value: " + val);
+                 }
+ 
+             }
+         });
+ 
+ 
+         menu.add(item);
+     }
+ 
+     private void refresh() {
+         IGVMainFrame.getInstance().repaintDataPanels();
+     }
+ 
+     public void addShadeBaseMenuItem(JPopupMenu menu) {
+         // Change track height by attribute
+         final JMenuItem item = new JCheckBoxMenuItem("Shade base by quality");
+         item.setSelected(renderOptions.isShadeBases());
+         item.addActionListener(new ActionListener() {
+ 
+             public void actionPerformed(ActionEvent e) {
+                 UIUtilities.invokeOnEventThread(new Runnable() {
+ 
+                     public void run() {
++<<<<<<< HEAD
++
++                        renderOptions.shadeCenters = item.isSelected();
++=======
+                         renderOptions.setShadeBases(item.isSelected());
++>>>>>>> upstream/1.5.56
                          refresh();
                      }
                  });
@@@ -905,10 -1007,10 +1173,12 @@@
          menu.add(item);
      }
  
++<<<<<<< HEAD
++=======
      public void addShadeCentersMenuItem(JPopupMenu menu) {
          // Change track height by attribute
          final JMenuItem item = new JCheckBoxMenuItem("Shade alignments intersecting center");
-         item.setSelected(renderOptions.shadeCenters);
+         item.setSelected(renderOptions.isShadeCenters());
          item.addActionListener(new ActionListener() {
  
              public void actionPerformed(ActionEvent e) {
@@@ -916,7 -1018,7 +1186,7 @@@
  
                      public void run() {
  
-                         renderOptions.shadeCenters = item.isSelected();
+                         renderOptions.setShadeCenters(item.isSelected());
                          refresh();
                      }
                  });
@@@ -925,6 -1027,6 +1195,7 @@@
  
          menu.add(item);
      }
++>>>>>>> upstream/1.5.56
  
  
      public void addShowCoverageItem(JPopupMenu menu) {
diff --combined src/org/broad/igv/sam/CoverageTrack.java
index efa42cd,ecc6c0d..47b1471
--- a/src/org/broad/igv/sam/CoverageTrack.java
+++ b/src/org/broad/igv/sam/CoverageTrack.java
@@@ -25,6 -25,7 +25,10 @@@ package org.broad.igv.sam
  import com.jidesoft.swing.JidePopupMenu;
  import org.apache.log4j.Logger;
  import org.broad.igv.PreferenceManager;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.sam.reader.CachingQueryReader;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.util.ColorUtilities;
  import org.broad.igv.util.AsciiLineReader;
  import org.broad.igv.util.ParsingUtils;
@@@ -44,7 -45,6 +48,7 @@@ import org.broad.igv.ui.FontManager
  import org.broad.igv.ui.IGVMainFrame;
  import org.broad.igv.ui.util.FileChooserDialog;
  import org.broad.igv.ui.util.MessageUtils;
 +import org.broad.igv.ui.util.UIUtilities;
  
  import javax.swing.*;
  import java.awt.*;
@@@ -140,19 -140,21 +144,37 @@@ public class CoverageTrack extends Abst
  
      public void render(RenderContext context, Rectangle rect) {
  
++<<<<<<< HEAD
 +        // TODO -- merge the two renderers,  this is very clumsy
 +        AlignmentInterval interval = null;
 +        if (dataManager != null) {
 +            interval = dataManager.getLoadedInterval();
 +        }
 +
 +
 +        if (interval != null && interval.overlaps(context.getGenomeId(), context.getChr(), (int) context.getOrigin(),
 +                (int) context.getEndLocation())) {
 +            intervalRenderer.paint(context, rect, interval);
 +        }
 +        // Use precomputed data source, if any
 +        else if (dataSource != null) {
++=======
+         float maxRange = PreferenceManager.getInstance().getSAMPreferences().getMaxVisibleRange();
+         float minVisibleScale = (maxRange * 1000) / 700;
+ 
+         if (context.getScale() < minVisibleScale) {
+             AlignmentInterval interval = null;
+             if (dataManager != null) {
+                 interval = dataManager.getLoadedInterval();
+             }
+ 
+             if (interval != null && interval.overlaps(context.getGenomeId(), context.getChr(), (int) context.getOrigin(),
+                     (int) context.getEndLocation())) {
+                 List<CachingQueryReader.AlignmentCounts> counts = interval.counts;
+                 intervalRenderer.paint(context, rect, counts);
+             }
+         } else if (dataSource != null) {
++>>>>>>> upstream/1.5.56
              String chr = context.getChr();
              int start = (int) context.getOrigin();
              int end = (int) context.getEndLocation();
@@@ -164,9 -166,12 +186,18 @@@
  
          }
  
++<<<<<<< HEAD
 +
 +
 +
++=======
+         drawBorder(context, rect);
+ 
+ 
+     }
+ 
+     private void drawBorder(RenderContext context, Rectangle rect) {
++>>>>>>> upstream/1.5.56
          // Draw border
          context.getGraphic2DForColor(Color.gray).drawLine(
                  rect.x, rect.y + rect.height,
@@@ -237,6 -242,6 +268,7 @@@
      }
  
      private String getPrecomputedValueString(String chr, double position) {
++<<<<<<< HEAD
  
          if (dataSource == null) {
              return "";
@@@ -378,128 -383,130 +410,334 @@@
      class IntervalRenderer {
  
  
 +        private void paint(RenderContext context, Rectangle rect, AlignmentInterval interval) {
++=======
 +
-             Graphics2D graphics = context.getGraphic2DForColor(AlignmentRenderer.grey1);
++        if (dataSource == null) {
++            return "";
++        }
++        int zoom = Math.max(0, ViewContext.getInstance().getZoom());
++        List<LocusScore> scores = dataSource.getSummaryScoresForRange(chr, (int) position - 10, (int) position + 10, zoom);
++>>>>>>> upstream/1.5.56
++
++        // give a 2 pixel window, otherwise very narrow features will be missed.
++        double bpPerPixel = ViewContext.getInstance().getScale();
++        double minWidth = 2 * bpPerPixel;    /* * */
 +
++<<<<<<< HEAD
 +            DataRange range = getDataRange();
 +            double max = range.isLog() ? Math.log10(range.getMaximum()) : range.getMaximum();
++=======
++        if (scores == null) {
++            return "";
++        } else {
++            LocusScore score = FeatureUtils.getFeatureAt(position, minWidth, scores);
++            return score == null ? "" : "Mean count: " + score.getScore();
++        }
++    }
 +
-             // Temporary until proper windowing is implemented
-             int lastpX = -1;
++    public float getRegionScore(String chr, int start, int end, int zoom, RegionScoreType type) {
++        return 0;
++    }
++>>>>>>> upstream/1.5.56
 +
-             for (int pos = interval.getStart(); pos < interval.getEnd(); pos++) {
 +
-                 int pX = (int) (rect.getX() + (pos - context.getOrigin()) / context.getScale());
-                 int dX = Math.max(1,
-                         (int) (rect.getX() + (pos + 1 - context.getOrigin()) / context.getScale()) - pX);
-                 if (dX > 3) {
-                     dX--;
-                 }
++    /**
++     * Load the set of known snps from a tab delimited file, format
++     * chr < tab> location
++     * The location is "1 base"  (first nucleotide is position 1).
++     *
++     * @param snpFile
++     */
++    private static synchronized void loadKnownSnps(String snpFile) {
 +
-                 if (pX > rect.getMaxX()) {
-                     break;
++        // This method might get called many times concurrently, but we only want to load these once.
++        if (knownSnps != null) {
++            return;
++        }
++
++        knownSnps = new HashMap();
++        AsciiLineReader reader = null;
++        try {
++            reader = ParsingUtils.openAsciiReader(new ResourceLocator(snpFile));
++            String nextLine = "";
++            while ((nextLine = reader.readLine()) != null) {
++                String[] tokens = nextLine.split("\t");
++                String chr = tokens[0];
++                Set<Integer> snps = knownSnps.get(chr);
++                if (snps == null) {
++                    snps = new HashSet(10000);
++                    knownSnps.put(chr, snps);
 +                }
++                snps.add(new Integer(tokens[1]));
++            }
++        } catch (Exception e) {
++            knownSnps = null;
++            log.error("", e);
++            MessageUtils.showMessage("Error loading snps file: " + snpFile + " (" + e.toString() + ")");
++        } finally {
++            reader.close();
++        }
 +
++<<<<<<< HEAD
 +                if (pX + dX >= 0) {
 +
 +                    // Test to see if any single nucleotide mismatch  (nucleotide other than the reference)
 +                    // has posA quality weight > 20% of the total
 +                    // Skip this test if the position is in the list of known snps
 +                    char ref = Character.toLowerCase((char) interval.getReference(pos));
 +                    boolean mismatch = false;
 +
 +                    Set<Integer> snps = knownSnps == null ? null : knownSnps.get(context.getChr());
 +                    if (snps == null || !snps.contains(pos + 1)) {
 +                        float threshold = snpThreshold * interval.getTotalQuality(pos);
 +                        if (ref > 0) {
 +                            for (char c : nucleotides) {
 +                                if (c != ref && c != 'n' && interval.getQuality(pos, (byte) c) > threshold) {
 +                                    mismatch = true;
 +                                    break;
 +                                }
 +                            }
 +                        }
 +                    }
 +
 +                    if (pX > lastpX || mismatch) {
 +
 +                        boolean strandOption = false;
 +
 +                        if (strandOption) {
++=======
++
++    }
++
++    /*
++                           if (plusMinusOption || nonRefOption) {
++>>>>>>> upstream/1.5.56
 +
 +                            int pY = (int) (rect.getY() + rect.getMaxY()) / 2;
 +
 +                            int totalNegCount = interval.getNegTotal(pos);
 +                            int height = (int) (totalNegCount * rect.getHeight() / getColorScale().getMaximum());
 +                            height = Math.min(height, rect.height / 2 - 1);
 +                            if (height > 0) {
 +
 +                                graphics.fillRect(pX, pY, dX, height);
 +
++<<<<<<< HEAD
 +                                if (mismatch || showAllSnps) {
 +                                    for (char c : nucleotides) {
 +                                        if (c != ref) {
 +                                            pY = drawStrandBar(context, pos, rect, getColorScale().getMaximum(), pY, pX, dX, c,
 +                                                    false, interval);
++=======
++                                    if (colorBases) {
++                                        for (char c : nucleotides) {
++                                            if (nonRefOption == false || c != ref) {
++                                                pY = drawBar(context, pos, rect, getColorScale().getMaximum(), pY, pX, dX, c,
++                                                        plusMinusOption || nonRefOption, false, interval);
++                                            }
++>>>>>>> upstream/1.5.56
 +                                        }
 +                                    }
 +                                }
 +
 +                            }
 +
 +                            pY = (int) (rect.getY() + rect.getMaxY()) / 2;
 +                            int totalPosCount = interval.getPosTotal(pos);
 +
 +                            height = (int) (totalPosCount * rect.getHeight() / getColorScale().getMaximum());
 +                            height = Math.min(height, rect.height / 2 - 1);
 +                            int topY = (pY - height);
 +
 +                            if (height > 0) {
 +
 +                                graphics.fillRect(pX, topY, dX, height);
 +
 +                                if (mismatch || showAllSnps) {
 +                                    for (char c : nucleotides) {
++<<<<<<< HEAD
 +                                        if (c != ref) {
 +                                            pY = drawStrandBar(context, pos, rect, getColorScale().getMaximum(), pY, pX, dX, c,
 +                                                    true, interval);
++=======
++                                        if (nonRefOption == false || c != ref) {
++                                            pY = drawBar(context, pos, rect, getColorScale().getMaximum(), pY, pX, dX, c,
++                                                    plusMinusOption || nonRefOption, true, interval);
++>>>>>>> upstream/1.5.56
 +                                        }
 +                                    }
 +                                }
 +                            }
 +
 +                            pY = (int) (rect.getY() + rect.getMaxY()) / 2;
 +                            Graphics2D blackGraphics = context.getGraphic2DForColor(lightBlue);
 +                            blackGraphics.drawLine(0, pY, rect.width, pY);
 +                        } else {
 +
 +                            int pY = (int) rect.getMaxY() - 1;
 +
 +                            int totalCount = interval.getTotalCount(pos);
 +
++<<<<<<< HEAD
 +                            double tmp = range.isLog() ? Math.log10(totalCount) / max : totalCount / max;
 +                            int height = (int) (tmp * rect.getHeight());
 +
++=======
++                            int pY = (int) rect.getMaxY() - 1;
++                            int height = (int) (totalCount * rect.getHeight() / getColorScale().getMaximum());
++>>>>>>> upstream/1.5.56
 +                            height = Math.min(height, rect.height - 1);
 +                            int topY = (pY - height);
 +
 +                            if (height > 0) {
 +                                graphics.fillRect(pX, topY, dX, height);
 +
 +                                if (mismatch || showAllSnps) {
 +                                    for (char c : nucleotides) {
 +                                        if (!(c == ref && showAllSnps)) {
 +                                            pY = drawBar(context, pos, rect, totalCount, max,
 +                                                    pY, pX, dX, c, interval, range.isLog());
 +                                        }
 +                                    }
 +                                }
 +                            }
 +                        }
++<<<<<<< HEAD
 +                        lastpX = pX;
 +                    }
 +
++=======
++     */
++
++    class IntervalRenderer {
++
++
+         private void paint(RenderContext context, Rectangle rect, List<CachingQueryReader.AlignmentCounts> countList) {
+ 
+             Graphics2D graphics = context.getGraphic2DForColor(AlignmentRenderer.grey1);
+ 
+             DataRange range = getDataRange();
+             double max = range.isLog() ? Math.log10(range.getMaximum()) : range.getMaximum();
+ 
+             // Temporary until proper windowing is implemented
+             int lastpX = -1;
+ 
+             for (CachingQueryReader.AlignmentCounts alignmentCounts : countList) {
+ 
+                 for (int pos = alignmentCounts.getStart(); pos < alignmentCounts.getEnd(); pos++) {
+ 
+                     int pX = (int) (rect.getX() + (pos - context.getOrigin()) / context.getScale());
+                     int dX = Math.max(1,
+                             (int) (rect.getX() + (pos + 1 - context.getOrigin()) / context.getScale()) - pX);
+                     if (dX > 3) {
+                         dX--;
+                     }
+ 
+                     if (pX > rect.getMaxX()) {
+                         break;
+                     }
+ 
+                     if (pX + dX >= 0) {
+ 
+                         // Test to see if any single nucleotide mismatch  (nucleotide other than the reference)
+                         // has posA quality weight > 20% of the total
+                         // Skip this test if the position is in the list of known snps
+                         char ref = Character.toLowerCase((char) alignmentCounts.getReference(pos));
+                         boolean mismatch = false;
+ 
+                         Set<Integer> snps = knownSnps == null ? null : knownSnps.get(context.getChr());
+                         if (snps == null || !snps.contains(pos + 1)) {
+                             float threshold = snpThreshold * alignmentCounts.getTotalQuality(pos);
+                             if (ref > 0) {
+                                 for (char c : nucleotides) {
+                                     if (c != ref && c != 'n' && alignmentCounts.getQuality(pos, (byte) c) > threshold) {
+                                         mismatch = true;
+                                         break;
+                                     }
+                                 }
+                             }
+                         }
+ 
+                         if (pX > lastpX || mismatch) {
+ 
+                             boolean strandOption = false;
+ 
+                             if (strandOption) {
+ 
+                                 int pY = (int) (rect.getY() + rect.getMaxY()) / 2;
+ 
+                                 int totalNegCount = alignmentCounts.getNegTotal(pos);
+                                 int height = (int) (totalNegCount * rect.getHeight() / getColorScale().getMaximum());
+                                 height = Math.min(height, rect.height / 2 - 1);
+                                 if (height > 0) {
+ 
+                                     graphics.fillRect(pX, pY, dX, height);
+ 
+                                     if (mismatch || showAllSnps) {
+                                         for (char c : nucleotides) {
+                                             if (c != ref) {
+                                                 pY = drawStrandBar(context, pos, rect, getColorScale().getMaximum(), pY, pX, dX, c,
+                                                         false, alignmentCounts);
+                                             }
+                                         }
+                                     }
+ 
+                                 }
+ 
+                                 pY = (int) (rect.getY() + rect.getMaxY()) / 2;
+                                 int totalPosCount = alignmentCounts.getPosTotal(pos);
+ 
+                                 height = (int) (totalPosCount * rect.getHeight() / getColorScale().getMaximum());
+                                 height = Math.min(height, rect.height / 2 - 1);
+                                 int topY = (pY - height);
+ 
+                                 if (height > 0) {
+ 
+                                     graphics.fillRect(pX, topY, dX, height);
+ 
+                                     if (mismatch || showAllSnps) {
+                                         for (char c : nucleotides) {
+                                             if (c != ref) {
+                                                 pY = drawStrandBar(context, pos, rect, getColorScale().getMaximum(), pY, pX, dX, c,
+                                                         true, alignmentCounts);
+                                             }
+                                         }
+                                     }
+                                 }
+ 
+                                 pY = (int) (rect.getY() + rect.getMaxY()) / 2;
+                                 Graphics2D blackGraphics = context.getGraphic2DForColor(lightBlue);
+                                 blackGraphics.drawLine(0, pY, rect.width, pY);
+                             } else {
+ 
+                                 int pY = (int) rect.getMaxY() - 1;
+ 
+                                 int totalCount = alignmentCounts.getTotalCount(pos);
+ 
+                                 double tmp = range.isLog() ? Math.log10(totalCount) / max : totalCount / max;
+                                 int height = (int) (tmp * rect.getHeight());
+ 
+                                 height = Math.min(height, rect.height - 1);
+                                 int topY = (pY - height);
+ 
+                                 if (height > 0) {
+                                     graphics.fillRect(pX, topY, dX, height);
+ 
+                                     if (mismatch || showAllSnps) {
+                                         for (char c : nucleotides) {
+                                             if (!(c == ref && showAllSnps)) {
+                                                 pY = drawBar(context, pos, rect, totalCount, max,
+                                                         pY, pX, dX, c, alignmentCounts, range.isLog());
+                                             }
+                                         }
+                                     }
+                                 }
+                             }
+                             lastpX = pX;
+                         }
+                     }
++>>>>>>> upstream/1.5.56
                  }
              }
          }
@@@ -529,18 -536,18 +767,33 @@@
                      int pX,
                      int dX,
                      char nucleotide,
++<<<<<<< HEAD
 +                    AlignmentInterval interval,
 +                    boolean isLog) {
 +
 +            int count = interval.getCount(pos, (byte) nucleotide);
 +
 +            Color c = AlignmentRenderer.nucleotideColors.get(nucleotide);
 +
 +            if (showAllSnps) {
 +                int q = interval.getAvgQuality(pos, (byte) nucleotide);
 +                c = getShadedColor(q, c);
 +            }
 +
++=======
+                     CachingQueryReader.AlignmentCounts interval,
+                     boolean isLog) {
+ 
+             int count = interval.getCount(pos, (byte) nucleotide);
+ 
+             Color c = AlignmentRenderer.getNucleotideColors().get(nucleotide);
+ 
+             if (showAllSnps) {
+                 int q = interval.getAvgQuality(pos, (byte) nucleotide);
+                 c = getShadedColor(q, c);
+             }
+ 
++>>>>>>> upstream/1.5.56
              Graphics2D tGraphics = context.getGraphic2DForColor(c);
  
              double tmp = isLog ?
@@@ -582,16 -589,16 +835,29 @@@
                            int dX,
                            char nucleotide,
                            boolean isPositive,
++<<<<<<< HEAD
 +                          AlignmentInterval interval) {
 +
 +
 +            Color c = AlignmentRenderer.nucleotideColors.get(nucleotide);
 +            Graphics2D tGraphics = context.getGraphic2DForColor(c);
 +
 +
 +            int count = isPositive ? interval.getPosCount(pos, (byte) nucleotide) :
 +                    interval.getNegCount(pos, (byte) nucleotide);
 +
++=======
+                           CachingQueryReader.AlignmentCounts interval) {
+ 
+ 
+             Color c = AlignmentRenderer.getNucleotideColors().get(nucleotide);
+             Graphics2D tGraphics = context.getGraphic2DForColor(c);
+ 
+ 
+             int count = isPositive ? interval.getPosCount(pos, (byte) nucleotide) :
+                     interval.getNegCount(pos, (byte) nucleotide);
+ 
++>>>>>>> upstream/1.5.56
              int height = (int) Math.round(count * rect.getHeight() / maxCount);
              height = isPositive ? Math.min(pY - rect.y, height) :
                      Math.min(rect.y + rect.height - pY, height);
@@@ -604,10 -611,10 +870,18 @@@
          }
  
      }
++<<<<<<< HEAD
++=======
  
++>>>>>>> upstream/1.5.56
++
++    static float[] colorComps = new float[3];
  
++<<<<<<< HEAD
      static float[] colorComps = new float[3];
  
++=======
++>>>>>>> upstream/1.5.56
      private Color getShadedColor(int qual, Color color) {
          float alpha = 0;
          int minQ = prefs.getSAMPreferences().getBaseQualityMin();
diff --combined src/org/broad/igv/sam/DotAlignedAlignment.java
index ff9117b,f7980fd..dc93b3c
--- a/src/org/broad/igv/sam/DotAlignedAlignment.java
+++ b/src/org/broad/igv/sam/DotAlignedAlignment.java
@@@ -26,6 -26,8 +26,8 @@@ import org.broad.igv.feature.LocusScore
  import org.broad.igv.feature.Strand;
  import org.broad.igv.track.WindowFunction;
  
+ import java.awt.*;
+ 
  /**
   * @author jrobinso
   */
@@@ -83,6 -85,10 +85,13 @@@ public class DotAlignedAlignment implem
          return false;  //To change body of implemented methods use File | Settings | File Templates.
      }
  
++<<<<<<< HEAD
++=======
+     public Color getDefaultColor() {      
+         return AlignmentRenderer.grey1;
+     }
+ 
++>>>>>>> upstream/1.5.56
      public String getChromosome() {
          return chromosome;
      }
diff --combined src/org/broad/igv/sam/FeatureWrappedAlignment.java
index 5012cc3,d5b0f11..799df32
--- a/src/org/broad/igv/sam/FeatureWrappedAlignment.java
+++ b/src/org/broad/igv/sam/FeatureWrappedAlignment.java
@@@ -24,6 -24,8 +24,11 @@@ import org.broad.igv.feature.LocusScore
  import org.broad.igv.feature.Strand;
  import org.broad.igv.track.WindowFunction;
  
++<<<<<<< HEAD
++=======
+ import java.awt.*;
+ 
++>>>>>>> upstream/1.5.56
  /**
   * Some alignment formats are parsed as Features.
   * <p/>
@@@ -222,6 -224,10 +227,13 @@@ public class FeatureWrappedAlignment im
          return false;  //To change body of implemented methods use File | Settings | File Templates.
      }
  
++<<<<<<< HEAD
++=======
+     public Color getDefaultColor() {
+         return AlignmentRenderer.grey1;
+     }
+ 
++>>>>>>> upstream/1.5.56
      public char[] getGapTypes() {
          return null;
      }
diff --combined src/org/broad/igv/sam/SamAlignment.java
index 31996f5,48850b6..f9119c9
--- a/src/org/broad/igv/sam/SamAlignment.java
+++ b/src/org/broad/igv/sam/SamAlignment.java
@@@ -29,7 -29,9 +29,12 @@@ import org.broad.igv.feature.LocusScore
  import org.broad.igv.feature.Strand;
  import org.broad.igv.session.ViewContext;
  import org.broad.igv.track.WindowFunction;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.util.ColorUtilities;
++>>>>>>> upstream/1.5.56
  
+ import java.awt.*;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
@@@ -74,6 -76,7 +79,10 @@@ public class SamAlignment extends Abstr
      boolean secondRead = false;
      private String mateSequence = null;
      private String pairOrientation = "";
++<<<<<<< HEAD
++=======
+     private Color defaultColor = AlignmentRenderer.grey1;
++>>>>>>> upstream/1.5.56
  
      /**
       * Constructs ...
@@@ -111,6 -114,16 +120,19 @@@
          setPairOrientation(record);
          setFirstReadStrand(record);
          createAlignmentBlocks(record.getCigarString(), record.getReadBases(), record.getBaseQualities());
++<<<<<<< HEAD
++=======
+ 
+         Object colorTag = record.getAttribute("YC");
+         if (colorTag != null) {
+             try {
+                 defaultColor = ColorUtilities.convertRGBStringToColor(colorTag.toString());
+             } catch (Exception e) {
+                 log.error("Error interpreting color tag: " + colorTag, e);
+                 defaultColor = AlignmentRenderer.grey1;
+             }
+         }
++>>>>>>> upstream/1.5.56
      }
  
      private void setFirstReadStrand(SAMRecord record) {
@@@ -248,7 -261,10 +270,14 @@@
              } else {
                  int nBases = Integer.parseInt(buffer.toString());
                  char op = next;
++<<<<<<< HEAD
 +                if (operatorIsMatch(showSoftClipped, op)) {
++=======
+                 if (op == HARD_CLIP) {
+                     buffer = new StringBuffer(4);
+                     continue;  // Just skip hardclips
+                 } else if (operatorIsMatch(showSoftClipped, op)) {
++>>>>>>> upstream/1.5.56
                      if (operatorIsMatch(showSoftClipped, prevOp)) {
                          nGaps++;   // Consecutive Ms
                      }
@@@ -282,7 -298,7 +311,11 @@@
          }
  
          // Adjust start and fill new arrays
++<<<<<<< HEAD
 +        if(showSoftClipped) {
++=======
+         if (showSoftClipped) {
++>>>>>>> upstream/1.5.56
              start -= softClippedBaseCount;
          }
          int fromIdx = showSoftClipped ? 0 : softClippedBaseCount;
@@@ -314,7 -330,7 +347,11 @@@
                  }
  
                  AlignmentBlock block = new AlignmentBlock(blockStart, blockBases, blockQualities);
++<<<<<<< HEAD
 +                if(op.operator == SOFT_CLIP) {
++=======
+                 if (op.operator == SOFT_CLIP) {
++>>>>>>> upstream/1.5.56
                      block.setSoftClipped(true);
                  }
                  alignmentBlocks[blockIdx++] = block;
@@@ -359,15 -375,14 +396,24 @@@
          }
  
          // Check for soft clipping at end
++<<<<<<< HEAD
 +        if(showSoftClipped && operators.size() > 0 ) {
 +            CigarOperator last = operators.get(operators.size()-1);
 +            if(last.operator == SOFT_CLIP) {
++=======
+         if (showSoftClipped && operators.size() > 0) {
+             CigarOperator last = operators.get(operators.size() - 1);
+             if (last.operator == SOFT_CLIP) {
++>>>>>>> upstream/1.5.56
                  end += last.nBases;
              }
          }
  
  
++<<<<<<< HEAD
 +
++=======
++>>>>>>> upstream/1.5.56
      }
  
      private boolean operatorIsMatch(boolean showSoftClipped, char operator) {
@@@ -579,6 -594,10 +625,13 @@@
          return record.getReadFailsVendorQualityCheckFlag();
      }
  
++<<<<<<< HEAD
++=======
+     public Color getDefaultColor() {
+         return defaultColor;
+     }
+ 
++>>>>>>> upstream/1.5.56
      static class CigarOperator {
  
          int nBases;
diff --combined src/org/broad/igv/sam/reader/BAMHttpQueryReader.java
index a6fa425,156f10a..1e66bb6
--- a/src/org/broad/igv/sam/reader/BAMHttpQueryReader.java
+++ b/src/org/broad/igv/sam/reader/BAMHttpQueryReader.java
@@@ -54,9 -54,11 +54,11 @@@ public class BAMHttpQueryReader impleme
      File indexFile;
      SAMFileReader reader;
  
-     public BAMHttpQueryReader(URL url) {
+     public BAMHttpQueryReader(URL url, boolean requireIndex) {
          this.url = url;
-         indexFile = getIndexFile(url);
+         if (requireIndex) {
+             indexFile = getIndexFile(url);
+         }
      }
  
      public void close() throws IOException {
@@@ -151,66 -153,22 +153,86 @@@
  
  
      // TODO -- revisit caching scehme,  do something for ftp loads
++<<<<<<< HEAD
  
      File getIndexFile(URL bamURL) {
  
 +        try {
 +            String bamURLString = bamURL.toString();
 +            String urlString = bamURLString + ".bai";
 +            URL indexURL = new URL(urlString);
 +            String eTag = null;
 +            Properties eTagCache = getTagCache();
 +
 +            // TODO -- ftp
 +            if (urlString.toLowerCase().startsWith("http:") || urlString.toLowerCase().startsWith("https:")) {
 +                eTag = IGVHttpUtils.getETag(indexURL);
 +
 +
 +                // Try other naming convention
 +                if (eTag == null) {
 +                    // Try other index convention
 +                    String baseName = bamURLString.substring(0, bamURLString.length() - 4);
 +                    indexURL = new URL(baseName + ".bai");
 +
 +                    urlString = bamURL.toString().replace(".bam", ".bai");
 +                    indexURL = new URL(urlString);
 +                    eTag = IGVHttpUtils.getETag(indexURL);
 +                }
 +            }
++=======
++>>>>>>> upstream/1.5.56
 +
++    File getIndexFile(URL bamURL) {
 +
++<<<<<<< HEAD
 +            // Create a filename unique for this url;
 +            String idxFilename = getCachedIndexFilename(bamURLString);
 +
 +            if (eTag != null) {
 +                File indexFile = new File(this.getCacheDirectory(), idxFilename);
 +                if (indexFile.exists()) {
 +                    String cachedETag = eTagCache.getProperty(urlString);
 +                    if (eTag == null || cachedETag == null || !eTag.equals(cachedETag)) {
 +                        indexFile.delete();
 +                        eTagCache.remove(urlString);
 +                        writeCachedProperties(eTagCache, "etags");
 +                    }
 +                }
 +            }
 +
 +            indexFile = new File(this.getCacheDirectory(), idxFilename);
 +            if (!indexFile.exists()) {
 +                loadIndexFile(bamURL.toString(), indexFile);
 +                if (eTag != null) {
 +                    eTagCache.put(urlString, eTag);
 +                    writeCachedProperties(eTagCache, "etags");
 +                } else {
 +                    indexFile.deleteOnExit();
 +                }
 +            }
 +            return indexFile;
 +        } catch (MalformedURLException e) {
 +            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
 +            return null;
++=======
+         String bamURLString = bamURL.toString();
+ 
+         String idxFilename = getCachedIndexFilename(bamURLString);
+ 
+         indexFile = new File(this.getCacheDirectory(), idxFilename);
+         if (!indexFile.exists()) {
+             loadIndexFile(bamURL.toString(), indexFile);
+             indexFile.deleteOnExit();
++>>>>>>> upstream/1.5.56
          }
+         return indexFile;
+ 
++<<<<<<< HEAD
++=======
      }
  
++>>>>>>> upstream/1.5.56
      private String getCachedIndexFilename(String bamURL) {
  
          Properties lookup = getIndexCache();
@@@ -234,7 -192,7 +256,11 @@@
              URL indexURL = new URL(bamURL + ".bai");
              os = new FileOutputStream(indexFile);
              try {
++<<<<<<< HEAD
 +                is = indexURL.openStream();
++=======
+                 is = IGVHttpUtils.openConnectionStream(indexURL);
++>>>>>>> upstream/1.5.56
  
              }
              catch (FileNotFoundException e) {
@@@ -243,14 -201,14 +269,22 @@@
                  indexURL = new URL(baseName + ".bai");
  
                  try {
++<<<<<<< HEAD
 +                    is = indexURL.openStream();
++=======
+                     is = IGVHttpUtils.openConnectionStream(indexURL);
++>>>>>>> upstream/1.5.56
                  }
                  catch (FileNotFoundException e1) {
                      MessageUtils.showMessage("Index file not found for file: " + bamURL);
                      throw new DataLoadException("Index file not found for file: " + bamURL, bamURL);
                  }
              }
++<<<<<<< HEAD
 +            byte[] buf = new byte[4 * 1024]; // 4K buffer
++=======
+             byte[] buf = new byte[512000];
++>>>>>>> upstream/1.5.56
              int bytesRead;
              while ((bytesRead = is.read(buf)) != -1) {
                  os.write(buf, 0, bytesRead);
@@@ -287,7 -245,7 +321,11 @@@
  
      static synchronized File getCacheDirectory() {
          if (cacheDirectory == null) {
++<<<<<<< HEAD
 +            File defaultDir = new File(UIConstants.DEFAULT_IGV_DIRECTORY);
++=======
+             File defaultDir = UIConstants.getIgvDirectory();
++>>>>>>> upstream/1.5.56
              if (defaultDir.exists()) {
                  cacheDirectory = new File(defaultDir, "bam");
                  if (!cacheDirectory.exists()) {
diff --combined src/org/broad/igv/sam/reader/CachingQueryReader.java
index 0c0533a,1806fdc..38c0cc7
--- a/src/org/broad/igv/sam/reader/CachingQueryReader.java
+++ b/src/org/broad/igv/sam/reader/CachingQueryReader.java
@@@ -27,8 -27,13 +27,16 @@@ import net.sf.samtools.util.CloseableIt
  import org.apache.log4j.Logger;
  import org.broad.igv.PreferenceManager;
  import org.broad.igv.exceptions.DataLoadException;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.feature.Genome;
+ import org.broad.igv.feature.GenomeManager;
+ import org.broad.igv.feature.SequenceManager;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.sam.Alignment;
+ import org.broad.igv.sam.AlignmentBlock;
  import org.broad.igv.sam.EmptyAlignmentIterator;
+ import org.broad.igv.session.ViewContext;
  import org.broad.igv.ui.IGVMainFrame;
  import org.broad.igv.ui.util.MessageUtils;
  import org.broad.igv.util.LRUCache;
@@@ -36,35 -41,49 +44,73 @@@ import org.broad.igv.util.RuntimeUtils
  
  import javax.swing.*;
  import java.io.IOException;
++<<<<<<< HEAD
 +import java.util.ArrayList;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Set;
++=======
+ import java.lang.ref.WeakReference;
+ import java.util.*;
++>>>>>>> upstream/1.5.56
  
  /**
   * A wrapper for an AlignmentQueryReader that caches query results
   *
   * @author jrobinso
   */
- public class CachingQueryReader implements AlignmentQueryReader {
+ public class CachingQueryReader {
  
      private static Logger log = Logger.getLogger(CachingQueryReader.class);
  
++<<<<<<< HEAD
 +    private static final int LOW_MEMORY_THRESHOLD = 150000000;
 +    private static final int KB = 1000;
 +    private static final int MITOCHONDRIA_TILE_SIZE = 1000;
 +    private static int DEFAULT_TILE_SIZE = 1600;
 +    private static int MAX_TILE_COUNT = 100;
++=======
+     private static Set<WeakReference<CachingQueryReader>> activeReaders = Collections.synchronizedSet(new HashSet());
+ 
+     private static void cancelReaders() {
+         for (WeakReference<CachingQueryReader> readerRef : activeReaders) {
+             CachingQueryReader reader = readerRef.get();
+             if (reader != null) {
+                 reader.cancel = true;
+             }
+         }
+         log.debug("Readers canceled");
+         activeReaders.clear();
+     }
+ 
+ 
+     //private static final int LOW_MEMORY_THRESHOLD = 150000000;
+     private static final int KB = 1000;
+     private static final int MITOCHONDRIA_TILE_SIZE = 1000;
+     private static int DEFAULT_TILE_SIZE = 16 * KB;
+     private static int MAX_TILE_COUNT = 4;
++>>>>>>> upstream/1.5.56
  
      String cachedChr = "";
      private int tileSize = DEFAULT_TILE_SIZE;
      AlignmentQueryReader reader;
++<<<<<<< HEAD
 +    LRUCache<Integer, Tile> cache;
 +    private int maxReadCount = 500000;
 +
 +    public CachingQueryReader(AlignmentQueryReader reader) {
 +        this.reader = reader;
 +        cache = new LRUCache(MAX_TILE_COUNT);
++=======
+     LRUCache<Integer, AlignmentTile> cache;
+     //private int maxReadCount = 500000;
+ 
+     private boolean cancel = false;
+ 
+     public CachingQueryReader(AlignmentQueryReader reader) {
+         this.reader = reader;
+         cache = new LRUCache(this, MAX_TILE_COUNT);
++>>>>>>> upstream/1.5.56
          tileSize = Math.min(DEFAULT_TILE_SIZE,
                  (int) (PreferenceManager.getInstance().getSAMPreferences().getMaxVisibleRange() * KB));
  
@@@ -78,7 -97,7 +124,11 @@@
          return reader.getSequenceNames();
      }
  
++<<<<<<< HEAD
 +    public SAMFileHeader getHeader() {
++=======
+     public SAMFileHeader getHeader() throws IOException {
++>>>>>>> upstream/1.5.56
          return reader.getHeader();
      }
  
@@@ -90,11 -109,11 +140,11 @@@
          return reader.hasIndex();
      }
  
-     public CloseableIterator<Alignment> query(String sequence, int start, int end, boolean contained) {
+     public CloseableIterator<Alignment> query(String sequence, int start, int end, List<AlignmentCounts> counts) {
  
          int startTile = (start + 1) / getTileSize(sequence);
          int endTile = end / getTileSize(sequence);    // <= inclusive
-         List<Tile> tiles = getTiles(sequence, startTile, endTile);
+         List<AlignmentTile> tiles = getTiles(sequence, startTile, endTile);
  
          if (tiles.size() == 0) {
              return EmptyAlignmentIterator.getInstance();
@@@ -102,19 -121,20 +152,20 @@@
  
          // Count total # of records
          int recordCount = tiles.get(0).getOverlappingRecords().size();
-         for (Tile t : tiles) {
+         for (AlignmentTile t : tiles) {
              recordCount += t.getContainedRecords().size();
          }
  
          List<Alignment> alignments = new ArrayList(recordCount);
          alignments.addAll(tiles.get(0).getOverlappingRecords());
-         for (Tile t : tiles) {
+         for (AlignmentTile t : tiles) {
              alignments.addAll(t.getContainedRecords());
+             counts.add(t.getCounts());
          }
          return new TiledIterator(start, end, alignments);
      }
  
-     private List<Tile> getTiles(String seq, int startTile, int endTile) {
+     public List<AlignmentTile> getTiles(String seq, int startTile, int endTile) {
  
          if (!seq.equals(cachedChr)) {
              cache.clear();
@@@ -122,18 -142,17 +173,22 @@@
          }
  
  
-         List<Tile> tiles = new ArrayList(endTile - startTile + 1);
-         List<Tile> tilesToLoad = new ArrayList(endTile - startTile + 1);
+         List<AlignmentTile> tiles = new ArrayList(endTile - startTile + 1);
+         List<AlignmentTile> tilesToLoad = new ArrayList(endTile - startTile + 1);
  
          int tileSize = getTileSize(seq);
          for (int t = startTile; t <= endTile; t++) {
-             Tile tile = cache.get(t);
+             AlignmentTile tile = cache.get(t);
  
              if (tile == null) {
                  int start = t * tileSize;
                  int end = start + tileSize;
++<<<<<<< HEAD
 +                tile = new Tile(t, start, end);
 +                cache.put(t, tile);
++=======
+                 tile = new AlignmentTile(seq, t, start, end);
++>>>>>>> upstream/1.5.56
              }
  
              tiles.add(tile);
@@@ -158,11 -177,17 +213,25 @@@
          return tiles;
      }
  
++<<<<<<< HEAD
 +    private boolean loadTiles(String seq, List<Tile> tiles) {
 +
 +        assert (tiles.size() > 0);
 +
 +        maxReadCount = PreferenceManager.getInstance().getSAMPreferences().getMaxReads();
++=======
+     private boolean loadTiles(String seq, List<AlignmentTile> tiles) {
+ 
+         assert (tiles.size() > 0);
+ 
+ 
+         final PreferenceManager.SAMPreferences prefs = PreferenceManager.getInstance().getSAMPreferences();
+         final int qualityThreshold = prefs.getQualityThreshold();
+         boolean filterFailedReads = prefs.isFilterFailedReads();
+         ReadGroupFilter filter = ReadGroupFilter.getFilter();
+         boolean showDuplicates = prefs.isShowDuplicates();
+         //maxReadCount = PreferenceManager.getInstance().getAsInt(PreferenceManager.SAM_MAX_READS);
++>>>>>>> upstream/1.5.56
  
          if (log.isDebugEnabled()) {
              int first = tiles.get(0).getTileNumber();
@@@ -177,12 -202,27 +246,27 @@@
          //log.debug("Loading : " + start + " - " + end);
          int alignmentCount = 0;
          try {
+             activeReaders.add(new WeakReference(this));
              iter = reader.query(seq, start, end, false);
  
              int tileSize = getTileSize(seq);
              while (iter != null && iter.hasNext()) {
+ 
+                 if (cancel) {
+                     return false;
+                 }
+ 
                  Alignment record = iter.next();
  
+ 
+                 if (!record.isMapped() ||
+                         (!showDuplicates && record.isDuplicate()) ||
+                         (filterFailedReads && record.isVendorFailedRead()) ||
+                         record.getMappingQuality() < qualityThreshold ||
+                         (filter != null && filter.filterAlignment(record))) {
+                     continue;
+                 }
+ 
                  // Range of tile indeces that this alignment contributes to.
                  int aStart = record.getAlignmentStart();
                  int aEnd = record.getEnd();
@@@ -191,36 -231,24 +275,42 @@@
  
                  // Loop over tiles this read overlaps
                  for (int i = idx0; i <= idx1; i++) {
-                     Tile t = tiles.get(i);
- 
-                     if ((aStart >= t.start) && (aStart < t.end)) {
-                         t.containedRecords.add(record);
-                     } else if ((aEnd >= t.start) && (aStart < t.start)) {
-                         t.overlappingRecords.add(record);
-                     }
+                     AlignmentTile t = tiles.get(i);
+                     t.addRecord(record);
                  }
  
                  alignmentCount++;
++<<<<<<< HEAD
 +                if (alignmentCount % MITOCHONDRIA_TILE_SIZE == 0) {
 +                    IGVMainFrame.getInstance().setStatusBarMessage("Reads loaded: " + alignmentCount);
 +                    if (checkMemory() == false) {
 +                        return false;
 +                    }
 +                }
 +
 +                if (alignmentCount > maxReadCount) {
 +                    String msg = "Maximum # of reads exceeded (" + maxReadCount + "). Continue?";
 +                    int v = JOptionPane.showConfirmDialog(null, msg, msg, JOptionPane.YES_NO_OPTION);
 +                    if (v == JOptionPane.YES_OPTION) {
 +                        maxReadCount = Math.min(Integer.MAX_VALUE, 2 * maxReadCount);
 +                    } else {
 +                        break;
 +                    }
++=======
+                 if (alignmentCount % 1000 == 0) {
+                     if (cancel) return false;
+                     IGVMainFrame.getInstance().setStatusBarMessage("Reads loaded: " + alignmentCount);
+                     if (checkMemory() == false) {
+                         cancelReaders();
+                         return false;
+                     }
++>>>>>>> upstream/1.5.56
                  }
              }
  
-             for (Tile t : tiles) {
+             for (AlignmentTile t : tiles) {
                  t.setLoaded(true);
+                 cache.put(t.getTileNumber(), t);
              }
  
              return true;
@@@ -231,6 -259,10 +321,10 @@@
          }
  
          finally {
+             // reset cancel flag.  It doesn't matter how we got here,  the read is complete and this flag is reset
+             // for the next time
+             cancel = false;
+             activeReaders.remove(this);
              if (iter != null) {
                  iter.close();
              }
@@@ -238,10 -270,16 +332,23 @@@
          }
      }
  
++<<<<<<< HEAD
 +    private boolean checkMemory() {
 +        if (RuntimeUtils.getAvailableMemory() < LOW_MEMORY_THRESHOLD) {
 +            LRUCache.clearCaches();
 +            if (RuntimeUtils.getAvailableMemory() < LOW_MEMORY_THRESHOLD) {
++=======
+     private static synchronized int confirmMaxReadCount(String msg) {
+         log.debug("Enter max read count");
+         return JOptionPane.showConfirmDialog(null, msg, msg, JOptionPane.YES_NO_OPTION);
+     }
+ 
+     private static synchronized boolean checkMemory() {
+         if (RuntimeUtils.getAvailableMemoryFraction() < 0.2) {
+             LRUCache.clearCaches();
+             System.gc();
+             if (RuntimeUtils.getAvailableMemoryFraction() < 0.2) {
++>>>>>>> upstream/1.5.56
                  String msg = "Memory is low, reading terminating.";
                  MessageUtils.showMessage(msg);
                  return false;
@@@ -261,7 -299,84 +368,84 @@@
          }
      }
  
-     static class Tile {
+     public void clearCache() {
+         if (cache != null) cache.clear();
+     }
+ 
+ 
+     public class TiledIterator implements CloseableIterator<Alignment> {
+ 
+         Iterator<Alignment> currentSamIterator;
+         int end;
+         Alignment nextRecord;
+         int start;
+         List<Alignment> alignments;
+ 
+         TiledIterator(int start, int end, List<Alignment> alignments) {
+             this.alignments = alignments;
+             this.start = start;
+             this.end = end;
+             currentSamIterator = alignments.iterator();
+             advanceToFirstRecord();
+         }
+ 
+         public void close() {
+             // No-op
+         }
+ 
+         public boolean hasNext() {
+             return nextRecord != null;
+         }
+ 
+         public Alignment next() {
+             Alignment ret = nextRecord;
+ 
+             advanceToNextRecord();
+ 
+             return ret;
+         }
+ 
+         public void remove() {
+             // ignored
+         }
+ 
+         private void advanceToFirstRecord() {
+             advanceToNextRecord();
+         }
+ 
+         private void advanceToNextRecord() {
+             advance();
+ 
+             while ((nextRecord != null) && (nextRecord.getEnd() < start)) {
+                 advance();
+             }
+         }
+ 
+         private void advance() {
+             if (currentSamIterator.hasNext()) {
+                 nextRecord = currentSamIterator.next();
+                 if (nextRecord.getAlignmentStart() > end) {
+                     nextRecord = null;
+                 }
+             } else {
+                 nextRecord = null;
+             }
+         }
+ 
+ 
+     }
+ 
+     /**
+      * Caches alignments and counts for the coverage plot.
+      * <p/>
+      * Notes:
+      * A "bucket" is a virtual container holding all the alignments with identical start position.  The concept
+      * is introduced to control the # of alignments we hold in memory for deep coverage regions.  In practice,
+      * little or no information is added by displaying more than ~50X coverage.  For an average alignment length L
+      * and coverage deptgh D we do not need to store more than D/L alignments at any given start position.
+      */
+ 
+     public static class AlignmentTile {
  
          private boolean loaded = false;
          private List<Alignment> containedRecords;
@@@ -269,13 -384,29 +453,29 @@@
          private List<Alignment> overlappingRecords;
          private int start;
          private int tileNumber;
+         private AlignmentCounts counts;
  
-         Tile(int tileNumber, int start, int end) {
+         /**
+          * Maximum # of alignments to load with a given start position
+          */
+         int maxBucketSize;
+         private int lastStart = -1;
+         private List<Alignment> currentBucket;
+ 
+ 
+         AlignmentTile(String chr, int tileNumber, int start, int end) {
              this.tileNumber = tileNumber;
              this.start = start;
              this.end = end;
              containedRecords = new ArrayList(16000);
              overlappingRecords = new ArrayList();
+             this.counts = new AlignmentCounts(chr, start, end);
+ 
+             int maxDepth = PreferenceManager.getInstance().getSAMPreferences().getMaxLevels();
+ 
+             // TODO -- compute this value from the data 
+             maxBucketSize = (maxDepth / 10) + 1;
+             currentBucket = new ArrayList(5 * maxBucketSize);
          }
  
          public int getTileNumber() {
@@@ -291,90 -422,453 +491,475 @@@
              this.start = start;
          }
  
++<<<<<<< HEAD
++=======
+         public void addRecord(Alignment record) {
+             if (lastStart != record.getStart()) {
+                 emptyBucket();
+                 lastStart = record.getStart();
+ 
+             }
+             currentBucket.add(record);
+             counts.incCounts(record);
+         }
+ 
+ 
+         private void emptyBucket() {
+             List<Alignment> sampledRecords = sampleCurrentBucket();
+             for (Alignment alignment : sampledRecords) {
+                 int aStart = alignment.getAlignmentStart();
+                 int aEnd = alignment.getEnd();
+                 if ((aStart >= start) && (aStart < end)) {
+                     containedRecords.add(alignment);
+                 } else if ((aEnd >= start) && (aStart < start)) {
+                     overlappingRecords.add(alignment);
+                 }
+             }
+             currentBucket.clear();
+         }
+ 
+ 
+         private List<Alignment> sampleCurrentBucket() {
+             if (currentBucket.size() < maxBucketSize) {
+                 return currentBucket;
+             }
+ 
+             Random rand = new Random(System.currentTimeMillis()); // would make this static to the class
+ 
+             List subsetList = new ArrayList(maxBucketSize);
+             for (int i = 0; i < maxBucketSize; i++) {
+                 // be sure to use Vector.remove() or you may get the same item twice
+                 subsetList.add(currentBucket.remove(rand.nextInt(currentBucket.size())));
+             }
+ 
+             return subsetList;
+         }
+ 
+ 
++>>>>>>> upstream/1.5.56
          public List<Alignment> getContainedRecords() {
              return containedRecords;
          }
  
++<<<<<<< HEAD
 +        public void setContainedRecords(List<Alignment> containedRecords) {
 +            this.containedRecords = containedRecords;
 +        }
++=======
++>>>>>>> upstream/1.5.56
  
          public List<Alignment> getOverlappingRecords() {
              return overlappingRecords;
          }
  
++<<<<<<< HEAD
 +        public void setOverlappingRecords(List<Alignment> overlappingRecords) {
 +            this.overlappingRecords = overlappingRecords;
 +        }
 +
++=======
++>>>>>>> upstream/1.5.56
          public boolean isLoaded() {
              return loaded;
          }
  
          public void setLoaded(boolean loaded) {
              this.loaded = loaded;
+ 
+             // Empty any remaining alignments in the current bucket
+             emptyBucket();
+ 
          }
  
+         public AlignmentCounts getCounts() {
+             return counts;
+         }
      }
  
-     public class TiledIterator implements CloseableIterator<Alignment> {
+     public static class AlignmentCounts {
  
++<<<<<<< HEAD
 +        Iterator<Alignment> currentSamIterator;
 +        int end;
 +        Alignment nextRecord;
++=======
+         String genomeId;
+         //String chr;
++>>>>>>> upstream/1.5.56
          int start;
-         List<Alignment> alignments;
- 
-         TiledIterator(int start, int end, List<Alignment> alignments) {
-             this.alignments = alignments;
+         int end;
+         byte[] reference;
+         // counts
+         int[] posA;
+         int[] posT;
+         int[] posC;
+         int[] posG;
+         int[] posN;
+         int[] negA;
+         int[] negT;
+         int[] negC;
+         int[] negG;
+         int[] negN;
+         int[] qA;
+         int[] qT;
+         int[] qC;
+         int[] qG;
+         int[] qN;
+         int[] posTotal;
+         int[] negTotal;
+         private int[] totalQ;
+         private int maxCount = 0;
+ 
+         public AlignmentCounts(String chr, int start, int end) {
+ 
+             Genome genome = ViewContext.getInstance().getGenome();
+             this.genomeId = genome.getId();
+             String chrAlias = genome.getChromosomeAlias(chr);
              this.start = start;
              this.end = end;
-             currentSamIterator = alignments.iterator();
-             advanceToFirstRecord();
+             reference = SequenceManager.readSequence(this.genomeId, chrAlias, start, end);
+ 
+             int nPts = end - start;
+             posA = new int[nPts];
+             posT = new int[nPts];
+             posC = new int[nPts];
+             posG = new int[nPts];
+             posN = new int[nPts];
+             posTotal = new int[nPts];
+             negA = new int[nPts];
+             negT = new int[nPts];
+             negC = new int[nPts];
+             negG = new int[nPts];
+             negN = new int[nPts];
+             negTotal = new int[nPts];
+             qA = new int[nPts];
+             qT = new int[nPts];
+             qC = new int[nPts];
+             qG = new int[nPts];
+             qN = new int[nPts];
+             totalQ = new int[nPts];
          }
  
-         public void close() {
-             // No-op
+         public int getTotalCount(int pos) {
+             int offset = pos - start;
+             if (offset < 0 || offset >= posA.length) {
+                 if (log.isDebugEnabled()) {
+                     log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
+                 }
+                 return 0;
+             } else {
+                 return posTotal[offset] + negTotal[offset];
+ 
+             }
          }
  
-         public boolean hasNext() {
-             return nextRecord != null;
+         public int getNegTotal(int pos) {
+             int offset = pos - start;
+             if (offset < 0 || offset >= posA.length) {
+                 if (log.isDebugEnabled()) {
+                     log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
+                 }
+                 return 0;
+             } else {
+                 return negTotal[offset];
+ 
+             }
          }
  
-         public Alignment next() {
-             Alignment ret = nextRecord;
+         public int getPosTotal(int pos) {
+             int offset = pos - start;
+             if (offset < 0 || offset >= posA.length) {
+                 if (log.isDebugEnabled()) {
+                     log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
+                 }
+                 return 0;
+             } else {
+                 return posTotal[offset];
  
-             advanceToNextRecord();
+             }
+         }
  
-             return ret;
+         public int getTotalQuality(int pos) {
+             int offset = pos - start;
+             if (offset < 0 || offset >= posA.length) {
+                 if (log.isDebugEnabled()) {
+                     log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
+                 }
+                 return 0;
+             } else {
+                 return totalQ[offset];
+ 
+             }
          }
  
-         public void remove() {
-             // ignored
+         public int getAvgQuality(int pos) {
+             int count = getTotalCount(pos);
+             return count == 0 ? 0 : getTotalQuality(pos) / count;
          }
  
-         private void advanceToFirstRecord() {
-             advanceToNextRecord();
+         public byte getReference(int pos) {
+             if (reference == null) {
+                 return 0;
+             }
+             int offset = pos - start;
+             if (offset < 0 || offset >= reference.length) {
+                 if (log.isDebugEnabled()) {
+                     log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
+                 }
+                 return 0;
+             } else {
+                 return reference[offset];
+             }
          }
  
-         private void advanceToNextRecord() {
-             advance();
+         public int getCount(int pos, byte b) {
+             int offset = pos - start;
+             if (offset < 0 || offset >= posA.length) {
+                 if (log.isDebugEnabled()) {
+                     log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
+                 }
+                 return 0;
+             } else {
+                 switch (b) {
+                     case 'a':
+                     case 'A':
+                         return posA[offset] + negA[offset];
+                     case 't':
+                     case 'T':
+                         return posT[offset] + negT[offset];
+                     case 'c':
+                     case 'C':
+                         return posC[offset] + negC[offset];
+                     case 'g':
+                     case 'G':
+                         return posG[offset] + negG[offset];
+                     case 'n':
+                     case 'N':
+                         return posN[offset] + negN[offset];
+                 }
+                 log.error("Unknown nucleotide: " + b);
+                 return 0;
+             }
+         }
  
-             while ((nextRecord != null) && (nextRecord.getEnd() < start)) {
-                 advance();
+         public int getNegCount(int pos, byte b) {
+             int offset = pos - start;
+             if (offset < 0 || offset >= posA.length) {
+                 if (log.isDebugEnabled()) {
+                     log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
+                 }
+                 return 0;
+             } else {
+                 switch (b) {
+                     case 'a':
+                     case 'A':
+                         return negA[offset];
+                     case 't':
+                     case 'T':
+                         return negT[offset];
+                     case 'c':
+                     case 'C':
+                         return negC[offset];
+                     case 'g':
+                     case 'G':
+                         return negG[offset];
+                     case 'n':
+                     case 'N':
+                         return negN[offset];
+                 }
+                 log.error("Unknown nucleotide: " + b);
+                 return 0;
              }
          }
  
-         private void advance() {
-             if (currentSamIterator.hasNext()) {
-                 nextRecord = currentSamIterator.next();
-                 if (nextRecord.getAlignmentStart() > end) {
-                     nextRecord = null;
+         public int getPosCount(int pos, byte b) {
+             int offset = pos - start;
+             if (offset < 0 || offset >= posA.length) {
+                 if (log.isDebugEnabled()) {
+                     log.debug("Position out of range: " + pos + " (valid range - " + start + "-" + end);
                  }
+                 return 0;
              } else {
-                 nextRecord = null;
+                 switch (b) {
+                     case 'a':
+                     case 'A':
+                         return posA[offset];
+                     case 't':
+                     case 'T':
+                         return posT[offset];
+                     case 'c':
+                     case 'C':
+                         return posC[offset];
+                     case 'g':
+                     case 'G':
+                         return posG[offset];
+                     case 'n':
+                     case 'N':
+                         return posN[offset];
+                 }
+                 log.error("Unknown nucleotide: " + b);
+                 return 0;
              }
          }
+ 
+         public int getQuality(int pos, byte b) {
+             int offset = pos - start;
+             if (offset < 0 || offset >= posA.length) {
+                 log.error("Position out of range: " + pos + " (valid range - " + start + "-" + end);
+                 return 0;
+             } else {
+                 switch (b) {
+                     case 'a':
+                     case 'A':
+                         return qA[offset];
+                     case 't':
+                     case 'T':
+                         return qT[offset];
+                     case 'c':
+                     case 'C':
+                         return qC[offset];
+                     case 'g':
+                     case 'G':
+                         return qG[offset];
+                     case 'n':
+                     case 'N':
+                         return qN[offset];
+                 }
+                 log.error("Unknown nucleotide: " + posN);
+                 return 0;
+             }
+         }
+ 
+         public int getAvgQuality(int pos, byte b) {
+             int count = getCount(pos, b);
+             return count == 0 ? 0 : getQuality(pos, b) / count;
+         }
+ 
+ 
+         // For alignments without blocks -- TODO refactor, this is ugly
+ 
+         void incCounts(Alignment alignment) {
+             int start = alignment.getAlignmentStart();
+             int end = alignment.getAlignmentEnd();
+ 
+             AlignmentBlock[] blocks = alignment.getAlignmentBlocks();
+             if (blocks != null) {
+                 for (AlignmentBlock b : blocks) {
+                     // Don't count softclips
+                     if (!b.isSoftClipped())
+                         incCounts(b, alignment.isNegativeStrand());
+                 }
+             } else {
+                 for (int pos = start; pos < end; pos++) {
+                     byte q = 0;
+                     incCount(pos, (byte) 'n', q, alignment.isNegativeStrand());
+                 }
+             }
+         }
+ 
+         private void incCounts(AlignmentBlock block, boolean isNegativeStrand) {
+             int start = block.getStart();
+             byte[] bases = block.getBases();
+             if (bases != null) {
+                 for (int i = 0; i < bases.length; i++) {
+                     int pos = start + i;
+                     byte q = block.getQuality(i);
+                     // TODO -- handle "="
+                     byte n = bases[i];
+                     incCount(pos, n, q, isNegativeStrand);
+                 }
+             }
+         }
+ 
+         private void incCount(int pos, byte b, byte q, boolean isNegativeStrand) {
+ 
+             int offset = pos - start;
+             if (offset > 0 && offset < posA.length) {
+                 switch (b) {
+                     case 'a':
+                     case 'A':
+                         if (isNegativeStrand) {
+                             negA[offset] = negA[offset] + 1;
+                         } else {
+                             posA[offset] = posA[offset] + 1;
+                         }
+                         qA[offset] = qA[offset] + q;
+                         break;
+                     case 't':
+                     case 'T':
+                         if (isNegativeStrand) {
+                             negT[offset] = negT[offset] + 1;
+                         } else {
+                             posT[offset] = posT[offset] + 1;
+                         }
+                         qT[offset] = qT[offset] + q;
+                         break;
+                     case 'c':
+                     case 'C':
+                         if (isNegativeStrand) {
+                             negC[offset] = negC[offset] + 1;
+                         } else {
+                             posC[offset] = posC[offset] + 1;
+                         }
+                         qC[offset] = qC[offset] + q;
+                         break;
+                     case 'g':
+                     case 'G':
+                         if (isNegativeStrand) {
+                             negG[offset] = negG[offset] + 1;
+                         } else {
+                             posG[offset] = posG[offset] + 1;
+                         }
+                         qG[offset] = qG[offset] + q;
+                         break;
+                     case 'n':
+                     case 'N':
+                         if (isNegativeStrand) {
+                             negN[offset] = negN[offset] + 1;
+                         } else {
+                             posN[offset] = posN[offset] + 1;
+                         }
+                         qN[offset] = qN[offset] + q;
+ 
+                 }
+                 if (isNegativeStrand) {
+                     negTotal[offset] = negTotal[offset] + 1;
+                 } else {
+                     posTotal[offset] = posTotal[offset] + 1;
+                 }
+                 totalQ[offset] = totalQ[offset] + q;
+ 
+                 maxCount = Math.max(posTotal[offset] + negTotal[offset], maxCount);
+             }
+         }
+ 
+         /**
+          * @return the start
+          */
+         public int getStart() {
+             return start;
+         }
+ 
+         /**
+          * @return the end
+          */
+         public int getEnd() {
+             return end;
+         }
+ 
+         /**
+          * @return the totalQ
+          */
+         public int[] getTotalQ() {
+             return totalQ;
+         }
+ 
+         /**
+          * @return the maxCount
+          */
+         public int getMaxCount() {
+             return maxCount;
+         }
      }
  }
  
diff --combined src/org/broad/igv/sam/reader/FeatureIndex.java
index 23ee705,16ac924..6656163
--- a/src/org/broad/igv/sam/reader/FeatureIndex.java
+++ b/src/org/broad/igv/sam/reader/FeatureIndex.java
@@@ -19,10 -19,13 +19,19 @@@ package org.broad.igv.sam.reader
  
  //~--- non-JDK imports --------------------------------------------------------
  
++<<<<<<< HEAD
++=======
+ import org.apache.log4j.Logger;
+ import org.broad.igv.exceptions.DataLoadException;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.feature.Genome;
  import org.broad.igv.session.ViewContext;
  import org.broad.igv.util.ParsingUtils;
  import org.broad.igv.util.ResourceLocator;
++<<<<<<< HEAD
++=======
+ import sun.management.Agent;
++>>>>>>> upstream/1.5.56
  
  import java.io.*;
  import java.util.*;
@@@ -34,6 -37,7 +43,7 @@@ public class FeatureIndex 
  
      private int tileWidth;
      private Map<String, ChromosomeIndex> chrIndeces;
+     private Logger log = Logger.getLogger(FeatureIndex.class);
  
      /**
       * Constructs ...
@@@ -62,8 -66,8 +72,13 @@@
              chrIndeces = new LinkedHashMap();
              read(is);
          } catch (IOException ex) {
++<<<<<<< HEAD
 +            // TODO log properly
 +            ex.printStackTrace();
++=======
+             log.error("Error reading index", ex);
+             throw new DataLoadException("Error reading index: " + ex.getMessage(), path);
++>>>>>>> upstream/1.5.56
          } finally {
              if (is != null) {
                  try {
@@@ -163,26 -167,31 +178,54 @@@
       * @throws IOException
       */
      private void read(InputStream is) throws IOException {
++<<<<<<< HEAD
 +
 +        DataInputStream dis = new DataInputStream(new BufferedInputStream(is));
 +
 +        tileWidth = dis.readInt();
 +        while (dis.available() != 0) {
 +
 +            String chr = dis.readUTF();
 +            int nTiles = dis.readInt();
 +            int longestFeature = dis.readInt();
 +
 +            List<TileDef> tileDefs = new ArrayList(nTiles);
 +            int tileNumber = 0;
 +            while (dis.available() != 0 && tileNumber < nTiles) {
 +                long pos = dis.readLong();
 +                int count = dis.readInt();
 +                tileDefs.add(new TileDef(pos, count));
 +                tileNumber++;
 +            }
 +
 +            chrIndeces.put(chr, new ChromosomeIndex(longestFeature, tileDefs));
++=======
+ 
+         DataInputStream dis = new DataInputStream(new BufferedInputStream(is));
+ 
+         tileWidth = dis.readInt();
+         try {
+             while (true) {
+                 String chr = dis.readUTF();
+                 int nTiles = dis.readInt();
+                 int longestFeature = dis.readInt();
+ 
+                 List<TileDef> tileDefs = new ArrayList(nTiles);
+                 int tileNumber = 0;
+                 while (tileNumber < nTiles) {
+                     long pos = dis.readLong();
+                     int count = dis.readInt();
+                     tileDefs.add(new TileDef(pos, count));
+                     tileNumber++;
+                 }
+ 
+                 chrIndeces.put(chr, new ChromosomeIndex(longestFeature, tileDefs));
+             }
+         } catch (EOFException e) {
+             // This is normal.  Unfortuantely we don't have a better way to test EOF for this stream
+         }  catch(UTFDataFormatException e) {
+             log.error("Error reading chromosome name. ", e);
++>>>>>>> upstream/1.5.56
          }
  
      }
diff --combined src/org/broad/igv/sam/reader/GeraldParser.java
index 2948f2b,de78e86..8c38ce9
--- a/src/org/broad/igv/sam/reader/GeraldParser.java
+++ b/src/org/broad/igv/sam/reader/GeraldParser.java
@@@ -167,7 -167,7 +167,11 @@@ public class GeraldParser implements Al
      // TODO -- move this ot a utility class,  "loadMap(map, file)"
      static synchronized void loadChrMap() {
          seqChrMap = new HashMap();
++<<<<<<< HEAD
 +        File samDir = new File(UIConstants.DEFAULT_IGV_DIRECTORY, "sam");
++=======
+         File samDir = new File(UIConstants.getIgvDirectory(), "sam");
++>>>>>>> upstream/1.5.56
          if (samDir.exists()) {
              File mapFile = new File(samDir, "sequence.map");
              if (!mapFile.exists()) {
diff --combined src/org/broad/igv/sam/reader/GeraldQueryReader.java
index 322bdc3,65fc57c..91e180f
--- a/src/org/broad/igv/sam/reader/GeraldQueryReader.java
+++ b/src/org/broad/igv/sam/reader/GeraldQueryReader.java
@@@ -26,6 -26,7 +26,7 @@@ import net.sf.samtools.SAMFileHeader
  import net.sf.samtools.util.AsciiLineReader;
  import net.sf.samtools.util.CloseableIterator;
  import org.apache.log4j.Logger;
+ import org.broad.igv.exceptions.DataLoadException;
  import org.broad.igv.sam.Alignment;
  import org.broad.igv.sam.EmptyAlignmentIterator;
  
@@@ -45,12 -46,16 +46,16 @@@ public class GeraldQueryReader implemen
      private static Logger log = Logger.getLogger(GeraldQueryReader.class);
      static int MAX_READ_LENGTH = 100;
      static int maxTileCount = 20;
-     File alignmentFile;
+     String alignmentFile;
      FeatureIndex featureIndex;
      FileInputStream is;
      AlignmentParser parser;
  
-     public GeraldQueryReader(File alignmentFile) {
+     public GeraldQueryReader(String alignmentFile) {
+         this(alignmentFile, true);
+     }
+ 
+     public GeraldQueryReader(String alignmentFile, boolean requireIndex) {
          this.alignmentFile = alignmentFile;
          parser = getParserFor(alignmentFile);
          try {
@@@ -58,17 -63,16 +63,21 @@@
          } catch (FileNotFoundException fileNotFoundException) {
              fileNotFoundException.printStackTrace();
          }
-     }
- 
-     public GeraldQueryReader(File samFile, File indexFile) {
-         this.alignmentFile = samFile;
-         if (indexFile.exists()) {
-             featureIndex = new FeatureIndex(indexFile);
+         if (requireIndex) {
+             featureIndex = SamUtils.getIndexFor(alignmentFile);
+             if (featureIndex == null) {
+                 throw new DataLoadException("Could not locate index file.", alignmentFile);
+             }
          }
      }
  
++<<<<<<< HEAD
 +    private static AlignmentParser getParserFor(File file) {
 +        String fn = file.getName().toLowerCase();
++=======
+ 
+     private static AlignmentParser getParserFor(String fn) {
++>>>>>>> upstream/1.5.56
          if (fn.endsWith(".aligned") || (fn.endsWith(".aligned.txt"))) {
              return new DotAlignedParser();
          } else if (fn.endsWith(".bedz") || fn.endsWith(".bed")) {
diff --combined src/org/broad/igv/sam/reader/SamQueryReaderFactory.java
index eef155f,c6de75f..ba63701
--- a/src/org/broad/igv/sam/reader/SamQueryReaderFactory.java
+++ b/src/org/broad/igv/sam/reader/SamQueryReaderFactory.java
@@@ -18,9 -18,13 +18,13 @@@
  package org.broad.igv.sam.reader;
  
  import net.sf.samtools.SAMFileReader;
+ import org.apache.log4j.Logger;
+ import org.broad.igv.exceptions.DataLoadException;
  import org.broad.igv.util.ResourceLocator;
+ import sun.management.Agent;
  
  import java.io.File;
+ import java.io.IOException;
  import java.net.MalformedURLException;
  import java.net.URL;
  
@@@ -28,64 -32,69 +32,97 @@@
   * @author jrobinso
   */
  public class SamQueryReaderFactory {
+     private static Logger log = Logger.getLogger(SamQueryReaderFactory.class);
  
      static {
          SAMFileReader.setDefaultValidationStringency(SAMFileReader.ValidationStringency.SILENT);
      }
  
-     public static AlignmentQueryReader getReader(String path, boolean cache) {
-         return getReader(new ResourceLocator(path), cache);
+     public static AlignmentQueryReader getReader(String path, boolean cacheAndIndex) {
+         return getReader(new ResourceLocator(path), cacheAndIndex);
      }
  
      public static AlignmentQueryReader getReader(ResourceLocator locator) {
          return getReader(locator, true);
      }
  
-     public static AlignmentQueryReader getReader(ResourceLocator locator, boolean cache) {
+     public static AlignmentQueryReader getReader(ResourceLocator locator, boolean requireIndex) {
  
          String path = locator.getPath().toLowerCase();
  
  
          AlignmentQueryReader reader = null;
  
++<<<<<<< HEAD
 +        if (locator.isLocal()) {
 +            File samFile = new File(locator.getPath());
 +            if (path.endsWith(".bam")) {
 +                reader = new BAMQueryReader(samFile);
 +            } else if (path.endsWith(".sam")) {
 +                //return new SamInMemoryQueryReader(samFile);
 +                reader = new SamQueryTextReader(samFile);
 +            } else if (path.endsWith("sorted.txt")
 +                    || path.endsWith(".aligned")
 +                    || path.endsWith(".aligned.txt")
 +                    || path.endsWith("bedz")
 +                    || path.endsWith("bed")
 +                    || path.endsWith("psl")
 +                    || path.endsWith("pslx")) {
 +                reader = new GeraldQueryReader(samFile);
 +            } else {
 +                throw new RuntimeException("Unknown file type: " + locator.getPath());
 +            }
 +        } else {
 +            if (locator.getPath().toLowerCase().startsWith("http:") ||
++=======
+         String samFile = locator.getPath();
+         if (path.endsWith(".sam")) {
+             try {
+                 reader = new SamQueryTextReader(samFile, requireIndex);
+             } catch (IOException e) {
+                 e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+             }
+         } else if (path.endsWith("sorted.txt")
+                 || path.endsWith(".aligned")
+                 || path.endsWith(".aligned.txt")
+                 || path.endsWith("bedz")
+                 || path.endsWith("bed")
+                 || path.endsWith("psl")
+                 || path.endsWith("pslx")) {
+             reader = new GeraldQueryReader(samFile, requireIndex);
+         } else if (path.endsWith(".bam")) {
+             if (locator.isLocal()) {
+                 reader = new BAMQueryReader(new File(samFile));
+             } else if (locator.getPath().toLowerCase().startsWith("http:") ||
++>>>>>>> upstream/1.5.56
                      locator.getPath().toLowerCase().startsWith("https:") ||
                      locator.getPath().toLowerCase().startsWith("ftp:")) {
                  try {
                      URL url = new URL(locator.getPath());
-                     reader = new BAMHttpQueryReader(url);
+                     reader = new BAMHttpQueryReader(url, requireIndex);
                  }
                  catch (MalformedURLException e) {
-                     // todo log
-                     e.printStackTrace();
-                     return null;
+                     log.error("", e);
+                     throw new DataLoadException("Error loading BAM file: " + e.toString(),
+                             locator.getPath());
  
                  }
++<<<<<<< HEAD
 +            } else {
 +                reader = new BAMRemoteQueryReader(locator);
++=======
++>>>>>>> upstream/1.5.56
+             }
+             else {
+                 reader = new BAMRemoteQueryReader(locator);
              }
+         } else if (path.endsWith(".bam.list")) {
+             reader = new BAMRemoteQueryReader(locator);
+         }  else {
+             throw new RuntimeException("No reader found for alignment file: " + locator.getPath());
          }
  
-         return cache ? new CachingQueryReader(reader) : reader;
+         return  reader;
      }
  }
  
diff --combined src/org/broad/igv/sam/reader/SamQueryTextReader.java
index 8deba52,adc6c69..1229ae9
--- a/src/org/broad/igv/sam/reader/SamQueryTextReader.java
+++ b/src/org/broad/igv/sam/reader/SamQueryTextReader.java
@@@ -28,9 -28,14 +28,14 @@@ import net.sf.samtools.SAMFileReader.Va
  import net.sf.samtools.SAMRecord;
  import net.sf.samtools.util.CloseableIterator;
  import org.apache.log4j.Logger;
+ import org.broad.igv.Globals;
+ import org.broad.igv.exceptions.DataLoadException;
  import org.broad.igv.sam.Alignment;
  import org.broad.igv.sam.EmptyAlignmentIterator;
  import org.broad.igv.sam.SamAlignment;
+ import org.broad.igv.util.FileUtils;
+ import org.broad.igv.util.SeekableStream;
+ import org.broad.igv.util.SeekableStreamFactory;
  
  import java.io.File;
  import java.io.FileInputStream;
@@@ -45,20 -50,26 +50,26 @@@ import java.util.Set
  public class SamQueryTextReader implements AlignmentQueryReader {
  
      static Logger log = Logger.getLogger(SamQueryTextReader.class);
-     File samFile;
+     String samFile;
+     SeekableStream stream;
      FeatureIndex featureIndex;
-     FileInputStream is;
      SAMFileHeader header;
  
-     public SamQueryTextReader(File samFile) {
-         this.samFile = samFile;
-         loadHeader();
+ 
+     public SamQueryTextReader(String samFile) throws IOException {
+         this(samFile, true);
      }
  
-     public SamQueryTextReader(File samFile, File indexFile) {
+     public SamQueryTextReader(String samFile, boolean requireIndex) throws IOException {
          this.samFile = samFile;
-         if (indexFile.exists()) {
-             featureIndex = new FeatureIndex(indexFile);
+         stream = SeekableStreamFactory.getStreamFor(samFile);
+         loadHeader();
+ 
+         if (requireIndex) {
+             featureIndex = SamUtils.getIndexFor(samFile);
+             if (featureIndex == null) {
+                 throw new DataLoadException("Could not locate index file.", samFile);
+             }
          }
      }
  
@@@ -70,12 -81,12 +81,12 @@@
      }
  
      private void loadHeader() {
-         SAMFileReader reader = new SAMFileReader(samFile);
+         SAMFileReader reader = new SAMFileReader(stream);
          header = reader.getFileHeader();
          reader.close();
      }
  
-     public CloseableIterator<Alignment> query(final String sequence, final int start, final int end, final boolean contained) {
+     public synchronized CloseableIterator<Alignment> query(final String sequence, final int start, final int end, final boolean contained) {
  
          if (featureIndex == null) {
              featureIndex = SamUtils.getIndexFor(samFile);
@@@ -99,10 -110,10 +110,10 @@@
  
              try {
                  // Skip to the start of the chromosome (approximate)
-                 is = new FileInputStream(samFile);
-                 is.getChannel().position(seekPos.getStartPosition());
- 
-                 SAMFileReader reader = new SAMFileReader(is);
+                 stream.close();
+                 stream = SeekableStreamFactory.getStreamFor(samFile);
+                 stream.seek(seekPos.getStartPosition());
+                 SAMFileReader reader = new SAMFileReader(stream);
                  reader.setValidationStringency(ValidationStringency.SILENT);
  
                  CloseableIterator<SAMRecord> iter = reader.iterator();
@@@ -117,14 -128,15 +128,15 @@@
  
      public boolean hasIndex() {
          if (featureIndex == null) {
-             featureIndex = SamUtils.getIndexFor(samFile);
+             getIndex();
          }
          return featureIndex != null;
      }
  
      public void close() throws IOException {
-         if (is != null) {
-             is.close();
+         if (stream != null) {
+             stream.close();
+             stream = null;
          }
      }
  
@@@ -135,20 -147,19 +147,29 @@@
          }
          return featureIndex;
      }
++<<<<<<< HEAD
 +    
 +    public Set<String> getSequenceNames() {
 +        FeatureIndex idx = getIndex();
 +        if(idx == null) {
 +            return null;
 +        }
 +        else {
++=======
+ 
+     public Set<String> getSequenceNames() {
+         FeatureIndex idx = getIndex();
+         if (idx == null) {
+             return null;
+         } else {
++>>>>>>> upstream/1.5.56
              return idx.getIndexedChromosomes();
          }
  
      }
  
      public CloseableIterator<Alignment> iterator() {
-         SAMFileReader reader = new SAMFileReader(samFile);
+         SAMFileReader reader = new SAMFileReader(stream);
          reader.setValidationStringency(ValidationStringency.SILENT);
          CloseableIterator<SAMRecord> iter = reader.iterator();
          return new SAMQueryIterator(iter);
diff --combined src/org/broad/igv/sam/reader/SamUtils.java
index c687cac,147b268..9cce7f9
--- a/src/org/broad/igv/sam/reader/SamUtils.java
+++ b/src/org/broad/igv/sam/reader/SamUtils.java
@@@ -40,16 -40,25 +40,25 @@@ public class SamUtils 
      // 10 KB window
      private static int DEFAULT_TILE_WIDTH = 100000;
  
-     public static FeatureIndex getIndexFor(File samFile) {
- 
-         File idxFile = new File(samFile.getAbsolutePath() + ".sai");
-         if (!idxFile.exists()) {
-             idxFile = getUserIdxFile(samFile);
-         }
-         if (idxFile.exists() && idxFile.lastModified() > samFile.lastModified()) {
-             return new FeatureIndex(idxFile);
+     public static FeatureIndex getIndexFor(String samPath) {
+ 
+         String idxPath = samPath + ".sai";
+ 
+         if (FileUtils.resourceExists(idxPath)) {
+             return new FeatureIndex(idxPath);
+         } else if (!FileUtils.isRemote(idxPath)) {
+             File idxFile = new File(idxPath);
+             File samFile = new File(samPath);
+             if (!idxFile.exists()) {
+                 idxFile = getUserIdxFile(samFile);
+             }
+             if (idxFile.exists() && idxFile.lastModified() > samFile.lastModified()) {
+                 return new FeatureIndex(idxFile);
+             } else {
+                 return createIndexFor(samFile);
+             }
          } else {
-             return createIndexFor(samFile);
+             return null;
          }
      }
  
@@@ -67,7 -76,7 +76,11 @@@
  
      private static File getUserIdxFile(File samFile) {
          File idxFile;
++<<<<<<< HEAD
 +        File samDir = new File(UIConstants.DEFAULT_IGV_DIRECTORY, "sam");
++=======
+         File samDir = new File(UIConstants.getIgvDirectory(), "sam");
++>>>>>>> upstream/1.5.56
          //Need the path information to distinguish like name indeces in separate
          // directories.
          idxFile = new File(samDir, samFile.getName() + "_" + samFile.getParent().hashCode() + ".sai");
diff --combined src/org/broad/igv/session/Session.java
index 5d32c40,1bd2b55..8cb5aa7
--- a/src/org/broad/igv/session/Session.java
+++ b/src/org/broad/igv/session/Session.java
@@@ -24,8 -24,12 +24,17 @@@ package org.broad.igv.session
  
  import org.apache.log4j.Logger;
  import org.broad.igv.PreferenceManager;
++<<<<<<< HEAD
 +import org.broad.igv.renderer.ContinuousColorScale;
 +import org.broad.igv.track.TrackType;
++=======
+ import org.broad.igv.feature.Feature;
+ import org.broad.igv.feature.FeatureDB;
+ import org.broad.igv.feature.Genome;
+ import org.broad.igv.renderer.ContinuousColorScale;
+ import org.broad.igv.track.TrackType;
+ import org.broad.igv.ui.IGVMainFrame;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.ui.RegionOfInterest;
  import org.broad.igv.ui.TrackFilter;
  import org.broad.igv.ui.util.MessageUtils;
@@@ -59,7 -63,7 +68,11 @@@ public class Session 
          regionsOfInterest = new LinkedHashMap();
          preferences = new HashMap();
          colorScales = new HashMap();
++<<<<<<< HEAD
 +        
++=======
+ 
++>>>>>>> upstream/1.5.56
      }
  
  
@@@ -138,7 -142,11 +151,15 @@@
  
  
      public String getLocus() {
++<<<<<<< HEAD
 +        return getViewContext().getCurrentLocusString();
++=======
+         ViewContext.Range range = getViewContext().getCurrentRange();
+         String startStr = String.valueOf(range.getStart());
+         String endStr = String.valueOf(range.getEnd());
+         String position = range.getChr() + ":" + startStr + "-" + endStr;
+         return position;
++>>>>>>> upstream/1.5.56
      }
  
  
@@@ -253,8 -261,19 +274,24 @@@
                          return new Locus(null, startEnd[0], startEnd[1]);
                      }
                  } else {
++<<<<<<< HEAD
 +                    // No dash, this is either a chromosome or an unkown search string
 +                    return new Locus(searchString, -1, -1);
++=======
+                     Feature feature = FeatureDB.getFeature(searchString.toUpperCase().trim());
+                     if (feature != null) {
+                         return new Locus(feature.getChr(), feature.getStart(), feature.getEnd());
+                     } else {
+ 
+                         Genome genome = IGVMainFrame.getInstance().getViewContext().getGenome();
+                         if (genome.getChromosome(searchString) != null) {
+                             // No dash, this is either a chromosome or an unkown search string
+                             return new Locus(searchString, -1, -1);
+                         } else {
+                             return null;
+                         }
+                     }
++>>>>>>> upstream/1.5.56
                  }
              }
          }
diff --combined src/org/broad/igv/session/SessionReader.java
index b571457,0e8f713..78bbbe8
--- a/src/org/broad/igv/session/SessionReader.java
+++ b/src/org/broad/igv/session/SessionReader.java
@@@ -33,8 -33,10 +33,13 @@@ import org.broad.igv.ui.TrackFilterElem
  import org.broad.igv.ui.panel.TrackPanel;
  import org.broad.igv.ui.util.MessageUtils;
  import org.broad.igv.util.ColorUtilities;
++<<<<<<< HEAD:src/org/broad/igv/session/SessionReader.java
++=======
+ import org.broad.igv.util.FileUtils;
++>>>>>>> upstream/1.5.56:src/org/broad/igv/session/SessionReader.java
  import org.broad.igv.util.FilterElement.BooleanOperator;
  import org.broad.igv.util.FilterElement.Operator;
+ import org.broad.igv.util.IGVHttpUtils;
  import org.broad.igv.util.ResourceLocator;
  import org.w3c.dom.*;
  import org.xml.sax.SAXException;
@@@ -448,11 -450,12 +453,12 @@@ public class SessionReader 
      }
  
      /**
-      * Process the data file element.  If relativePaths == true treat the
-      * file path as relative to the session file path.  If false
-      *
       * @param session
       * @param element
+      * @Deprecated // TODO -- this method should not be called.  Delete?
+      * @Deprectated -- user processResource
+      * Process the data file element.  If relativePaths == true treat the
+      * file path as relative to the session file path.  If false
       */
      private void processDataFile(Session session, Element element, HashMap additionalInformation) {
  
@@@ -496,10 -499,6 +502,13 @@@
  
      private void processResource(Session session, Element element, HashMap additionalInformation) {
  
++<<<<<<< HEAD:src/org/broad/igv/session/SessionReader.java
 +        String serverURL = getAttribute(element, SessionAttribute.SERVER_URL.getText());
 +        String path = getAttribute(element, SessionAttribute.PATH.getText());
 +        ResourceLocator resourceLocator = new ResourceLocator(serverURL, path);
 +
++=======
++>>>>>>> upstream/1.5.56:src/org/broad/igv/session/SessionReader.java
          String label = getAttribute(element, SessionAttribute.LABEL.getText());
          String name = getAttribute(element, SessionAttribute.NAME.getText());
          String sampleId = getAttribute(element, SessionAttribute.SAMPLE_ID.getText());
@@@ -509,6 -508,26 +518,29 @@@
          String trackLine = getAttribute(element, SessionAttribute.TRACK_LINE.getText());
          String colorString = getAttribute(element, SessionAttribute.COLOR.getText());
  
++<<<<<<< HEAD:src/org/broad/igv/session/SessionReader.java
++=======
+         String relPathValue = getAttribute(element, SessionAttribute.RELATIVE_PATH.getText());
+         boolean relativePaths = ((relPathValue != null) && relPathValue.equalsIgnoreCase("true"));
+         String serverURL = getAttribute(element, SessionAttribute.SERVER_URL.getText());
+         String path = getAttribute(element, SessionAttribute.PATH.getText());
+ 
+         ResourceLocator resourceLocator = new ResourceLocator(serverURL, path);
+         if (relativePaths) {
+             if (FileUtils.isRemote(session.getPath())) {
+                 int idx = session.getPath().lastIndexOf("/");
+                 String basePath = session.getPath().substring(0, idx);
+                 String resPath = basePath + "/" + path;
+                 resourceLocator = new ResourceLocator(serverURL, resPath);
+             } else {
+                 File parent = (relativePaths ? new File(session.getPath()).getParentFile() : null);
+                 File file = new File(parent, path);
+                 resourceLocator = new ResourceLocator(serverURL, file.getAbsolutePath());
+             }
+         }
+ 
+ 
++>>>>>>> upstream/1.5.56:src/org/broad/igv/session/SessionReader.java
          String url = getAttribute(element, SessionAttribute.URL.getText());
          if (url == null) {
              url = getAttribute(element, SessionAttribute.FEATURE_URL.getText());
diff --combined src/org/broad/igv/session/SessionWriter.java
index f8d9e77,7d2e30f..1260cc9
--- a/src/org/broad/igv/session/SessionWriter.java
+++ b/src/org/broad/igv/session/SessionWriter.java
@@@ -217,7 -217,7 +217,7 @@@ public class SessionWriter 
      }
  
      private void writeRegionsOfInterest(Element globalElement, Document document) {
-         Collection<RegionOfInterest> regions = getRegionsOfInterestSet();
+         Collection<RegionOfInterest> regions = session.getAllRegionsOfInterest();
          if ((regions != null) && !regions.isEmpty()) {
  
              Element regionsElement = document.createElement(SessionElement.REGIONS.getText());
@@@ -297,9 -297,9 +297,15 @@@
      }
  
      private void writePanels(Element globalElement, Document document) throws DOMException {
++<<<<<<< HEAD
 +
 +        for (TrackPanelScrollPane tsp : IGVMainFrame.getInstance().getTrackManager().getTrackPanelScrollPanes()) {
 +            TrackPanel trackPanel = tsp.getTrackPanel();
++=======
+ 
+         for (TrackPanel trackPanel : IGVMainFrame.getInstance().getTrackPanels()) {
+ 
++>>>>>>> upstream/1.5.56
              // TODO -- loop through panels groups, rather than skipping groups to tracks
  
              List<Track> tracks = trackPanel.getTracks();
@@@ -364,12 -364,5 +370,15 @@@
          return locators;
      }
  
++<<<<<<< HEAD
 +    public Collection<RegionOfInterest> getRegionsOfInterestSet() {
 +
 +        Collection<RegionOfInterest> regions =
 +                session.getRegionsOfInterest(session.getViewContext().getChrName());
 +
 +        return regions;
 +    }
++=======
++>>>>>>> upstream/1.5.56
  }
  
diff --combined src/org/broad/igv/session/ViewContext.java
index 2810e1a,771ea89..c9bd137
--- a/src/org/broad/igv/session/ViewContext.java
+++ b/src/org/broad/igv/session/ViewContext.java
@@@ -41,6 -41,7 +41,7 @@@ import org.broad.igv.ui.panel.TrackPane
  import org.broad.igv.ui.util.MessageUtils;
  
  import javax.swing.*;
+ import javax.swing.text.NumberFormatter;
  import java.awt.*;
  import java.awt.event.ComponentAdapter;
  import java.awt.event.ComponentEvent;
@@@ -56,9 -57,10 +57,12 @@@ public class ViewContext 
  
      private static Logger log = Logger.getLogger(ViewContext.class);
  
+     private static ViewContext instance = new ViewContext();
+ 
+     private static NumberFormat numberFormat = NumberFormat.getInstance(Locale.US);
  
 +    private static ViewContext instance = new ViewContext();
 +
      private String genomeId;
  
      Genome genome;
@@@ -260,7 -262,7 +264,11 @@@
      }
  
      public void recordHistory() {
++<<<<<<< HEAD:src/org/broad/igv/session/ViewContext.java
 +        history.push(getCurrentLocusString());
++=======
+         history.push(getFormattedLocusString());
++>>>>>>> upstream/1.5.56:src/org/broad/igv/session/ViewContext.java
      }
  
      private void jumpToChromosomeForGenomeLocation(double locationMB) {
@@@ -731,10 -733,10 +739,15 @@@
          genome = GenomeManager.getInstance().getGenome(genomeId);
  
          if (genome == null || loadFailed) {
++<<<<<<< HEAD:src/org/broad/igv/session/ViewContext.java
 +            GenomeDescriptor defaultDesc = GenomeManager.getInstance().getDefaultGenomeDescriptor();
 +            String msg = "Could not locate genome: " + genomeId + ".  Loading " + defaultDesc.getName();
++=======
+             GenomeManager.GenomeListItem defaultDesc = GenomeManager.getInstance().getTopGenomeListItem();
+             String msg = "Could not locate genome: " + genomeId + ".  Loading " + defaultDesc.getDisplayableName();
++>>>>>>> upstream/1.5.56:src/org/broad/igv/session/ViewContext.java
              MessageUtils.showMessage(msg);
-             log.error("Could not locate genome: " + genomeId + ".  Loading " + defaultDesc.getName());
+             log.error("Could not locate genome: " + genomeId + ".  Loading " + defaultDesc.getDisplayableName());
  
              // The previously used genome is unavailable.   Load hg18, we are assuming that
              // this is always available.  // TODO -- permit IGV starting with no selected genome
@@@ -757,17 -759,19 +770,26 @@@
              }
              genome = GenomeManager.getInstance().getGenome(genomeId);
  
++<<<<<<< HEAD:src/org/broad/igv/session/ViewContext.java
++
++            PreferenceManager.getInstance().setDefaultGenome(genomeId);
++            this.setChrName(getHomeChr());
 +
++=======
              PreferenceManager.getInstance().setDefaultGenome(genomeId);
              this.setChrName(getHomeChr());
  
+ 
++>>>>>>> upstream/1.5.56:src/org/broad/igv/session/ViewContext.java
          } else if (!startUp) {
              // We don't know what chromosomes the new genome has, set to "all" (whole genome)
              this.setChrName(getHomeChr());
          }
          computeMaxZoom();
          invalidateLocationScale();
- 
+         if (!Globals.isHeadless()) {
+             IGVMainFrame.getInstance().chromosomeChangeEvent();
+         }
          return genomeId;
      }
  
@@@ -840,17 -844,15 +862,24 @@@
       *
       * @return
       */
-     public String getCurrentLocusString() {
+     public String getFormattedLocusString() {
  
          if (zoom == 0) {
              return getChrName();
          } else {
++<<<<<<< HEAD:src/org/broad/igv/session/ViewContext.java
 +
 +            Range range = getCurrentRange();
 +            String startStr = NumberFormat.getInstance().format(range.getStart());
 +            String endStr = NumberFormat.getInstance().format(range.getEnd());
 +            String position = range.getChr() + ":" + startStr + "-" + endStr;
 +
++=======
+             Range range = getCurrentRange();
+             String startStr = numberFormat.format(range.getStart());
+             String endStr = numberFormat.format(range.getEnd());
+             String position = range.getChr() + ":" + startStr + "-" + endStr;
++>>>>>>> upstream/1.5.56:src/org/broad/igv/session/ViewContext.java
              return position;
          }
  
@@@ -905,8 -907,8 +934,13 @@@
  
  
                      if (track.isVisible()) {
++<<<<<<< HEAD:src/org/broad/igv/session/ViewContext.java
 +                    //    track.preloadData(chrName, start, end, zoom);
 +                    //
++=======
+                         //    track.preloadData(chrName, start, end, zoom);
+                         //
++>>>>>>> upstream/1.5.56:src/org/broad/igv/session/ViewContext.java
                          trackY += track.getHeight();
                      }
                  }
diff --combined src/org/broad/igv/tdf/TDFDataset.java
index 5b38288,cb9cbca..7a26290
--- a/src/org/broad/igv/tdf/TDFDataset.java
+++ b/src/org/broad/igv/tdf/TDFDataset.java
@@@ -49,7 -49,7 +49,11 @@@ public class TDFDataset extends TDFEnti
      long[] tilePositions;
      int[] tileSizes;
      int nTiles;
++<<<<<<< HEAD:src/org/broad/igv/tdf/TDFDataset.java
 +    LRUCache<String, TDFTile> cache = new LRUCache(20);
++=======
+     LRUCache<String, TDFTile> cache = new LRUCache(this, 10);
++>>>>>>> upstream/1.5.56:src/org/broad/igv/tdf/TDFDataset.java
      // TODO -- refactor this dependency out
      TDFReader reader;
  
diff --combined src/org/broad/igv/tdf/TDFReader.java
index 33fcdc5,6f9c31b..41cb538
--- a/src/org/broad/igv/tdf/TDFReader.java
+++ b/src/org/broad/igv/tdf/TDFReader.java
@@@ -57,8 -57,8 +57,13 @@@ public class TDFReader 
      private TrackType trackType;
      private String trackLine;
      private String[] trackNames;
++<<<<<<< HEAD
 +    LRUCache<String, TDFGroup> groupCache = new LRUCache(20);
 +    LRUCache<String, TDFDataset> datasetCache = new LRUCache(20);
++=======
+     LRUCache<String, TDFGroup> groupCache = new LRUCache(this, 10);
+     LRUCache<String, TDFDataset> datasetCache = new LRUCache(this, 10);
++>>>>>>> upstream/1.5.56
  
      Map<WindowFunction, Double> valueCache = new HashMap();
      private List<WindowFunction> windowFunctions;
diff --combined src/org/broad/igv/tools/IgvTools.java
index 708df5e,febc56d..30aa69e
--- a/src/org/broad/igv/tools/IgvTools.java
+++ b/src/org/broad/igv/tools/IgvTools.java
@@@ -30,11 -30,13 +30,19 @@@ import org.broad.igv.feature.Genome
  import org.broad.igv.feature.GenomeManager;
  import org.broad.igv.sam.reader.AlignmentIndexer;
  import org.broad.igv.session.ViewContext;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.tools.parsers.GCTtoIGVConverter;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.tools.sort.Sorter;
  import org.broad.igv.track.WindowFunction;
  import org.broad.igv.track.tribble.CodecFactory;
  import org.broad.igv.util.FileUtils;
  import org.broad.igv.util.ParsingUtils;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.util.ResourceLocator;
++>>>>>>> upstream/1.5.56
  import org.broad.tribble.FeatureCodec;
  import org.broad.tribble.index.IndexCreator;
  import org.broad.tribble.index.interval.IntervalIndexCreator;
@@@ -57,7 -59,7 +65,11 @@@ import java.util.List
   */
  public class IgvTools {
  
++<<<<<<< HEAD
 +    static String version = "1.5.7";
++=======
+     static String version = "1.5.10";
++>>>>>>> upstream/1.5.56
  
      static String[] commandDocs = new String[]{
              "version print the version number",
@@@ -66,15 -68,15 +78,27 @@@
              "tile    convert an input file (cn, gct, wig) to tiled data format (tdf)",
              "count   compute coverage density for an alignment file"
      };
++<<<<<<< HEAD
 +     static final int MAX_RECORDS_IN_RAM = 500000;
 +     static final int MAX_ZOOM = 7;
 +     static final int WINDOW_SIZE = 25;
 +     static final int EXT_FACTOR = 0;
 +     static final Object PROBE_FILE = null;
 +     static final int LINEAR_BIN_SIZE = 16000;
 +     static final int INTERVAL_SIZE = 1000;
 +     static final int LINEAR_INDEX = 1;
 +     static final int INTERVAL_INDEX = 2;
++=======
+     static final int MAX_RECORDS_IN_RAM = 500000;
+     static final int MAX_ZOOM = 7;
+     static final int WINDOW_SIZE = 25;
+     static final int EXT_FACTOR = 0;
+     static final Object PROBE_FILE = null;
+     static final int LINEAR_BIN_SIZE = 16000;
+     static final int INTERVAL_SIZE = 1000;
+     static final int LINEAR_INDEX = 1;
+     static final int INTERVAL_INDEX = 2;
++>>>>>>> upstream/1.5.56
  
      /**
       * The general usage string
@@@ -120,7 -122,7 +144,11 @@@
          CmdLineParser.Option strandOption = parser.addIntegerOption('s', "strand");
          CmdLineParser.Option unOrdered = parser.addBooleanOption('u', "unOrdered");
  
++<<<<<<< HEAD
 +        
++=======
+ 
++>>>>>>> upstream/1.5.56
          // Parse optional arguments (switches, etc)
          try {
              parser.parse(argv);
@@@ -130,18 -132,17 +158,30 @@@
          }
  
          boolean help = ((Boolean) parser.getOptionValue(helpOption, false));
++<<<<<<< HEAD
 +        if(argv.length < 1 || help) {
++=======
+         if (argv.length < 1 || help) {
++>>>>>>> upstream/1.5.56
              System.out.println(usageString());
              return;
          }
  
++<<<<<<< HEAD
 +
 +        boolean gui = ((Boolean) parser.getOptionValue(guiOption, false));
 +        if(gui) {
 +            launchGUI();
 +            Runtime.getRuntime().halt(0);
 +        }
++=======
++>>>>>>> upstream/1.5.56
  
+         boolean gui = ((Boolean) parser.getOptionValue(guiOption, false));
+         if (gui) {
+             launchGUI();
+             Runtime.getRuntime().halt(0);
+         }
  
  
          int maxZoomValue = (Integer) parser.getOptionValue(maxZoomOption, MAX_ZOOM);
@@@ -220,116 -221,133 +260,245 @@@
                  validateArgsLength(nonOptionArgs, 2);
                  String ofile = ifile;
                  TestFileGenerator.generateTestFile(ofile, sorted, nRowsValue, strandOptionValue);
++<<<<<<< HEAD
 +            } else {
 +                throw new PreprocessingException("Unknown command: " + argv[EXT_FACTOR]);
 +            }
 +        } catch (PreprocessingException e) {
 +            System.err.println(e.getMessage());
 +        } catch (IOException e) {
 +            throw new PreprocessingException("Unexpected IO error: ", e);
 +        }
 +    }
 +
 +    public static void doTile(String ifile, String ofile, String probeFile, String genomeId, int maxZoomValue,
 +                              Collection<WindowFunction> windowFunctions) throws IOException, PreprocessingException {
 +        validateIsTilable(ifile);
 +
 +        System.out.println("Tile.  File = " + ifile);
 +        System.out.println("Max zoom = " + maxZoomValue);
 +        if(probeFile != null && probeFile.trim().length() > 0) {
 +            System.out.println("Probe file = " + probeFile);
 +        }
 +        System.out.print("Window functions: ");
 +        for(WindowFunction wf : windowFunctions) {
 +            System.out.print(wf.toString() + " ");
 +        }
 +        System.out.println();
 +
 +        Genome genome = loadGenome(genomeId);
 +        if (genome == null) {
 +            throw new PreprocessingException("Genome could not be loaded: " + genomeId);
 +        }
 +        File tmp = new File(ifile);
 +
 +        // TODO -- do a better size estimate for directories
 +        int nLines = tmp.isDirectory() ? 310000000 : ParsingUtils.estimateLineCount(ifile);
 +
 +        Preprocessor p = new Preprocessor(new File(ofile), genome, windowFunctions, nLines, null);
 +        if (tmp.isDirectory()) {
 +            for (File f : tmp.listFiles()) {
 +                p.preprocess(f, probeFile, maxZoomValue);
 +            }
 +        } else {
 +            p.preprocess(tmp, probeFile, maxZoomValue);
 +        }
 +        p.finish();
 +
 +        System.out.flush();
++=======
+             }  else if (command.toLowerCase().equals("gcttoigv")) {
+                 validateArgsLength(nonOptionArgs, 4);
+                 String ofile = nonOptionArgs[2];
+                 // Output files must have .igv extension
+                 if (!ofile.endsWith(".igv")) {
+                     ofile = ofile + ".igv";
+                 }
+                 String genomeId = nonOptionArgs[3];
+                 doGCTtoIGV(ifile, ofile, probeFile, genomeId);
+             } else {
+                 throw new PreprocessingException("Unknown command: " + argv[EXT_FACTOR]);
+             }
+         } catch (PreprocessingException e) {
+             System.err.println(e.getMessage());
+         } catch (IOException e) {
+             throw new PreprocessingException("Unexpected IO error: ", e);
+         }
+     }
++>>>>>>> upstream/1.5.56
  
+     private static void doGCTtoIGV(String ifile, String ofile, String probefile, String genomeId) throws IOException {
+         Genome genome = loadGenome(genomeId);
+         if (genome == null) {
+             throw new PreprocessingException("Genome could not be loaded: " + genomeId);
+         }
+         GCTtoIGVConverter.convert(new File(ifile), new File(ofile), probefile, genomeId);
+         
      }
  
++<<<<<<< HEAD
 +    public static void doCount(String ifile, String ofile, String genomeId, int maxZoomValue,
 +                               Collection<WindowFunction> windowFunctions,
 +                               int windowSizeValue, int extFactorValue, int strandOption) throws IOException {
 +        System.out.println("Computing coverage.  File = " + ifile);
 +        System.out.println("Max zoom = " + maxZoomValue);
 +        System.out.println("Window size = " + windowSizeValue);
 +        System.out.print("Window functions: ");
 +        for(WindowFunction wf : windowFunctions) {
 +            System.out.print(wf.toString() + " ");
 +        }
 +        System.out.println();
 +        System.out.println("Ext factor = " + extFactorValue);
 +
 +
 +
++=======
+     public static void doTile(String ifile, String ofile, String probeFile, String genomeId, int maxZoomValue,
+                               Collection<WindowFunction> windowFunctions) throws IOException, PreprocessingException {
+         validateIsTilable(ifile);
+ 
+         System.out.println("Tile.  File = " + ifile);
+         System.out.println("Max zoom = " + maxZoomValue);
+         if (probeFile != null && probeFile.trim().length() > 0) {
+             System.out.println("Probe file = " + probeFile);
+         }
+         System.out.print("Window functions: ");
+         for (WindowFunction wf : windowFunctions) {
+             System.out.print(wf.toString() + " ");
+         }
+         System.out.println();
+ 
++>>>>>>> upstream/1.5.56
          Genome genome = loadGenome(genomeId);
          if (genome == null) {
              throw new PreprocessingException("Genome could not be loaded: " + genomeId);
          }
++<<<<<<< HEAD
 +        int nLines = ParsingUtils.estimateLineCount(ifile);
 +
 +        // Multiple files allowed for count command (a tdf and a wig)
 +        File tdfFile = null;
 +        File wigFile = null;
 +        String[] files = ofile.split(",");
 +        if (files[0].endsWith("wig")) {
 +            wigFile = new File(files[0]);
 +        } else {
 +            tdfFile = new File(files[0]);
 +        }
 +        if (files.length > 1) {
 +            if (files[1].endsWith("wig")) {
 +                wigFile = new File(files[1]);
 +            } else if (files[1].endsWith("tdf")) {
 +                tdfFile = new File(files[1]);
 +            }
 +        }
 +
 +        if(!tdfFile.getName().endsWith(".tdf")) {
 +            tdfFile = new File(tdfFile.getAbsolutePath() + ".tdf");
 +        }
 +
 +        Preprocessor p = new Preprocessor(tdfFile, genome, windowFunctions, nLines, null);
 +        p.count(ifile, windowSizeValue, extFactorValue, maxZoomValue, wigFile, strandOption);
 +        p.finish();
 +
 +        System.out.flush();
 +    }
 +
 +
 +    public static void doWIBtoWIG(File txtFile, File wibFile, File wigFile, String trackLine) {
 +        UCSCUtils.convertWIBFile(txtFile, wibFile, wigFile, trackLine);
 +    }
 +
 +
 +    public static void doPreprocessSeg(String[] argv) {
 +        int nArgs = argv.length - 1;
 +        String[] args = new String[nArgs];
 +        System.arraycopy(argv, 1, args, EXT_FACTOR, nArgs);
 +        SegmentedDataWriter.main(args);
 +    }
 +
++=======
+         File tmp = new File(ifile);
+ 
+         // TODO -- do a better size estimate for directories
+         int nLines = tmp.isDirectory() ? 310000000 : ParsingUtils.estimateLineCount(ifile);
+ 
+         Preprocessor p = new Preprocessor(new File(ofile), genome, windowFunctions, nLines, null);
+         if (tmp.isDirectory()) {
+             for (File f : tmp.listFiles()) {
+                 p.preprocess(f, probeFile, maxZoomValue);
+             }
+         } else {
+             p.preprocess(tmp, probeFile, maxZoomValue);
+         }
+         p.finish();
+ 
+         System.out.flush();
+ 
+     }
+ 
+     public static void doCount(String ifile, String ofile, String genomeId, int maxZoomValue,
+                                Collection<WindowFunction> windowFunctions,
+                                int windowSizeValue, int extFactorValue, int strandOption) throws IOException {
+         System.out.println("Computing coverage.  File = " + ifile);
+         System.out.println("Max zoom = " + maxZoomValue);
+         System.out.println("Window size = " + windowSizeValue);
+         System.out.print("Window functions: ");
+         for (WindowFunction wf : windowFunctions) {
+             System.out.print(wf.toString() + " ");
+         }
+         System.out.println();
+         System.out.println("Ext factor = " + extFactorValue);
+ 
+ 
+         Genome genome = loadGenome(genomeId);
+         if (genome == null) {
+             throw new PreprocessingException("Genome could not be loaded: " + genomeId);
+         }
+         int nLines = ParsingUtils.estimateLineCount(ifile);
+ 
+         // Multiple files allowed for count command (a tdf and a wig)
+         File tdfFile = null;
+         File wigFile = null;
+         String[] files = ofile.split(",");
+         if (files[0].endsWith("wig")) {
+             wigFile = new File(files[0]);
+         } else {
+             tdfFile = new File(files[0]);
+         }
+         if (files.length > 1) {
+             if (files[1].endsWith("wig")) {
+                 wigFile = new File(files[1]);
+             } else if (files[1].endsWith("tdf")) {
+                 tdfFile = new File(files[1]);
+             }
+         }
+ 
+         if (tdfFile != null && !tdfFile.getName().endsWith(".tdf")) {
+             tdfFile = new File(tdfFile.getAbsolutePath() + ".tdf");
+         }
+ 
+         Preprocessor p = new Preprocessor(tdfFile, genome, windowFunctions, nLines, null);
+         p.count(ifile, windowSizeValue, extFactorValue, maxZoomValue, wigFile, strandOption);
+         p.finish();
+ 
+         System.out.flush();
+     }
+ 
+ 
+     public static void doWIBtoWIG(File txtFile, File wibFile, File wigFile, String trackLine) {
+         UCSCUtils.convertWIBFile(txtFile, wibFile, wigFile, trackLine);
+     }
+ 
+ 
+     public static void doPreprocessSeg(String[] argv) {
+         int nArgs = argv.length - 1;
+         String[] args = new String[nArgs];
+         System.arraycopy(argv, 1, args, EXT_FACTOR, nArgs);
+         SegmentedDataWriter.main(args);
+     }
+ 
++>>>>>>> upstream/1.5.56
  
      /**
       * Create an index for an alignment or feature file
@@@ -345,7 -363,7 +514,11 @@@
  
          File inputFile = new File(ifile);
          if (ifile.endsWith(".bed") || ifile.endsWith(".vcf") || ifile.endsWith(".gff") ||
++<<<<<<< HEAD
 +                ifile.endsWith(".gff3")|| ifile.endsWith(".psl") || ifile.endsWith(".pslx")) {
++=======
+                 ifile.endsWith(".gff3") || ifile.endsWith(".psl") || ifile.endsWith(".pslx")) {
++>>>>>>> upstream/1.5.56
              FeatureCodec codec = CodecFactory.getCodec(ifile);
  
              IndexCreator indexer = null;
@@@ -399,13 -417,13 +572,23 @@@
      }
  
  
++<<<<<<< HEAD
 +    private static Genome loadGenome(String genomeFileOrID) {
 +        
 +
 +        String rootDir = FileUtils.getInstallDirectory();
 +
 +        Genome genome = GenomeManager.getInstance().getGenome(genomeFileOrID);
 +        if(genome != null) {
++=======
+     public static Genome loadGenome(String genomeFileOrID) {
+ 
+ 
+         String rootDir = FileUtils.getInstallDirectory();
+ 
+         Genome genome = GenomeManager.getInstance().getGenome(genomeFileOrID);
+         if (genome != null) {
++>>>>>>> upstream/1.5.56
              return genome;
          }
  
diff --combined src/org/broad/igv/tools/IgvToolsGui.java
index b409783,9ef61d5..eb416f8
--- a/src/org/broad/igv/tools/IgvToolsGui.java
+++ b/src/org/broad/igv/tools/IgvToolsGui.java
@@@ -610,7 -610,7 +610,11 @@@ public class IgvToolsGui extends JDialo
                  String input = inputField.getText();
                  int ext = input.lastIndexOf(".");
                  if (ext > 0) {
++<<<<<<< HEAD
 +                    String output = input.substring(0, ext) + ".sorted." + input.substring(ext);
++=======
+                     String output = input.substring(0, ext) + ".sorted" + input.substring(ext);
++>>>>>>> upstream/1.5.56
                      outputField.setText(output);
                  }
              }
diff --combined src/org/broad/igv/track/AttributeManager.java
index 5d29525,d3bbe08..4bd3466
--- a/src/org/broad/igv/track/AttributeManager.java
+++ b/src/org/broad/igv/track/AttributeManager.java
@@@ -131,7 -131,12 +131,16 @@@ public class AttributeManager 
      }
  
      public void setHiddenAttributes(Set<String> attributes) {
++<<<<<<< HEAD
 +        this.hiddenAttributes = attributes;
++=======
+         // Interpret null as the empty set
+         if (attributes == null) {
+             hiddenAttributes.clear();
+         } else {
+             hiddenAttributes = attributes;
+         }
++>>>>>>> upstream/1.5.56
      }
  
      public void clearAllAttributes() {
@@@ -174,7 -179,7 +183,11 @@@
      public void addAttributeKey(String key) {
          if (!attributeKeys.contains(key) && !key.startsWith("#")) {
              attributeKeys.add(key);
++<<<<<<< HEAD
 +        }        
++=======
+         }
++>>>>>>> upstream/1.5.56
      }
  
  
@@@ -188,102 -193,102 +201,224 @@@
              reader = ParsingUtils.openAsciiReader(locator);
              nextLine = reader.readLine();
              if (nextLine.toLowerCase().startsWith("#sampletable")) {
++<<<<<<< HEAD
 +                loadSampleTable (reader, nextLine, locator.getPath());
 +            } else {
 +                loadOldSamapleInfo(reader, nextLine, locator.getPath());
 +            }
 +            loadedResources.add(locator);
 +
 +            //createCurrentAttributeFileString(files);
 +            IGVMainFrame.getInstance().getTrackManager().resetOverlayTracks();
 +
 +            IGVMainFrame.getInstance().doRefresh();
 +            
 +        } catch (IOException ex) {
 +            log.error("Error loading attribute file", ex);
 +            throw new DataLoadException("Error reading attribute file", locator.getPath());
 +        }  finally {
 +            if (reader != null) {
 +                reader.close();
 +
 +            }
 +            firePropertyChange(this, ATTRIBUTES_LOADED_PROPERTY, null, null);
 +        }
 +    }
 +
 +    private String loadOldSamapleInfo(AsciiLineReader reader, String nextLine, String path) throws IOException {
 +        // Parse column neadings for attribute names.
 +        // Columns 1 and 2 are array and sample name (not attributes)
 +        boolean foundAttributes = false;
 +        String[] colHeadings = nextLine.split("\t");
 +        int nLines = 0;
 +        int lineLimit = 100000;
 +        while ((nextLine = reader.readLine()) != null) {
 +            if (nLines++ > lineLimit) {
 +                break;
 +            }
 +            String[] values = nextLine.split("\t");
 +
 +            if (values.length >= 2) {
 +                String arrayName = values[0].trim();
 +                // Loop through attribute columns
 +                for (int i = 0; i < colHeadings.length; i++) {
 +                    String attributeName = colHeadings[i].trim();
 +                    String attributeValue = (i < values.length ? values[i].trim() : "");
 +                    addAttribute(arrayName, attributeName, attributeValue);
 +                    foundAttributes = true;
 +                }
 +            }
 +        }
 +
 +
 +        if (!foundAttributes) {
 +            throw new DataLoadException("Could not determine file type.  Does file have proper extension? ", path);
 +        }
 +        return nextLine;
 +    }
 +
 +    /**
 +     * Load attributes from an ascii file in "Sample Table" format.  This format expects
 +     * a sample table section, prefaced by #sampleTable,  followed by a sample mapping
 +     * section  (track -> sample) prefaced by #sampleMappings
 +     */
 +    private void loadSampleTable(AsciiLineReader reader, String nextLine, String path) throws IOException {
 +
 +        // Parse column neadings for attribute names.
 +        // Columns 1 and 2 are array and sample name (not attributes)
 +        nextLine = reader.readLine();
 +        String[] colHeadings = nextLine.split("\t");
 +
 +        // Map of sample -> attribute list
 +        Map<String, List<Attribute>> sampleTable = new HashMap();
 +
 +        boolean foundAttributes = false;
 +        int nLines = 0;
 +        int lineLimit = 100000;
 +        while ((nextLine = reader.readLine()) != null) {
 +            if (nLines++ > lineLimit || nextLine.toLowerCase().startsWith("#samplemapping")) {
 +                break;
 +            }
 +            String[] values = nextLine.split("\t");
 +
 +            if (values.length >= 2) {
 +                String sampleName = values[0].trim();
 +                // Loop through attribute columns
 +                List<Attribute> attributes = new ArrayList(colHeadings.length);
 +                for (int i = 0; i < colHeadings.length; i++) {
 +                    String attributeName = colHeadings[i].trim();
 +                    String attributeValue = (i < values.length ? values[i].trim() : "");
 +                    attributes.add(new Attribute(attributeName, attributeValue));
 +                    foundAttributes = true;
 +                }
 +                sampleTable.put(sampleName, attributes);
 +            }
 +        }
 +        if (!foundAttributes) {
 +            throw new DataLoadException("Could not determine file type.  Does file have proper extension? ", path);
 +        }
 +
++=======
+                 loadSampleTable(reader, nextLine, locator.getPath());
+             } else {
+                 loadOldSamapleInfo(reader, nextLine, locator.getPath());
+             }
+             loadedResources.add(locator);
+ 
+             //createCurrentAttributeFileString(files);
+             IGVMainFrame.getInstance().getTrackManager().resetOverlayTracks();
+ 
+             IGVMainFrame.getInstance().doRefresh();
+ 
+         } catch (IOException ex) {
+             log.error("Error loading attribute file", ex);
+             throw new DataLoadException("Error reading attribute file", locator.getPath());
+         } finally {
+             if (reader != null) {
+                 reader.close();
++>>>>>>> upstream/1.5.56
+ 
++        if (nextLine.toLowerCase().startsWith("#samplemapping")) {
++            while ((nextLine = reader.readLine()) != null) {
++                String[] tokens = nextLine.split("\t");
++                if (tokens.length < 2) {
++                    continue;
++                }
++                String array = tokens[0];
++                String sample = tokens[1];
++                List<Attribute> attributes = sampleTable.get(sample);
++                if (attributes == null) {
++                    log.info("Warning: sample in mapping section:  " + sample + " in sample table file " + path);
++                } else {
++                    for (Attribute att : attributes) {
++                        addAttribute(array, att.getKey(), att.getValue());
++                    }
++                }
++            }
++        } else {
++            // No mapping section.
++            for (Map.Entry<String, List<Attribute>> entry : sampleTable.entrySet()) {
++                String sample = entry.getKey();
++                for (Attribute att : entry.getValue()) {
++                    addAttribute(sample, att.getKey(), att.getValue());
++                }
+             }
 -            firePropertyChange(this, ATTRIBUTES_LOADED_PROPERTY, null, null);
+         }
+     }
+ 
+     private String loadOldSamapleInfo(AsciiLineReader reader, String nextLine, String path) throws IOException {
+         // Parse column neadings for attribute names.
+         // Columns 1 and 2 are array and sample name (not attributes)
+         boolean foundAttributes = false;
+         String[] colHeadings = nextLine.split("\t");
+         int nLines = 0;
+         int lineLimit = 100000;
+         while ((nextLine = reader.readLine()) != null) {
+             if (nLines++ > lineLimit) {
+                 break;
+             }
+             String[] values = nextLine.split("\t");
+ 
+             if (values.length >= 2) {
+                 String arrayName = values[0].trim();
+                 // Loop through attribute columns
+                 for (int i = 0; i < colHeadings.length; i++) {
+                     String attributeName = colHeadings[i].trim();
+                     String attributeValue = (i < values.length ? values[i].trim() : "");
+                     addAttribute(arrayName, attributeName, attributeValue);
+                     foundAttributes = true;
+                 }
+             }
+         }
+ 
+ 
+         if (!foundAttributes) {
+             throw new DataLoadException("Could not determine file type.  Does file have proper extension? ", path);
+         }
+         return nextLine;
+     }
+ 
+     /**
+      * Load attributes from an ascii file in "Sample Table" format.  This format expects
+      * a sample table section, prefaced by #sampleTable,  followed by a sample mapping
+      * section  (track -> sample) prefaced by #sampleMappings
+      */
+     private void loadSampleTable(AsciiLineReader reader, String nextLine, String path) throws IOException {
+ 
+         // Parse column neadings for attribute names.
+         // Columns 1 and 2 are array and sample name (not attributes)
+         nextLine = reader.readLine();
+         String[] colHeadings = nextLine.split("\t");
+ 
+         // Map of sample -> attribute list
+         Map<String, List<Attribute>> sampleTable = new HashMap();
+ 
+         boolean foundAttributes = false;
+         int nLines = 0;
+         int lineLimit = 100000;
+         while ((nextLine = reader.readLine()) != null) {
+             if (nLines++ > lineLimit || nextLine.toLowerCase().startsWith("#samplemapping")) {
+                 break;
+             }
+             String[] values = nextLine.split("\t");
+ 
+             if (values.length >= 2) {
+                 String sampleName = values[0].trim();
+                 // Loop through attribute columns
+                 List<Attribute> attributes = new ArrayList(colHeadings.length);
+                 for (int i = 0; i < colHeadings.length; i++) {
+                     String attributeName = colHeadings[i].trim();
+                     String attributeValue = (i < values.length ? values[i].trim() : "");
+                     attributes.add(new Attribute(attributeName, attributeValue));
+                     foundAttributes = true;
+                 }
+                 sampleTable.put(sampleName, attributes);
+             }
+         }
+         if (!foundAttributes) {
+             throw new DataLoadException("Could not determine file type.  Does file have proper extension? ", path);
+         }
+ 
  
          if (nextLine.toLowerCase().startsWith("#samplemapping")) {
              while ((nextLine = reader.readLine()) != null) {
@@@ -313,6 -318,6 +448,10 @@@
          }
  
  
++<<<<<<< HEAD
++
++=======
++>>>>>>> upstream/1.5.56
      }
  
  
diff --combined src/org/broad/igv/track/FeatureDirSource.java
index 1669645,8c491dd..04a87eb
--- a/src/org/broad/igv/track/FeatureDirSource.java
+++ b/src/org/broad/igv/track/FeatureDirSource.java
@@@ -47,7 -47,7 +47,11 @@@ public class FeatureDirSource implement
      ResourceLocator rootLocator;
  
      public FeatureDirSource(ResourceLocator locator) throws IOException {
++<<<<<<< HEAD
 +        featureCache = new LRUCache(3);
++=======
+         featureCache = new LRUCache(this, 3);
++>>>>>>> upstream/1.5.56
          rootLocator = locator;
          setRootDir(locator.getPath());
  
diff --combined src/org/broad/igv/track/FeatureTrack.java
index 5c607d5,e1266d8..7e79493
--- a/src/org/broad/igv/track/FeatureTrack.java
+++ b/src/org/broad/igv/track/FeatureTrack.java
@@@ -28,6 -28,8 +28,11 @@@ import org.broad.igv.ui.UIConstants
  import org.broad.igv.ui.WaitCursorManager;
  import org.broad.igv.ui.util.MessageUtils;
  import org.broad.igv.util.BrowserLauncher;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.util.LongRunningTask;
+ import org.broad.igv.util.NamedRunnable;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.util.ResourceLocator;
  
  import java.awt.*;
@@@ -85,19 -87,16 +90,29 @@@ public class FeatureTrack extends Abstr
          setColor(Color.blue.darker());
          coverageRenderer = new HeatmapRenderer();
  
++<<<<<<< HEAD
 +        if(source.getBinSize() > 0) {
 +            visibilityWindow = source.getBinSize();
 +        }
 +        else {
 +
 +        }
++=======
+         if (source.getBinSize() > 0) {
+             visibilityWindow = source.getBinSize();
+         }
++>>>>>>> upstream/1.5.56
      }
  
      @Override
      public void setTrackProperties(TrackProperties trackProperties) {
          super.setTrackProperties(trackProperties);
  
++<<<<<<< HEAD
 +        if (trackProperties.getFeatureVisibilityWindow() > 0) {
++=======
+         if (trackProperties.getFeatureVisibilityWindow() >= 0) {
++>>>>>>> upstream/1.5.56
              setVisibilityWindow(trackProperties.getFeatureVisibilityWindow());
          }
  
@@@ -182,345 -181,361 +197,702 @@@
                  LocusScore score = (LocusScore) FeatureUtils.getFeatureAt(position, minWidth, scores);
                  return score == null ? "" : "Mean count: " + score.getScore();
              }
++<<<<<<< HEAD
 +
 +        }
 +    }
 +
 +    private Feature getFeatureAt(String chr, double position, int y) {
 +
 +        if (packedFeatures == null) {
 +            return null;
 +        }
 +
 +        Feature feature = null;
 +        // Determine the level number (for expanded tracks.
 +        int levelNumber = 0;
 +        if (featureRects != null) {
 +            for (int i = 0; i < featureRects.size(); i++) {
 +                Rectangle r = featureRects.get(i);
 +                if ((y >= r.y) && (y <= r.getMaxY())) {
 +                    levelNumber = i;
 +                    break;
 +                }
 +            }
 +        }
 +
 +        int nLevels = this.getNumberOfFeatureLevels();
 +        List<Feature> features = null;
 +        if ((nLevels > 1) && (levelNumber < nLevels)) {
 +            features = packedFeatures.rows.get(levelNumber).features;
 +        } else {
 +            features = packedFeatures.features;
 +        }
 +        if (features != null) {
 +
 +            // give a 2 pixel window, otherwise very narrow features will be missed.
 +            double bpPerPixel = ViewContext.getInstance().getScale();
 +            double minWidth = MINIMUM_FEATURE_SPACING * bpPerPixel;
 +            feature = (Feature) FeatureUtils.getFeatureAt(position, minWidth, features);
 +        }
 +        return feature;
 +    }
 +
 +    public WindowFunction getWindowFunction() {
 +        return WindowFunction.count;
 +    }
 +
 +    @Override
 +    public boolean handleClick(MouseEvent e) {
 +
 +        if (e.getClickCount() == 1 && !e.isShiftDown() && !e.isPopupTrigger() && e.getButton() == MouseEvent.BUTTON1) {
 +            if (e.getX() < EXPAND_ICON_BUFFER_WIDTH) {
 +                if (expandButtonRect.contains(e.getPoint())) {
 +                    setExpanded(!expanded);
 +                    IGVMainFrame.getInstance().doResizeTrackPanels();
 +                    IGVMainFrame.getInstance().doRefresh();
 +                }
 +                return true;
 +            }
 +
 +
 +            Feature f = getFeatureAtMousePosition(e);
 +
 +            if (f != null) {
 +                String url = f.getURL();
 +                if (url == null) {
 +                    String trackURL = getUrl();
 +                    if (trackURL != null && f.getIdentifier() != null) {
 +                        String encodedID = URLEncoder.encode(f.getIdentifier());
 +                        url = trackURL.replaceAll("\\$\\$", encodedID);
 +                    }
 +                }
 +                // A scheduler is used so that the browser opening can be canceled in the event of a double
 +                // click.  In that case the first click will schedule the browser opening, but it is delayed
 +                // long enough to enable the second click to cancel it.
 +                if (url != null) {
 +                    scheduleBrowserTask(url, UIConstants.getDoubleClickInterval());
 +                    e.consume();
 +                    return true;
 +                }
 +            }
 +
 +        } else
 +
 +        {
 +            // This call will cancel opening a browser in the event of a double click
 +            cancelBrowserTask();
 +        }
 +
 +        return false;
 +    }
 +
 +    public Feature getFeatureAtMousePosition(MouseEvent e) {
 +        double location = getViewContext().getChromosomePosition(e.getX());
 +        double displayLocation = location + 1;
 +        Feature f = getFeatureAt(getViewContext().getChrName(), displayLocation, e.getY());
 +        return f;
 +    }
 +
 +
 +    @Override
 +    public boolean isExpanded() {
 +        return expanded;
 +    }
 +
 +    /**
 +     * Required by the interface, really not applicable to feature tracks
 +     */
 +    public boolean isLogNormalized() {
 +        return true;
 +    }
 +
 +
 +    public void overlay(RenderContext context, Rectangle rect) {
 +        getRenderer().setOverlayMode(true);
 +        renderFeatures(context, rect);
 +    }
 +
 +    public void render(RenderContext context, Rectangle rect) {
 +        getRenderer().setOverlayMode(false);
 +        Rectangle renderRect = new Rectangle(rect);
 +        renderRect.y = renderRect.y + MARGIN;
 +        renderRect.height -= MARGIN;
 +
 + 
 +        double windowSize = rect.width * context.getScale();
 +
 +        int vw = getVisibilityWindow();
 +        showFeatures = true;
 +        if(vw == 0) {
 +            showFeatures = !context.getChr().equals(Globals.CHR_ALL);
 +        }
 +        else if(vw > 0) {
 +            showFeatures = !context.getChr().equals(Globals.CHR_ALL) && windowSize <= vw;
 +        }
 +
 +        if (showFeatures) {
 +            renderFeatures(context, renderRect);
 +        } else {
 +            renderCoverage(context, renderRect);
 +        }
 +        boolean showIcon = PreferenceManager.getInstance().getBooleanPreference(PreferenceManager.SHOW_EXPAND_ICON, true);
 +        if (showIcon && !IGVMainFrame.getInstance().isExportingSnapshot()) {
 +            renderExpandTool(context, rect);
 +        }
 +    }
 +
 +    private void renderCoverage(RenderContext context, Rectangle inputRect) {
 +        List<LocusScore> scores = source.getCoverageScores(context.getChr(), (int) context.getOrigin(),
 +                (int) context.getEndLocation(), context.getZoom());
 +        if (scores == null) {
 +            Graphics2D g = context.getGraphic2DForColor(Color.gray);
 +            GraphicUtils.drawCenteredText("Zoom in to see features.", inputRect, g);
 +        } else {
 +            float max = getMaxEstimate(scores);
 +            ContinuousColorScale cs = getColorScale();
 +            if (cs != null) {
 +                cs.setPosEnd(max);
 +            }
 +            setDataRange(new DataRange(0, 0, max));
 +            coverageRenderer.render(this, scores, context, inputRect);
 +        }
 +    }
 +
 +
 +    private float getMaxEstimate(List<LocusScore> scores) {
 +        float max = 0;
 +        int n = Math.min(200, scores.size());
 +        for (int i = 0; i < n; i++) {
 +            max = Math.max(max, scores.get(i).getScore());
 +        }
 +        return max;
 +    }
 +
 +
 +    private boolean featuresLoading = false;
 +
 +
 +    private int[] p1 = new int[3];
 +    private int[] p2 = new int[3];
 +
 +    private void renderExpandTool(RenderContext contect, Rectangle rect) {
 +
 +        if (packedFeatures == null || packedFeatures.getRowCount() <= 1) {
 +            return;
 +        }
 +
 +        Graphics2D g2d = contect.getGraphic2DForColor(Color.DARK_GRAY);
 +        int levelHeight = getHeight() / this.getNumberOfFeatureLevels() + 1;
 +
 +        g2d.clearRect(rect.x, rect.y, EXPAND_ICON_BUFFER_WIDTH, levelHeight);
 +
 +        expandButtonRect.x = rect.x + 3;
 +        expandButtonRect.y = rect.y + MARGIN + 4;
 +        expandButtonRect.width = 10;
 +        expandButtonRect.height = 10;
 +
 +        if (expanded) {
 +            p1[0] = expandButtonRect.x;
 +            p1[1] = expandButtonRect.x + 8;
 +            p1[2] = expandButtonRect.x + 4;
 +            p2[0] = expandButtonRect.y;
 +            p2[1] = expandButtonRect.y;
 +            p2[2] = expandButtonRect.y + 8;
 +            g2d.fillPolygon(p1, p2, 3);
  
 +        } else {
 +            p1[0] = expandButtonRect.x;
 +            p1[1] = expandButtonRect.x + 8;
 +            p1[2] = expandButtonRect.x;
 +            p2[0] = expandButtonRect.y;
 +            p2[1] = expandButtonRect.y + 4;
 +            p2[2] = expandButtonRect.y + 8;
 +            g2d.fillPolygon(p1, p2, 3);
++=======
++
++>>>>>>> upstream/1.5.56
          }
 +
      }
  
+     private Feature getFeatureAt(String chr, double position, int y) {
  
++<<<<<<< HEAD
 +    // Render features in the given input rectangle.
 +
 +    private void renderFeatures(RenderContext context, Rectangle inputRect) {
 +
 +        if (featuresLoading) {
 +            return;
 +        }
 +
 +        //if (log.isDebugEnabled()) {
 +        //    log.debug("renderFeatures: " + getName());
 +        //}
 +
 +        String chr = context.getChr();
 +        int start = (int) context.getOrigin();
 +        int end = (int) context.getEndLocation() + 1;
 +        if (packedFeatures == null || !packedFeatures.containsInterval(chr, start, end)) {
 +            featuresLoading = true;
 +            int expandedStart = 0;
 +            int expandedEnd = Integer.MAX_VALUE;
 +            int binSize = source.getBinSize();
 +            if (binSize > 0) {
 +                int t1 = start / binSize;
 +                int t2 = end / binSize;
 +                expandedStart = t1 * binSize;
 +                expandedEnd = (t2 + 1) * binSize;
 +            }
 +            loadFeatures(chr, expandedStart, expandedEnd);
 +            return;
 +        }
 +
 +
 +        if (expanded) {
 +            List<FeatureRow> rows = packedFeatures.rows;
 +            if (rows != null && rows.size() > 0) {
 +
 +                int nLevels = rows.size();
 +                synchronized (featureRects) {
 +
 +                    featureRects.clear();
 +
 +                    // Divide rectangle into equal height levels
 +                    double h = inputRect.getHeight() / nLevels;
 +                    Rectangle rect = new Rectangle(inputRect.x, inputRect.y, inputRect.width, (int) h);
 +                    for (FeatureRow row : rows) {
 +                        featureRects.add(new Rectangle(rect));
 +                        getRenderer().renderFeatures(row.features, context, rect, this);
 +                        rect.y += h;
 +                    }
 +                }
 +            }
 +        } else {
 +            List<Feature> features = packedFeatures.features;
 +            if (features != null) {
 +                getRenderer().renderFeatures(features, context, inputRect, this);
 +            }
 +        }
 +
 +
 +    }
 +
 +    /**
 +     * Loads and segregates features into rows such that they do not overlap.  Loading is done in a background
 +     * thread.
 +     *
 +     * @param chr
 +     * @param start
 +     * @param end
 +     */
 +    private void loadFeatures(final String chr, final int start, final int end) {
 +
 +        WaitCursorManager.CursorToken token = WaitCursorManager.showWaitCursor();
 +        try {
 +
 +            // TODO -- implement source to return iterators
 +            Iterator<Feature> iter = source.getFeatures(chr, start, end);
 +            if (iter == null) {
 +                packedFeatures = new PackedFeatures(chr, start, end);
 +            } else {
 +                packedFeatures = new PackedFeatures(chr, start, end, iter, getName());
 +            }
 +
 +            // TODO -- replace with more limited paint
 +            IGVMainFrame.getInstance().repaint();
 +        } catch (Throwable e) {
 +            // Mark the interval with an empty feature list to prevent an endless loop of load
 +            // attempts.
 +            packedFeatures = new PackedFeatures(chr, start, end);
 +            String msg = "Error loading features for interval: " +
 +                    chr + ":" + start + "-" + end + " <br>" + e.toString();
 +            MessageUtils.showMessage(msg);
 +            log.error(msg, e);
 +        }
 +
 +        finally {
 +            WaitCursorManager.removeWaitCursor(token);
 +            featuresLoading = false;
 +            if (log.isDebugEnabled()) {
 +                log.debug("features loaded");
 +            }
 +        }
 +    }
 +
 +
 +    @Override
 +    public void setExpanded(boolean value) {
 +        expanded = value;
 +    }
 +
 +    @Override
 +    public void setHeight(int newHeight) {
 +
 +        int levelCount = this.getNumberOfFeatureLevels();
 +        super.setHeight(Math.max(getMinimumHeight(), newHeight / levelCount));
 +    }
 +
 +    public void setRendererClass(Class rc) {
 +        try {
 +            renderer = (FeatureRenderer) rc.newInstance();
 +        } catch (Exception ex) {
 +            log.error("Error instatiating renderer ", ex);
 +        }
 +    }
 +
++=======
+         if (packedFeatures == null) {
+             return null;
+         }
+ 
+         Feature feature = null;
+         // Determine the level number (for expanded tracks.
+         int levelNumber = 0;
+         if (featureRects != null) {
+             for (int i = 0; i < featureRects.size(); i++) {
+                 Rectangle r = featureRects.get(i);
+                 if ((y >= r.y) && (y <= r.getMaxY())) {
+                     levelNumber = i;
+                     break;
+                 }
+             }
+         }
+ 
+         int nLevels = this.getNumberOfFeatureLevels();
+         List<Feature> features = null;
+         if ((nLevels > 1) && (levelNumber < nLevels)) {
+             features = packedFeatures.rows.get(levelNumber).features;
+         } else {
+             features = packedFeatures.features;
+         }
+         if (features != null) {
+ 
+             // give a 2 pixel window, otherwise very narrow features will be missed.
+             double bpPerPixel = ViewContext.getInstance().getScale();
+             double minWidth = MINIMUM_FEATURE_SPACING * bpPerPixel;
+             feature = (Feature) FeatureUtils.getFeatureAt(position, minWidth, features);
+         }
+         return feature;
+     }
+ 
+     public WindowFunction getWindowFunction() {
+         return WindowFunction.count;
+     }
+ 
+     @Override
+     public boolean handleClick(MouseEvent e) {
+ 
+         if (e.getClickCount() == 1 && !e.isShiftDown() && !e.isPopupTrigger() && e.getButton() == MouseEvent.BUTTON1) {
+             if (e.getX() < EXPAND_ICON_BUFFER_WIDTH) {
+                 if (expandButtonRect.contains(e.getPoint())) {
+                     setExpanded(!expanded);
+                     IGVMainFrame.getInstance().doResizeTrackPanels();
+                     IGVMainFrame.getInstance().doRefresh();
+                 }
+                 return true;
+             }
+ 
+ 
+             Feature f = getFeatureAtMousePosition(e);
+ 
+             if (f != null) {
+                 String url = f.getURL();
+                 if (url == null) {
+                     String trackURL = getUrl();
+                     if (trackURL != null && f.getIdentifier() != null) {
+                         String encodedID = URLEncoder.encode(f.getIdentifier());
+                         url = trackURL.replaceAll("\\$\\$", encodedID);
+                     }
+                 }
+                 // A scheduler is used so that the browser opening can be canceled in the event of a double
+                 // click.  In that case the first click will schedule the browser opening, but it is delayed
+                 // long enough to enable the second click to cancel it.
+                 if (url != null) {
+                     scheduleBrowserTask(url, UIConstants.getDoubleClickInterval());
+                     e.consume();
+                     return true;
+                 }
+             }
+ 
+         } else
+ 
+         {
+             // This call will cancel opening a browser in the event of a double click
+             cancelBrowserTask();
+         }
+ 
+         return false;
+     }
+ 
+     public Feature getFeatureAtMousePosition(MouseEvent e) {
+         double location = getViewContext().getChromosomePosition(e.getX());
+         double displayLocation = location + 1;
+         Feature f = getFeatureAt(getViewContext().getChrName(), displayLocation, e.getY());
+         return f;
+     }
+ 
+ 
+     @Override
+     public boolean isExpanded() {
+         return expanded;
+     }
+ 
+     /**
+      * Required by the interface, really not applicable to feature tracks
+      */
+     public boolean isLogNormalized() {
+         return true;
+     }
+ 
+ 
+     public void overlay(RenderContext context, Rectangle rect) {
+         getRenderer().setOverlayMode(true);
+         renderFeatures(context, rect);
+     }
+ 
+     public void render(RenderContext context, Rectangle rect) {
+         getRenderer().setOverlayMode(false);
+         Rectangle renderRect = new Rectangle(rect);
+         renderRect.y = renderRect.y + MARGIN;
+         renderRect.height -= MARGIN;
+ 
+ 
+         double windowSize = rect.width * context.getScale();
+ 
+         int vw = getVisibilityWindow();
+         showFeatures = true;
+         if (vw == 0) {
+             showFeatures = !context.getChr().equals(Globals.CHR_ALL);
+         } else if (vw > 0) {
+             showFeatures = !context.getChr().equals(Globals.CHR_ALL) && windowSize <= vw;
+         }
+ 
+         if (showFeatures) {
+             renderFeatures(context, renderRect);
+         } else {
+             renderCoverage(context, renderRect);
+         }
+         boolean showIcon = PreferenceManager.getInstance().getBooleanPreference(PreferenceManager.SHOW_EXPAND_ICON, true);
+         if (showIcon && !IGVMainFrame.getInstance().isExportingSnapshot()) {
+             renderExpandTool(context, rect);
+         }
+     }
+ 
+     private void renderCoverage(RenderContext context, Rectangle inputRect) {
+         List<LocusScore> scores = source.getCoverageScores(context.getChr(), (int) context.getOrigin(),
+                 (int) context.getEndLocation(), context.getZoom());
+         if (scores == null) {
+             Graphics2D g = context.getGraphic2DForColor(Color.gray);
+             Rectangle textRect = new Rectangle(inputRect);
+ 
+             // Keep text near the top of the track rectangle
+             textRect.height = Math.min(inputRect.height, 20);
+             String message = context.getChr().equals(Globals.CHR_ALL) ? "Zoom in to see features." :
+                     "Zoom in to see features, or right-click to increase Feature Visibility Window.";
+             GraphicUtils.drawCenteredText(message, textRect, g);
+         } else {
+             float max = getMaxEstimate(scores);
+             ContinuousColorScale cs = getColorScale();
+             if (cs != null) {
+                 cs.setPosEnd(max);
+             }
+             setDataRange(new DataRange(0, 0, max));
+             coverageRenderer.render(this, scores, context, inputRect);
+         }
+     }
+ 
+ 
+     private float getMaxEstimate(List<LocusScore> scores) {
+         float max = 0;
+         int n = Math.min(200, scores.size());
+         for (int i = 0; i < n; i++) {
+             max = Math.max(max, scores.get(i).getScore());
+         }
+         return max;
+     }
+ 
+ 
+     private boolean featuresLoading = false;
+ 
+ 
+     private int[] p1 = new int[3];
+     private int[] p2 = new int[3];
+ 
+     private void renderExpandTool(RenderContext contect, Rectangle rect) {
+ 
+         if (packedFeatures == null || packedFeatures.getRowCount() <= 1) {
+             return;
+         }
+ 
+         Graphics2D g2d = contect.getGraphic2DForColor(Color.DARK_GRAY);
+         int levelHeight = getHeight() / this.getNumberOfFeatureLevels() + 1;
+ 
+         g2d.clearRect(rect.x, rect.y, EXPAND_ICON_BUFFER_WIDTH, levelHeight);
+ 
+         expandButtonRect.x = rect.x + 3;
+         expandButtonRect.y = rect.y + MARGIN + 4;
+         expandButtonRect.width = 10;
+         expandButtonRect.height = 10;
+ 
+         if (expanded) {
+             p1[0] = expandButtonRect.x;
+             p1[1] = expandButtonRect.x + 8;
+             p1[2] = expandButtonRect.x + 4;
+             p2[0] = expandButtonRect.y;
+             p2[1] = expandButtonRect.y;
+             p2[2] = expandButtonRect.y + 8;
+             g2d.fillPolygon(p1, p2, 3);
+ 
+         } else {
+             p1[0] = expandButtonRect.x;
+             p1[1] = expandButtonRect.x + 8;
+             p1[2] = expandButtonRect.x;
+             p2[0] = expandButtonRect.y;
+             p2[1] = expandButtonRect.y + 4;
+             p2[2] = expandButtonRect.y + 8;
+             g2d.fillPolygon(p1, p2, 3);
+         }
+ 
+     }
+ 
+ 
+     // Render features in the given input rectangle.
+ 
+     private void renderFeatures(RenderContext context, Rectangle inputRect) {
+ 
+         if (featuresLoading) {
+             return;
+         }
+ 
+         //if (log.isDebugEnabled()) {
+         //    log.debug("renderFeatures: " + getName());
+         //}
+ 
+         String chr = context.getChr();
+         int start = (int) context.getOrigin();
+         int end = (int) context.getEndLocation() + 1;
+         if (packedFeatures == null || !packedFeatures.containsInterval(chr, start, end)) {
+             featuresLoading = true;
+             int maxEnd = end;
+             Genome genome = ViewContext.getInstance().getGenome();
+             if (genome != null) {
+                 Chromosome c = genome.getChromosome(chr);
+                 if (c != null) maxEnd = Math.max(c.getLength(), end);
+             }
+             int delta = (end - start) / 2;
+             int expandedStart = Math.max(0, start - delta);
+             int expandedEnd = Math.min(maxEnd, end + delta);
+ 
+             loadFeatures(chr, expandedStart, expandedEnd);
+ 
+             if (!IGVMainFrame.getInstance().isExportingSnapshot()) {
+                 return;
+             }
+         }
+ 
+ 
+         if (expanded) {
+             List<FeatureRow> rows = packedFeatures.rows;
+             if (rows != null && rows.size() > 0) {
+ 
+                 int nLevels = rows.size();
+                 synchronized (featureRects) {
+ 
+                     featureRects.clear();
+ 
+                     // Divide rectangle into equal height levels
+                     double h = inputRect.getHeight() / nLevels;
+                     Rectangle rect = new Rectangle(inputRect.x, inputRect.y, inputRect.width, (int) h);
+                     for (FeatureRow row : rows) {
+                         featureRects.add(new Rectangle(rect));
+                         getRenderer().renderFeatures(row.features, context, rect, this);
+                         rect.y += h;
+                     }
+                 }
+             }
+         } else {
+             List<Feature> features = packedFeatures.features;
+             if (features != null) {
+                 getRenderer().renderFeatures(features, context, inputRect, this);
+             }
+         }
+ 
+ 
+     }
+ 
+     /**
+      * Loads and segregates features into rows such that they do not overlap.  Loading is done in a background
+      * thread.
+      *
+      * @param chr
+      * @param start
+      * @param end
+      */
+     private void loadFeatures(final String chr, final int start, final int end) {
+ 
+         NamedRunnable runnable = new NamedRunnable() {
+             public void run() {
+                 try {
+ 
+                     // TODO -- implement source to return iterators
+                     Iterator<Feature> iter = source.getFeatures(chr, start, end);
+                     if (iter == null) {
+                         packedFeatures = new PackedFeatures(chr, start, end);
+                     } else {
+                         packedFeatures = new PackedFeatures(chr, start, end, iter, getName());
+                     }
+ 
+                     IGVMainFrame.getInstance().repaint();
+                 } catch (Throwable e) {
+                     // Mark the interval with an empty feature list to prevent an endless loop of load
+                     // attempts.
+                     packedFeatures = new PackedFeatures(chr, start, end);
+                     String msg = "Error loading features for interval: " +
+                             chr + ":" + start + "-" + end + " <br>" + e.toString();
+                     MessageUtils.showMessage(msg);
+                     log.error(msg, e);
+                 }
+ 
+                 finally {
+                     featuresLoading = false;
+                     if (log.isDebugEnabled()) {
+                         log.debug("features loaded");
+                     }
+                 }
+             }
+ 
+             public String getName() {
+                 return "Load features: " + FeatureTrack.this.getName();
+             }
+         };
+ 
+         LongRunningTask.submit(runnable);
+     }
+ 
+ 
+     @Override
+     public void setExpanded(boolean value) {
+         expanded = value;
+     }
+ 
+     @Override
+     public void setHeight(int newHeight) {
+ 
+         int levelCount = this.getNumberOfFeatureLevels();
+         super.setHeight(Math.max(getMinimumHeight(), newHeight / levelCount));
+     }
+ 
+     public void setRendererClass(Class rc) {
+         try {
+             renderer = (FeatureRenderer) rc.newInstance();
+         } catch (Exception ex) {
+             log.error("Error instatiating renderer ", ex);
+         }
+     }
+ 
++>>>>>>> upstream/1.5.56
      public void setStatType(WindowFunction type) {
      }
  
@@@ -595,8 -610,16 +967,21 @@@
                          while (nextStart < chrLength) {
                              int nextEnd = binSize > 0 ? nextStart + source.getBinSize() : chrLength;
                              Iterator<Feature> iter = source.getFeatures(nextChr, nextStart, nextEnd);
++<<<<<<< HEAD
 +                            if (iter != null && iter.hasNext()) {
 +                                return iter.next();
++=======
+ 
+                             // The check on position should not be neccessary, but not all implementations of getFeatures
+                             // obey the contract to return features only in the interval.
+                             if (iter != null) {
+                                 while (iter.hasNext()) {
+                                     Feature feat = iter.next();
+                                     if (feat.getStart() > nextStart) {
+                                         return feat;
+                                     }
+                                 }
++>>>>>>> upstream/1.5.56
                              }
                              nextStart = nextEnd;
                          }
@@@ -611,11 -634,17 +996,25 @@@
                          while (nextEnd > 0) {
                              int nextStart = binSize > 0 ? Math.max(0, nextEnd - source.getBinSize()) : 0;
                              Iterator<Feature> iter = source.getFeatures(nextChr, nextStart, nextEnd);
++<<<<<<< HEAD
 +                            if (iter.hasNext()) {
 +                                while (iter.hasNext()) {
 +                                    f = iter.next();
 +                                }
 +                                return f;
++=======
+                             if (iter != null && iter.hasNext()) {
+                                 Feature prevFeature = null;
+                                 while (iter.hasNext()) {
+                                     Feature feat = iter.next();
+                                     if (feat.getStart() < nextEnd) {
+                                         prevFeature = feat;
+                                     }
+                                 }
+                                 if (prevFeature != null) {
+                                     return prevFeature;
+                                 }
++>>>>>>> upstream/1.5.56
                              }
                              nextEnd = nextStart;
                          }
@@@ -626,6 -655,6 +1025,69 @@@
                      }
                  }
              }
++<<<<<<< HEAD
++        }
++
++        return f;
++    }
++
++    public int getVisibilityWindow() {
++        return visibilityWindow;
++    }
++
++    public void setVisibilityWindow(int windowSize) {
++        this.visibilityWindow = windowSize;
++        source.setBinSize(visibilityWindow);
++    }
++
++    @Override
++    public void restorePersistentState(Map<String, String> attributes) {
++        super.restorePersistentState(attributes);    //To change body of overridden methods use File | Settings | File Templates.
++
++        String fvw = attributes.get(FEATURE_VISIBILITY_WINDOW);
++        if (fvw != null) {
++            try {
++                visibilityWindow = Integer.parseInt(fvw);
++            } catch (NumberFormatException e) {
++                log.error("Error restoring visibilityWindow: " + fvw);
++            }
++        }
++
++    }
++
++    @Override
++    public Map<String, String> getPersistentState() {
++        Map<String, String> stateMap = super.getPersistentState();
++        stateMap.put(FEATURE_VISIBILITY_WINDOW, String.valueOf(visibilityWindow));
++        return stateMap;
++
++    }
++
++    //public Feature nextFeature(String chr, double position, boolean forward) {
++//
++//    return source.nextFeature(chr, position, forward);
++//}
++
++
++    static class FeatureRow {
++        int start;
++        int end;
++        List<Feature> features;
++
++        FeatureRow() {
++            this.features = new ArrayList(100);
++        }
++
++        void addFeature(Feature feature) {
++            if (features.isEmpty()) {
++                this.start = feature.getStart();
++            }
++            features.add(feature);
++            end = feature.getEnd();
++        }
++    }
++
++=======
          }
  
          return f;
@@@ -687,6 -716,6 +1149,7 @@@
          }
      }
  
++>>>>>>> upstream/1.5.56
  
      static class PackedFeatures {
          private String trackName;
diff --combined src/org/broad/igv/track/IndexedBEDFeatureSource.java
index 58b7bcf,e01b11e..afc2ed9
--- a/src/org/broad/igv/track/IndexedBEDFeatureSource.java
+++ b/src/org/broad/igv/track/IndexedBEDFeatureSource.java
@@@ -87,7 -87,7 +87,11 @@@ public class IndexedBEDFeatureSource im
  
      private FeatureIndex getIndex() {
          if (featureIndex == null) {
++<<<<<<< HEAD
 +            featureIndex = SamUtils.getIndexFor(bedFile);
++=======
+             featureIndex = SamUtils.getIndexFor(bedFile.getAbsolutePath());
++>>>>>>> upstream/1.5.56
          }
          return featureIndex;
      }
@@@ -107,7 -107,7 +111,11 @@@
  
          final List<Feature> features = new ArrayList();
          if (featureIndex == null) {
++<<<<<<< HEAD
 +            featureIndex = SamUtils.getIndexFor(bedFile);
++=======
+             featureIndex = SamUtils.getIndexFor(bedFile.getAbsolutePath());
++>>>>>>> upstream/1.5.56
          }
  
          if (featureIndex == null) {
@@@ -171,7 -171,7 +179,11 @@@
  
      public boolean hasIndex() {
          if (featureIndex == null) {
++<<<<<<< HEAD
 +            featureIndex = SamUtils.getIndexFor(bedFile);
++=======
+             featureIndex = SamUtils.getIndexFor(bedFile.getAbsolutePath());
++>>>>>>> upstream/1.5.56
          }
          return featureIndex != null;
      }
diff --combined src/org/broad/igv/track/TrackLoader.java
index 4c9a61e,6ba3b7c..e8faf42
--- a/src/org/broad/igv/track/TrackLoader.java
+++ b/src/org/broad/igv/track/TrackLoader.java
@@@ -84,7 -84,8 +84,12 @@@ public class TrackLoader 
  
  
              if (typeString.endsWith(".tbi")) {
++<<<<<<< HEAD
 +                MessageUtils.showMessage("<html><b>Error:</b> Loading tabix index files (.tbi) is not supported.  Load the .gz file ");
++=======
+                 MessageUtils.showMessage("<html><b>Error:</b>File type '.tbi' is not recognized.  If this is a 'tabix' index <br>" +
+                         " load the associated gzipped file, which should have an extension of '.gz'");
++>>>>>>> upstream/1.5.56
              }
  
              // Check for index
@@@ -163,7 -164,7 +168,11 @@@
              } else if (typeString.endsWith(".psl") || typeString.endsWith(".psl.gz") ||
                      typeString.endsWith(".pslx") || typeString.endsWith(".pslx.gz")) {
                  loadPslFile(locator, newTracks);
++<<<<<<< HEAD
 +            } else if(AbstractFeatureParser.getInstanceFor(locator) != null) {
++=======
+             } else if (AbstractFeatureParser.getInstanceFor(locator) != null) {
++>>>>>>> upstream/1.5.56
                  loadFeatureFile(locator, newTracks);
              } else if (MutationParser.isMutationAnnotationFile(locator)) {
                  this.loadMutFile(locator, newTracks);
@@@ -195,7 -196,7 +204,11 @@@
                  if (locator.getColor() != null) {
                      track.setColor(locator.getColor());
                  }
++<<<<<<< HEAD
 +                if(locator.getSampleId() != null) {
++=======
+                 if (locator.getSampleId() != null) {
++>>>>>>> upstream/1.5.56
                      track.setSampleId(locator.getSampleId());
                  }
                  IGVMainFrame.getInstance().getTrackManager().addLoadedType(track.getTrackType());
@@@ -319,7 -320,6 +332,10 @@@
          }
  
  
++<<<<<<< HEAD
 +
++=======
++>>>>>>> upstream/1.5.56
      }
  
      /**
@@@ -846,7 -846,7 +862,11 @@@
          // TODO - -handle remote resource
          SegmentedAsciiDataSet ds = new SegmentedAsciiDataSet(locator);
          String path = locator.getPath();
++<<<<<<< HEAD
 +        TrackProperties props = ds.getTrackProperties(); 
++=======
+         TrackProperties props = ds.getTrackProperties();
++>>>>>>> upstream/1.5.56
          for (String trackName : ds.getDataHeadings()) {
              String trackId = path + "_" + trackName;
              SegmentedDataSource dataSource = new SegmentedDataSource(trackName, ds);
@@@ -855,7 -855,7 +875,11 @@@
              track.setRendererClass(HeatmapRenderer.class);
              track.setTrackType(ds.getType());
  
++<<<<<<< HEAD
 +            if(props != null) {
++=======
+             if (props != null) {
++>>>>>>> upstream/1.5.56
                  track.setTrackProperties(props);
              }
  
@@@ -885,10 -885,24 +909,31 @@@
          // TODO -- move the source creation to a factory
  
  
++<<<<<<< HEAD
 +        FeatureSource featureSource = new DASFeatureSource(locator);
 +
 +        FeatureTrack track = new FeatureTrack(locator, featureSource);
 +        track.setName(locator.getTrackName());
++=======
+         DASFeatureSource featureSource = null;
+         try {
+             featureSource = new DASFeatureSource(locator);
+         } catch (MalformedURLException e) {
+             log.error("Malformed URL", e);
+             throw new DataLoadException("Error: Malformed URL ", locator.getPath());
+         }
+ 
+         FeatureTrack track = new FeatureTrack(locator, featureSource);
+ 
+         // Try to create a sensible name from the path
+         String name = locator.getPath();
+         if (locator.getPath().contains("genome.ucsc.edu")) {
+             name = featureSource.getType();
+         } else {
+             name = featureSource.getPath().replace("/das/", "").replace("/features", "");
+         }
+         track.setName(name);
++>>>>>>> upstream/1.5.56
  
          // A hack until we can notate this some other way
          if (locator.getPath().contains("cosmic")) {
diff --combined src/org/broad/igv/track/TrackManager.java
index edb6b76,9ade623..79f7823
--- a/src/org/broad/igv/track/TrackManager.java
+++ b/src/org/broad/igv/track/TrackManager.java
@@@ -164,6 -164,6 +164,8 @@@ public class TrackManager 
      }
  
      public void sortAlignmentTracks(AlignmentTrack.SortOption option) {
++<<<<<<< HEAD
++=======
          for (Track t : getAllTracks(false)) {
              if (t instanceof AlignmentTrack) {
                  ((AlignmentTrack) t).sortRows(option);
@@@ -171,6 -171,14 +173,15 @@@
          }
      }
  
+     public void sortAlignmentTracks(AlignmentTrack.SortOption option, double location) {
++>>>>>>> upstream/1.5.56
+         for (Track t : getAllTracks(false)) {
+             if (t instanceof AlignmentTrack) {
+                 ((AlignmentTrack) t).sortRows(option, location);
+             }
+         }
+     }
+ 
      public void packAlignmentTracks() {
          for (Track t : getAllTracks(false)) {
              if (t instanceof AlignmentTrack) {
@@@ -233,7 -241,7 +244,11 @@@
                  List<Track> tracks = load(locator);
                  group.addTracks(tracks);
                  tracksWereLoaded = tracks.size() > 0;
++<<<<<<< HEAD
 +            } catch (Exception e) {
++=======
+             } catch (Throwable e) {
++>>>>>>> upstream/1.5.56
                  log.error("Error loading tracks", e);
                  messages.append(e.getMessage());
              }
@@@ -273,7 -281,7 +288,11 @@@
  
  
                  }
++<<<<<<< HEAD
 +            } 
++=======
+             }
++>>>>>>> upstream/1.5.56
              return newTracks;
  
          } catch (DataLoadException dle) {
@@@ -658,7 -666,7 +677,11 @@@
          }
  
          FeatureTrack geneFeatureTrack = new FeatureTrack("Genes", new FeatureCollectionSource(featureMap));
++<<<<<<< HEAD
 +        geneFeatureTrack.setMinimumHeight(5);
++=======
+         geneFeatureTrack.setMinimumHeight(30);
++>>>>>>> upstream/1.5.56
          geneFeatureTrack.setHeight(30);
          geneFeatureTrack.setRendererClass(BasicFeatureRenderer.class);
          geneFeatureTrack.setColor(Color.BLUE.darker());
@@@ -674,6 -682,7 +697,10 @@@
  
              GeneTrack gt = new GeneTrack(geneFeatureTrack, seqTrack);
              gt.setName(geneTrackName);
++<<<<<<< HEAD
++=======
+             gt.setHeight(45);
++>>>>>>> upstream/1.5.56
  
              Genome genome = GenomeManager.getInstance().getGenome(genomeId);
              if (genome != null && gt.getUrl() == null) {
diff --combined src/org/broad/igv/track/TrackMenuUtils.java
index 5bde433,8882673..cf0abc3
--- a/src/org/broad/igv/track/TrackMenuUtils.java
+++ b/src/org/broad/igv/track/TrackMenuUtils.java
@@@ -18,11 -18,11 +18,15 @@@
  
  package org.broad.igv.track;
  
 +import com.jidesoft.utils.SwingWorker;
  import com.jidesoft.swing.JidePopupMenu;
  import org.apache.commons.math.stat.StatUtils;
  import org.apache.log4j.Logger;
  import org.broad.igv.PreferenceManager;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.feature.Exon;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.feature.Feature;
  import org.broad.igv.feature.SequenceManager;
  import org.broad.igv.renderer.*;
@@@ -107,7 -107,7 +111,11 @@@ public class TrackMenuUtils 
          } else if (hasDataTracks) {
              addDataItems(menu, tracks);
          } else {
++<<<<<<< HEAD
 +            addFeatureItems(menu, tracks, e);
++=======
+             addFeatureItems(menu, tracks, e, hasFeatureTracks);
++>>>>>>> upstream/1.5.56
          }
      }
  
@@@ -222,6 -222,6 +230,7 @@@
          menu.add(scaleHeading);
  
          menu.add(getDataRangeItem(tracks));
++<<<<<<< HEAD
  
          if (tracks.size() > 0) {
              menu.add(getLogScaleItem(tracks));
@@@ -240,6 -240,6 +249,26 @@@
  
          menu.add(getTrackRenameItem(tracks));
  
++=======
++
++        if (tracks.size() > 0) {
++            menu.add(getLogScaleItem(tracks));
++        }
++
++        menu.add(getAutoscaleItem(tracks));
++
++        menu.add(getHeatmapScaleItem(tracks));
++
++        menu.add(getShowDataRangeItem(tracks));
++
++        JLabel trackSettingsHeading = new JLabel(LEADING_HEADING_SPACER + "Track Settings", JLabel.LEFT);
++        trackSettingsHeading.setFont(newFont);
++
++        menu.add(trackSettingsHeading);
++
++        menu.add(getTrackRenameItem(tracks));
++
++>>>>>>> upstream/1.5.56
          addTrackSettingsMenuItems(menu, false, tracks);
  
      }
@@@ -249,12 -249,9 +278,18 @@@
       *
       * @return
       */
++<<<<<<< HEAD
 +    private static void addFeatureItems(JPopupMenu featurePopupMenu, final Collection<Track> tracks, MouseEvent e) {
 +
 +        //JPopupMenu featurePopupMenu = new JidePopupMenu();
 +
 +        //JLabel popupTitle = new JLabel(LEADING_HEADING_SPACER + title,
 +        //        JLabel.CENTER);
++=======
+     private static void addFeatureItems(JPopupMenu featurePopupMenu, final Collection<Track> tracks,
+                                         MouseEvent e, boolean hasFeatureTracks) {
+ 
++>>>>>>> upstream/1.5.56
  
          Font newFont = featurePopupMenu.getFont().deriveFont(Font.BOLD, 12);
          // popupTitle.setFont(newFont);
@@@ -262,10 -259,10 +297,18 @@@
          //     featurePopupMenu.add(popupTitle);
          //     featurePopupMenu.addSeparator();
          // }
++<<<<<<< HEAD
++=======
+ 
++>>>>>>> upstream/1.5.56
  
+         JLabel trackSettingsHeading = new JLabel(LEADING_HEADING_SPACER + "Track Settings", JLabel.LEFT);
  
++<<<<<<< HEAD
 +        JLabel trackSettingsHeading = new JLabel(LEADING_HEADING_SPACER + "Track Settings", JLabel.LEFT);
 +
++=======
++>>>>>>> upstream/1.5.56
          trackSettingsHeading.setFont(newFont);
  
          featurePopupMenu.add(trackSettingsHeading);
@@@ -273,23 -270,41 +316,61 @@@
          featurePopupMenu.add(getTrackRenameItem(tracks));
  
          featurePopupMenu.add(getExpandCollapseItem(tracks));
++<<<<<<< HEAD
 +
 +        featurePopupMenu.add(getChangeFontSizeItem(tracks));
 +
 +        if (tracks.size() == 1) {
 +            Track t = tracks.iterator().next();
 +            Feature f = t.getFeatureAtMousePosition(e);
 +            if (f != null) {
 +                featurePopupMenu.addSeparator();
 +                featurePopupMenu.add(getCopyDetailsItem(f, e.getX()));
 +                featurePopupMenu.add(getCopySequenceItem(f));
 +
 +            }
 +        }
 +
 +        featurePopupMenu.addSeparator();
 +        featurePopupMenu.add(getChangeFeatureWindow(tracks));
 +        featurePopupMenu.addSeparator();
++=======
+ 
+         if (hasFeatureTracks) {
+             featurePopupMenu.add(getChangeFontSizeItem(tracks));
+ 
+             if (tracks.size() == 1) {
+                 Track t = tracks.iterator().next();
+                 Feature f = t.getFeatureAtMousePosition(e);
+                 if (f != null) {
+                     featurePopupMenu.addSeparator();
+                     featurePopupMenu.add(getCopyDetailsItem(f, e.getX()));
+ 
+                     // If we are over an exon, copy its sequence instead of the entire feature.
+                     double position = ViewContext.getInstance().getChromosomePosition(e.getX());
+                     Collection<Exon> exons = f.getExons();
+                     if (exons != null) {
+                         for (Exon exon : exons) {
+                             if (position > exon.getStart() && position < exon.getEnd()) {
+                                 f = exon;
+                                 break;
+                             }
+                         }
+                     }
+ 
+                     featurePopupMenu.add(getCopySequenceItem(f));
+ 
+                     f.getExons();
+ 
+                 }
+             }
+ 
+             featurePopupMenu.addSeparator();
+             featurePopupMenu.add(getChangeFeatureWindow(tracks));
+             featurePopupMenu.addSeparator();
+         }
+ 
++>>>>>>> upstream/1.5.56
          addTrackSettingsMenuItems(featurePopupMenu, true, tracks);
      }
  
@@@ -344,18 -359,7 +425,22 @@@
  
          menu.add(getChangeTrackHeightItem(tracks));
  
++<<<<<<< HEAD
 +
 +        // Remove tracks by attribute
 +        item = new JMenuItem("Remove Tracks");
 +        item.addActionListener(new ActionListener() {
 +
 +            public void actionPerformed(ActionEvent e) {
 +
 +                (new RemoveTracksWorker(tracks)).execute();
 +                clearTrackSelections();
 +            }
 +        });
 +        menu.add(item);
++=======
+         menu.add(getRemoveMenuItem(tracks));
++>>>>>>> upstream/1.5.56
      }
  
  
@@@ -471,11 -475,11 +556,19 @@@
          });
          return item;
      }
++<<<<<<< HEAD
 +
 +    private static JMenuItem getLogScaleItem(final Collection<Track> selectedTracks) {
 +        // Change track height by attribute
 +
 +
++=======
+ 
+     private static JMenuItem getLogScaleItem(final Collection<Track> selectedTracks) {
+         // Change track height by attribute
+ 
+ 
++>>>>>>> upstream/1.5.56
          final JCheckBoxMenuItem logScaleItem = new JCheckBoxMenuItem("Log scale");
          final boolean logScale = selectedTracks.iterator().next().getDataRange().isLog();
          logScaleItem.setSelected(logScale);
@@@ -600,8 -604,42 +693,46 @@@
          JMenuItem item = new JMenuItem("Remove Track" + (multiple ? "s" : ""));
          item.addActionListener(new ActionListener() {
  
+ 
              public void actionPerformed(ActionEvent e) {
++<<<<<<< HEAD
 +                (new RemoveTracksWorker(selectedTracks)).execute();
++=======
+ 
+                 if (selectedTracks.isEmpty()) {
+                     return;
+                 }
+ 
+                 StringBuffer buffer = new StringBuffer();
+                 for (Track track : selectedTracks) {
+                     buffer.append("\n\t");
+                     buffer.append(track.getName());
+                 }
+                 String deleteItems = buffer.toString();
+ 
+                 JTextArea textArea = new JTextArea();
+                 textArea.setEditable(false);
+                 JScrollPane scrollPane = new JScrollPane(textArea);
+                 textArea.setText(deleteItems);
+ 
+                 JOptionPane optionPane = new JOptionPane(scrollPane,
+                         JOptionPane.PLAIN_MESSAGE,
+                         JOptionPane.YES_NO_OPTION);
+                 optionPane.setPreferredSize(new Dimension(550, 500));
+                 JDialog dialog = optionPane.createDialog(IGVMainFrame.getInstance(),
+                         "Remove The Following Tracks");
+                 dialog.setVisible(true);
+ 
+                 Object choice = optionPane.getValue();
+                 if ((choice != null) && (JOptionPane.YES_OPTION == ((Integer) choice).intValue())) {
+ 
+ 
+                     IGVMainFrame.getInstance().getTrackManager().removeTracks(selectedTracks);
+                     IGVMainFrame.getInstance().doResizeTrackPanels();
+                     IGVMainFrame.getInstance().doRefresh();
+                 }
+ 
++>>>>>>> upstream/1.5.56
                  clearTrackSelections();
              }
          });
@@@ -678,14 -716,14 +809,25 @@@
      }
  
      public static void changeFeatureVisibilityWindow(final Collection<Track> selectedTracks) {
++<<<<<<< HEAD
 +
 +        Collection<FeatureTrack> featureTracks = new ArrayList(selectedTracks.size());
 +        for (Track t : selectedTracks) {
 +            if (t instanceof FeatureTrack) {
 +                featureTracks.add((FeatureTrack) t);
 +            }
 +        }
 +
++=======
+ 
+         Collection<FeatureTrack> featureTracks = new ArrayList(selectedTracks.size());
+         for (Track t : selectedTracks) {
+             if (t instanceof FeatureTrack) {
+                 featureTracks.add((FeatureTrack) t);
+             }
+         }
+ 
++>>>>>>> upstream/1.5.56
          if (featureTracks.isEmpty()) {
              return;
          }
@@@ -804,7 -842,7 +946,11 @@@
                  double location = ViewContext.getInstance().getChromosomePosition(mouseX);
                  String details = f.getValueString(location, null);
                  if (details != null) {
++<<<<<<< HEAD
 +                    details = details.replace("<br>",  System.getProperty("line.separator"));
++=======
+                     details = details.replace("<br>", System.getProperty("line.separator"));
++>>>>>>> upstream/1.5.56
                      details += System.getProperty("line.separator") +
                              f.getChr() + ":" + (f.getStart() + 1) + "-" + f.getEnd();
                      StringSelection stringSelection = new StringSelection(details);
@@@ -895,78 -933,25 +1041,98 @@@
              public void actionPerformed(ActionEvent e) {
                  changeFeatureVisibilityWindow(selectedTracks);
                  clearTrackSelections();
++<<<<<<< HEAD
 +            }
 +        });
 +        return item;
 +    }
 +
 +    public static JMenuItem getChangeFontSizeItem(final Collection<Track> selectedTracks) {
 +        // Change track height by attribute
 +        JMenuItem item = new JMenuItem("Change Font Size");
 +        item.addActionListener(new ActionListener() {
 +
 +            public void actionPerformed(ActionEvent e) {
 +                changeFontSize(selectedTracks);
 +                clearTrackSelections();
++=======
++>>>>>>> upstream/1.5.56
              }
          });
          return item;
      }
  
++<<<<<<< HEAD
 +
 +    static class RemoveTracksWorker extends SwingWorker {
 +
 +        Collection<Track> selectedTracks;
 +
 +        RemoveTracksWorker(final Collection<Track> selectedTracks) {
 +            this.selectedTracks = new HashSet<Track>(selectedTracks);
 +        }
 +
 +        @Override
 +        protected Object doInBackground() throws Exception {
 +
 +            if (selectedTracks.isEmpty()) {
 +                return null;
 +            }
 +
 +            StringBuffer buffer = new StringBuffer();
 +            for (Track track : selectedTracks) {
 +                buffer.append("\n\t");
 +                buffer.append(track.getName());
 +            }
 +            String deleteItems = buffer.toString();
 +
 +            JTextArea textArea = new JTextArea();
 +            textArea.setEditable(false);
 +            JScrollPane scrollPane = new JScrollPane(textArea);
 +            textArea.setText(deleteItems);
 +
 +            JOptionPane optionPane = new JOptionPane(scrollPane,
 +                    JOptionPane.PLAIN_MESSAGE,
 +                    JOptionPane.YES_NO_OPTION);
 +            optionPane.setPreferredSize(new Dimension(550, 500));
 +            JDialog dialog = optionPane.createDialog(IGVMainFrame.getInstance(),
 +                    "Remove The Following Tracks");
 +            dialog.setVisible(true);
 +
 +            Object choice = optionPane.getValue();
 +            if ((choice == null) || (JOptionPane.YES_OPTION != ((Integer) choice).intValue())) {
 +                return null;
 +            }
 +
 +            IGVMainFrame.getInstance().getTrackManager().removeTracks(selectedTracks);
 +            IGVMainFrame.getInstance().doResizeTrackPanels();
 +            //IGVMainFrame.getInstance().showLoadedTrackCount();
 +            //IGVMainFrame.getInstance().getContentPane().repaint();
 +            return null;
 +        }
 +
 +        @Override
 +        protected void done() {
 +            IGVMainFrame.getInstance().doRefresh();
 +        }
 +    }
 +
++=======
+     public static JMenuItem getChangeFontSizeItem(final Collection<Track> selectedTracks) {
+         // Change track height by attribute
+         JMenuItem item = new JMenuItem("Change Font Size");
+         item.addActionListener(new ActionListener() {
+ 
+             public void actionPerformed(ActionEvent e) {
+                 changeFontSize(selectedTracks);
+                 clearTrackSelections();
+             }
+         });
+         return item;
+     }
+ 
+ 
++>>>>>>> upstream/1.5.56
      public static void clearTrackSelections() {
          IGVMainFrame.getInstance().getTrackManager().clearSelections();
      }
diff --combined src/org/broad/igv/track/tribble/CachingFeatureReader.java
index f26de40,9e693b0..d09349e
--- a/src/org/broad/igv/track/tribble/CachingFeatureReader.java
+++ b/src/org/broad/igv/track/tribble/CachingFeatureReader.java
@@@ -21,6 -21,8 +21,11 @@@ package org.broad.igv.track.tribble
  import net.sf.samtools.util.CloseableIterator;
  import org.apache.log4j.Logger;
  import org.broad.igv.exceptions.DataLoadException;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.feature.Genome;
+ import org.broad.igv.session.ViewContext;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.ui.util.MessageUtils;
  import org.broad.igv.util.LRUCache;
  import org.broad.igv.util.RuntimeUtils;
@@@ -36,17 -38,14 +41,26 @@@ import java.util.Set
  
  
  /**
++<<<<<<< HEAD
 + * Created by IntelliJ IDEA.
 + * User: jrobinso
 + * Date: Jun 24, 2010
 + * Time: 10:45:32 PM
 + * To change this template use File | Settings | File Templates.
++=======
+  * Author: jrobinso
+  * Date: Jun 24, 2010
++>>>>>>> upstream/1.5.56
   */
  public class CachingFeatureReader implements FeatureReader {
  
      private static Logger log = Logger.getLogger(CachingFeatureReader.class);
      String cachedChr = "";
++<<<<<<< HEAD
 +    static int maxTileCount = 10;
++=======
+     static int maxTileCount = 5;
++>>>>>>> upstream/1.5.56
      private static int defaultTileSize = 1000000;
      private int tileSize = defaultTileSize;
      FeatureReader reader;
@@@ -58,10 -57,9 +72,16 @@@
      }
  
  
++<<<<<<< HEAD
 +
 +    public CachingFeatureReader(FeatureReader reader, int tileSize) {
 +        this.reader = reader;
 +        this.cache = new LRUCache(maxTileCount);
++=======
+     public CachingFeatureReader(FeatureReader reader, int tileSize) {
+         this.reader = reader;
+         this.cache = new LRUCache(this, maxTileCount);
++>>>>>>> upstream/1.5.56
          this.tileSize = tileSize;
      }
  
@@@ -95,6 -93,9 +115,12 @@@
  
      /**
       * TODO -- implement contained support (specifically contained == true).  Not needed for IGV
++<<<<<<< HEAD
++=======
+      * <p/>
+      * tileSize == 0 implies cache by whole chromosome (1 tile)
+      *
++>>>>>>> upstream/1.5.56
       * @param chr
       * @param start
       * @param end
@@@ -104,8 -105,12 +130,17 @@@
       */
      public CloseableTribbleIterator query(String chr, int start, int end, boolean contained) throws IOException {
  
++<<<<<<< HEAD
 +        int startTile = start / tileSize;
 +        int endTile = end / tileSize;    // <= inclusive
++=======
+         int startTile = 0;
+         int endTile = 0;
+         if (tileSize > 0) {
+             startTile = start / tileSize;
+             endTile = end / tileSize;    // <= inclusive
+         }
++>>>>>>> upstream/1.5.56
          List<Tile> tiles = getTiles(chr, startTile, endTile);
  
          if (tiles.size() == 0) {
@@@ -138,9 -143,6 +173,12 @@@
      private List<Tile> getTiles(String seq, int startTile, int endTile) {
  
          if (!seq.equals(cachedChr)) {
++<<<<<<< HEAD
 +            if (log.isDebugEnabled()) {
 +                log.debug("Creating cache for: " + seq);
 +            }
++=======
++>>>>>>> upstream/1.5.56
              cache.clear();
              cachedChr = seq;
          }
@@@ -153,9 -155,6 +191,12 @@@
              Tile tile = cache.get(t);
  
              if (tile == null) {
++<<<<<<< HEAD
 +                if (log.isDebugEnabled()) {
 +                    log.debug("Tile cache miss: " + t);
 +                }
++=======
++>>>>>>> upstream/1.5.56
                  int start = t * tileSize;
                  int end = start + tileSize;
                  tile = new Tile(t, start, end);
@@@ -186,9 -185,9 +227,15 @@@
  
      private boolean loadTiles(String seq, List<Tile> tiles) {
  
++<<<<<<< HEAD
 +        assert(tiles.size() > 0);
 +
 +         if (log.isDebugEnabled()) {
++=======
+         assert (tiles.size() > 0);
+ 
+         if (log.isDebugEnabled()) {
++>>>>>>> upstream/1.5.56
              int first = tiles.get(0).getTileNumber();
              int end = tiles.get(tiles.size() - 1).getTileNumber();
              log.debug("Loading tiles: " + first + "-" + end);
@@@ -198,9 -197,6 +245,12 @@@
          int end = tiles.get(tiles.size() - 1).end;
          CloseableIterator<Feature> iter = null;
  
++<<<<<<< HEAD
 +        //log.debug("Loading : " + start + " - " + end);
 +        int featureCount = 0;
 +        long t0 = System.currentTimeMillis();
++=======
++>>>>>>> upstream/1.5.56
          try {
              iter = reader.query(seq, start, end);
  
@@@ -210,17 -206,26 +260,38 @@@
                  // Range of tile indeces that this alignment contributes to.
                  int aStart = record.getStart();
                  int aEnd = record.getEnd();
++<<<<<<< HEAD
 +                int idx0 = Math.max(0, (aStart - start) / tileSize);
 +                int idx1 = Math.min(tiles.size() - 1, (aEnd - start) / tileSize);
++=======
+                 int idx0 = 0;
+                 int idx1 = 0;
+                 if (tileSize > 0) {
+                     idx0 = Math.max(0, (aStart - start) / tileSize);
+                     idx1 = Math.min(tiles.size() - 1, (aEnd - start) / tileSize);
+                 }
++>>>>>>> upstream/1.5.56
  
                  // Loop over tiles this read overlaps
                  for (int i = idx0; i <= idx1; i++) {
                      Tile t = tiles.get(i);
  
++<<<<<<< HEAD
 +                    if ((aStart >= t.start) && (aStart < t.end)) {
 +                        t.containedRecords.add(record);
 +                    } else if ((aEnd >= t.start) && (aStart < t.start)) {
 +                        t.overlappingRecords.add(record);
++=======
+                     // A tile end of zero => the tile represents the entire chromosome
+                     if (t.end <= 0) {
+                         t.containedRecords.add(record);
+                     } else {
+                         if ((aStart >= t.start) && (aStart < t.end)) {
+                             t.containedRecords.add(record);
+                         } else if ((aEnd >= t.start) && (aStart < t.start)) {
+                             t.overlappingRecords.add(record);
+                         }
++>>>>>>> upstream/1.5.56
                      }
                  }
              }
@@@ -257,7 -262,6 +328,10 @@@
      }
  
  
++<<<<<<< HEAD
 +
++=======
++>>>>>>> upstream/1.5.56
      static class Tile {
  
          private boolean loaded = false;
diff --combined src/org/broad/igv/track/tribble/CodecFactory.java
index 7c77b9d,ea06996..9ca57dd
--- a/src/org/broad/igv/track/tribble/CodecFactory.java
+++ b/src/org/broad/igv/track/tribble/CodecFactory.java
@@@ -22,11 -22,7 +22,15 @@@ import org.broad.igv.exceptions.DataLoa
  import org.broad.tribble.FeatureCodec;
  
  /**
++<<<<<<< HEAD
 + * Created by IntelliJ IDEA.
 + * User: jrobinso
 + * Date: Jun 28, 2010
 + * Time: 11:40:43 AM
 + * To change this template use File | Settings | File Templates.
++=======
+  * 
++>>>>>>> upstream/1.5.56
   */
  public class CodecFactory {
      public static FeatureCodec getCodec(String file) {
diff --combined src/org/broad/igv/track/tribble/TribbleFeatureSource.java
index d01a971,e3abf48..4dc2974
--- a/src/org/broad/igv/track/tribble/TribbleFeatureSource.java
+++ b/src/org/broad/igv/track/tribble/TribbleFeatureSource.java
@@@ -28,12 -28,14 +28,20 @@@ import org.broad.igv.tdf.TDFDataSource
  import org.broad.igv.tdf.TDFReader;
  import org.broad.igv.track.FeatureSource;
  import org.broad.igv.util.ParsingUtils;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.util.RuntimeUtils;
++>>>>>>> upstream/1.5.56
  import org.broad.tribble.FeatureCodec;
  import org.broad.tribble.FeatureReader;
  import org.broad.tribble.readers.BasicFeatureReader;
  import org.broad.tribble.util.CloseableTribbleIterator;
  
  import java.io.IOException;
++<<<<<<< HEAD
++=======
+ import java.util.Collection;
++>>>>>>> upstream/1.5.56
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
@@@ -41,8 -43,8 +49,13 @@@
  public class TribbleFeatureSource implements FeatureSource {
  
      CachingFeatureReader reader;
++<<<<<<< HEAD
 +
 +    DataSource coverageSource;
++=======
+     DataSource coverageSource;
+     boolean isVCF;
++>>>>>>> upstream/1.5.56
  
      /**
       * Map of IGV chromosome name -> source name
@@@ -54,19 -56,18 +67,30 @@@
      public TribbleFeatureSource(String path) throws IOException {
  
          FeatureCodec codec = CodecFactory.getCodec(path);
++<<<<<<< HEAD
 +
++=======
+         isVCF = codec instanceof VCFCodec;
++>>>>>>> upstream/1.5.56
          BasicFeatureReader basicReader = new BasicFeatureReader(path, codec);
          header = basicReader.getHeader();
          initBinSize(basicReader);
          reader = new CachingFeatureReader(basicReader, getBinSize());
++<<<<<<< HEAD
 +
++=======
++>>>>>>> upstream/1.5.56
          init();
          initCoverageSource(path + ".tdf");
  
      }
  
      private void initCoverageSource(String covPath) {
++<<<<<<< HEAD
 +        if (ParsingUtils.pathExists(covPath))   {
++=======
+         if (ParsingUtils.pathExists(covPath)) {
++>>>>>>> upstream/1.5.56
              TDFReader reader = TDFReader.getReader(covPath);
              coverageSource = new TDFDataSource(reader, 0, "");
          }
@@@ -75,12 -76,14 +99,23 @@@
      private void init() {
          Genome genome = ViewContext.getInstance().getGenome();
          if (genome != null) {
++<<<<<<< HEAD
 +            for (String seqName : reader.getSequenceNames()) {
 +                String igvChr = genome.getChromosomeAlias(seqName);
 +                if (igvChr != null && !igvChr.equals(seqName)) {
 +                    chrNameMap.put(igvChr, seqName);
 +                }
 +            }
++=======
+             Collection<String> seqNames = reader.getSequenceNames();
+             if (seqNames != null)
+                 for (String seqName : seqNames) {
+                     String igvChr = genome.getChromosomeAlias(seqName);
+                     if (igvChr != null && !igvChr.equals(seqName)) {
+                         chrNameMap.put(igvChr, seqName);
+                     }
+                 }
++>>>>>>> upstream/1.5.56
          }
      }
  
@@@ -128,48 -131,53 +163,98 @@@
          return header;
      }
  
++<<<<<<< HEAD
 +
 +    private void initBinSize(FeatureReader reader) {
 +        int m = 10000;
 +        double density = estimateDensity(reader);
 +        if (density == -1) {
 +            binSize = 100000;
 +        } else {
 +            int tmp = (int) (m / density);
 +            binSize = Math.max(30000, tmp);
 +        }
 +    }
 +
 +    private double estimateDensity(FeatureReader reader) {
 +
 +
 +        int number = 10000;
 +        int n = 0;
 +        org.broad.tribble.Feature firstFeature = null;
 +        org.broad.tribble.Feature lastFeature = null;
 +        CloseableTribbleIterator<org.broad.tribble.Feature> iter = null;
 +
 +        try {
 +            iter = reader.iterator();
 +
 +            while (iter.hasNext() && n < number) {
 +                org.broad.tribble.Feature f = iter.next();
 +                if (f != null) {
 +                    if (firstFeature == null) {
 +                        firstFeature = f;
 +                    } else {
 +                        lastFeature = f;
 +                    }
 +                    n++;
 +                }
 +            }
 +            if (n > 1) {
 +                return ((double) n) / (lastFeature.getStart() - firstFeature.getStart());
 +            } else {
 +                return -1;
 +            }
 +        } catch (IOException e) {
 +            return -1;
++=======
+     // Estimate a binSize (featureVisibilitWindow) such that each bin contains ~ 10 mbytes of features
+ 
+     private void initBinSize(FeatureReader reader) {
+ 
+         CloseableTribbleIterator<org.broad.tribble.Feature> iter = null;
+ 
+         try {
+             double mem = RuntimeUtils.getAvailableMemory();
+             iter = reader.iterator();
+             if (iter.hasNext()) {
+ 
+                 int nSamples = isVCF ? 100 : 1000;
+                 org.broad.tribble.Feature firstFeature = iter.next();
+                 org.broad.tribble.Feature lastFeature = iter.next();
+                 String chr = firstFeature.getChr();
+                 int n = 1;
+                 long len = 0;
+                 while (iter.hasNext() && n < nSamples) {
+                     org.broad.tribble.Feature f = iter.next();
+                     if (f != null) {
+                         n++;
+                         if (f.getChr().equals(chr)) {
+                             lastFeature = f;
+                         } else {
+                             len += lastFeature.getEnd() - firstFeature.getStart() + 1;
+                             firstFeature = f;
+                             lastFeature = f;
+                             chr = f.getChr();
+                         }
+ 
+                     }
+                 }
+                 double dMem = mem - RuntimeUtils.getAvailableMemory();
+                 double bytesPerFeature = Math.max(100, dMem / n);
+ 
+                 len += lastFeature.getEnd() - firstFeature.getStart() + 1;
+                 double featuresPerBase = ((double) n) / len;
+ 
+                 double targetBinMemory =  10000000;  // 10  mega bytes
+                 int maxBS = isVCF ? 1000000 : Integer.MAX_VALUE;
+                 int bs = Math.min(maxBS, (int) (targetBinMemory / (bytesPerFeature * featuresPerBase)));
+                 binSize = Math.max(100000, bs);
+             } else {
+                 binSize = Integer.MAX_VALUE;
+             }
+         } catch (IOException e) {
+             binSize = 1000000;
++>>>>>>> upstream/1.5.56
          }
          finally {
              if (iter != null) {
diff --combined src/org/broad/igv/ui/IGVCommandBar.java
index e96c89d,7f5ed3f..20a43e8
--- a/src/org/broad/igv/ui/IGVCommandBar.java
+++ b/src/org/broad/igv/ui/IGVCommandBar.java
@@@ -40,7 -40,6 +40,10 @@@ import org.broad.igv.ui.util.ProgressBa
  import org.broad.igv.ui.util.ProgressMonitor;
  import org.broad.igv.ui.util.UIUtilities;
  import org.broad.igv.util.LRUCache;
++<<<<<<< HEAD
 +import org.broad.igv.util.LongRunningTask;
++=======
++>>>>>>> upstream/1.5.56
  import org.broad.igv.util.NamedRunnable;
  
  import javax.swing.*;
@@@ -56,7 -55,6 +59,6 @@@ import java.io.FileNotFoundException
  import java.net.NoRouteToHostException;
  import java.util.*;
  import java.util.List;
- import java.util.concurrent.ExecutionException;
  
  /**
   * @author jrobinso
@@@ -373,10 -371,10 +375,10 @@@ public class IGVCommandBar extends java
              }
  
              LinkedHashSet<GenomeListItem> cacheGenomeItemList =
-                     GenomeManager.getInstance().getCachedGenomeArchiveList(excludedArchivesUrls);
+                     GenomeManager.getInstance().getCachedGenomeArchiveList();
  
              LinkedHashSet<GenomeListItem> clientSideItemList =
-                     GenomeManager.getInstance().getUserDefinedGenomeArchiveList(excludedArchivesUrls);
+                     GenomeManager.getInstance().getUserDefinedGenomeArchiveList();
  
              setGenomeItemList(clientSideItemList, serverSideItemList, cacheGenomeItemList);
              setGenomeItemListModel();
@@@ -459,7 -457,7 +461,11 @@@
          String p = "";
  
          if (!chr.equals(Globals.CHR_ALL)) {
++<<<<<<< HEAD
 +            p = getViewContext().getCurrentLocusString();
++=======
+             p = getViewContext().getFormattedLocusString();
++>>>>>>> upstream/1.5.56
          }
          final String position = p;
          UIUtilities.invokeOnEventThread(new Runnable() {
@@@ -639,17 -637,16 +645,20 @@@
      /**
       * Called from session loading,  command line listener, startup code
       */
-     public void selectGenomeFromList(final String gid)
+     public void selectGenomeFromList(final String genomeId)
              throws FileNotFoundException, NoRouteToHostException {
  
  
          // See if this genome is already loaded
          String currentGenomeId = ViewContext.getInstance().getGenomeId();
++<<<<<<< HEAD
 +        if (currentGenomeId != null && gid != null && gid.equalsIgnoreCase(currentGenomeId)) {
++=======
+         if (currentGenomeId != null && genomeId != null && genomeId.equalsIgnoreCase(currentGenomeId)) {
++>>>>>>> upstream/1.5.56
              return;
          }
  
-         final String genomeId = checkGenomeId(gid);
  
  
          NamedRunnable runnable = new NamedRunnable() {
@@@ -733,7 -730,7 +742,11 @@@
              }
  
              public String getName() {
++<<<<<<< HEAD
 +                return "selectGenomeFromList: " + gid;  //To change body of implemented methods use File | Settings | File Templates.
++=======
+                 return "selectGenomeFromList: " + genomeId;  //To change body of implemented methods use File | Settings | File Templates.
++>>>>>>> upstream/1.5.56
              }
          };
  
@@@ -1172,30 -1169,4 +1185,33 @@@
      }
  
  
++<<<<<<< HEAD
 +    private String checkGenomeId(String genomeId) {
 +        // See if the genomeID is available
 +        Map<String, String> aliasTable = GenomeManager.getInstance().getGenomeAliasTable();
 +
 +        if (aliasTable != null && !aliasTable.isEmpty()) {
 +
 +            int cnt = genomeComboBox.getItemCount();
 +            Set<String> availableIds = new HashSet(cnt);
 +            for (int i = 0; i < cnt; i++) {
 +                Object item = genomeComboBox.getItemAt(i);
 +                if (item instanceof GenomeListItem) {
 +                    GenomeListItem genomeListItem = (GenomeListItem) item;
 +                    availableIds.add(genomeListItem.getId());
 +                }
 +            }
 +            if (!availableIds.contains(genomeId)) {
 +                String altGenomeId = aliasTable.get(genomeId);
 +                if (altGenomeId != null && availableIds.contains(altGenomeId)) {
 +                    return altGenomeId;
 +                }
 +            }
 +        }
 +        return genomeId;
 +    }
 +
 +
++=======
++>>>>>>> upstream/1.5.56
  }
diff --combined src/org/broad/igv/ui/IGVMainFrame.java
index 55fa997,5b079ec..4cdae75
--- a/src/org/broad/igv/ui/IGVMainFrame.java
+++ b/src/org/broad/igv/ui/IGVMainFrame.java
@@@ -34,12 -34,10 +34,10 @@@ import org.broad.igv.Globals
  import org.broad.igv.PreferenceManager;
  import org.broad.igv.data.IGVDatasetParser;
  import org.broad.igv.event.StatusChangeEvent;
- import org.broad.igv.feature.FeatureDB;
- import org.broad.igv.feature.GenomeDescriptor;
- import org.broad.igv.feature.GenomeManager;
+ import org.broad.igv.feature.*;
  import org.broad.igv.feature.GenomeManager.GenomeListItem;
- import org.broad.igv.feature.MaximumContigGenomeException;
  import org.broad.igv.listener.StatusListener;
+ import org.broad.igv.main.BatchRunner;
  import org.broad.igv.main.CommandListener;
  import org.broad.igv.session.Session;
  import org.broad.igv.session.SessionReader;
@@@ -66,7 -64,6 +64,10 @@@ import org.broad.igv.ui.util.ProgressMo
  import static org.broad.igv.ui.util.UIUtilities.getFileChooser;
  
  import org.broad.igv.util.*;
++<<<<<<< HEAD
 +import org.jdesktop.layout.GroupLayout;
++=======
++>>>>>>> upstream/1.5.56
  
  import javax.swing.*;
  import javax.swing.filechooser.FileFilter;
@@@ -162,7 -159,11 +163,15 @@@ public class IGVMainFrame extends javax
  
      public static IGVMainFrame getInstance() {
          if (theInstance == null) {
++<<<<<<< HEAD
 +            theInstance = new IGVMainFrame();
++=======
+             if (Globals.isHeadless()) {
+                 System.err.println("Attempt to create IGVMainFrame in headless mode.");
+             } else {
+                 theInstance = new IGVMainFrame();
+             }
++>>>>>>> upstream/1.5.56
          }
          return theInstance;
      }
@@@ -383,7 -384,7 +392,7 @@@
      private void initializeDefaultUserDirectory() {
  
          // Create the user directory
-         File defaultUserDirectory = new File(DEFAULT_IGV_DIRECTORY);
+         File defaultUserDirectory = getIgvDirectory();
          if (!defaultUserDirectory.exists()) {
              boolean exists = defaultUserDirectory.exists();
              if (!exists) {
@@@ -736,8 -737,7 +745,12 @@@
                  File importDirectory =
                          PreferenceManager.getInstance().getLastGenomeImportDirectory();
                  if (importDirectory == null) {
++<<<<<<< HEAD
 +                    PreferenceManager.getInstance().setLastGenomeImportDirectory(
 +                            new File(UIConstants.getDefaultUserDirectory()));
++=======
+                     PreferenceManager.getInstance().setLastGenomeImportDirectory(UIConstants.getUserDirectory());
++>>>>>>> upstream/1.5.56
                  }
  
                  FileFilter[] fileFilters = {new GenericUtilities.GenomeArchiveFileFilter()};
@@@ -911,59 -911,54 +924,110 @@@
      public void loadTracks(final Collection<ResourceLocator> locators, boolean doInBackground) {
  
          ((ApplicationStatusBar) statusBar).setMessage("Loading ...");
++<<<<<<< HEAD
 +
 +        log.debug("Run loadTracks");
 +
 +        boolean tracksWereLoaded = false;
 +        CursorToken token = null;
 +
 +        try {
 +            token = WaitCursorManager.showWaitCursor();
 +            if (locators != null && !locators.isEmpty()) {
 +
 +                // get current track count per panel.  Needed to detect which panels
 +                // changed.  Also record panel sizes
 +                final HashMap<TrackPanelScrollPane, Integer> trackCountMap = new HashMap();
 +                final HashMap<TrackPanelScrollPane, Integer> panelSizeMap = new HashMap();
 +                for (TrackPanelScrollPane sp : trackManager.getTrackPanelScrollPanes()) {
 +                    trackCountMap.put(sp, sp.getDataPanel().getAllTracks().size());
 +                    panelSizeMap.put(sp, sp.getDataPanel().getHeight());
 +                }
 +
 +                tracksWereLoaded = getTrackManager().loadResources(locators);
 +
 +                if (tracksWereLoaded) {
 +                    UIUtilities.invokeOnEventThread(new Runnable() {
 +
 +                        public void run() {
 +
 +                            for (TrackPanelScrollPane sp : trackManager.getTrackPanelScrollPanes()) {
 +                                if (trackCountMap.containsKey(sp)) {
 +                                    int prevTrackCount = trackCountMap.get(sp).intValue();
 +                                    if (prevTrackCount != sp.getDataPanel().getAllTracks().size()) {
 +                                        //TODO Do not do a resize if this is a session reload
 +                                        sp.getDataPanel().doResize();
 +                                        int scrollPosition = panelSizeMap.get(sp);
 +                                        if (prevTrackCount != 0 && sp.getVerticalScrollBar().isShowing()) {
 +                                            sp.getVerticalScrollBar().setMaximum(sp.getDataPanel().getHeight());
 +                                            sp.getVerticalScrollBar().setValue(scrollPosition);
 +                                        }
 +                                    }
 +                                }
 +                            }
 +
 +                            // Adjust divider for data panel.  The data panel divider can be
 +                            // zero if there are no data tracks loaded.
 +                            TrackPanelScrollPane dsp = trackManager.getScrollPane(TrackManager.DATA_PANEL_NAME);
 +                            if (dsp.getDataPanel().getAllTracks().size() > 0 &&
 +                                    centerSplitPane.getDividerLocation(0) < 10) {
 +                                centerSplitPane.setDividerLocation(0, 40);
 +                            }
 +
 +                            doRefresh();
 +
 +                        }
 +                    });
++=======
+ 
+         log.debug("Run loadTracks");
+ 
+         boolean tracksWereLoaded = false;
+         CursorToken token = null;
+ 
+         try {
+             token = WaitCursorManager.showWaitCursor();
+             if (locators != null && !locators.isEmpty()) {
+ 
+                 // get current track count per panel.  Needed to detect which panels
+                 // changed.  Also record panel sizes
+                 final HashMap<TrackPanelScrollPane, Integer> trackCountMap = new HashMap();
+                 final HashMap<TrackPanelScrollPane, Integer> panelSizeMap = new HashMap();
+                 for (TrackPanelScrollPane sp : trackManager.getTrackPanelScrollPanes()) {
+                     trackCountMap.put(sp, sp.getDataPanel().getAllTracks().size());
+                     panelSizeMap.put(sp, sp.getDataPanel().getHeight());
+                 }
+ 
+                 tracksWereLoaded = getTrackManager().loadResources(locators);
+ 
+                 if (tracksWereLoaded) {
+ 
+                     for (TrackPanelScrollPane sp : trackManager.getTrackPanelScrollPanes()) {
+                         if (trackCountMap.containsKey(sp)) {
+                             int prevTrackCount = trackCountMap.get(sp).intValue();
+                             if (prevTrackCount != sp.getDataPanel().getAllTracks().size()) {
+                                 //TODO Do not do a resize if this is a session reload
+                                 sp.getDataPanel().doResize();
+                                 int scrollPosition = panelSizeMap.get(sp);
+                                 if (prevTrackCount != 0 && sp.getVerticalScrollBar().isShowing()) {
+                                     sp.getVerticalScrollBar().setMaximum(sp.getDataPanel().getHeight());
+                                     sp.getVerticalScrollBar().setValue(scrollPosition);
+                                 }
+                             }
+                         }
+                     }
+ 
+                     // Adjust divider for data panel.  The data panel divider can be
+                     // zero if there are no data tracks loaded.
+                     TrackPanelScrollPane dsp = trackManager.getScrollPane(TrackManager.DATA_PANEL_NAME);
+                     if (dsp.getDataPanel().getAllTracks().size() > 0 &&
+                             centerSplitPane.getDividerLocation(0) < 10) {
+                         centerSplitPane.setDividerLocation(0, 40);
+                     }
+ 
+                     doRefresh();
+ 
++>>>>>>> upstream/1.5.56
                  }
              }
          } catch (Exception e) {
@@@ -1048,7 -1043,7 +1112,7 @@@
  
          boolean hasImportedGenomes = true;
          try {
-             hasImportedGenomes = !GenomeManager.getInstance().getUserDefinedGenomeArchiveList(null).isEmpty();
+             hasImportedGenomes = !GenomeManager.getInstance().getUserDefinedGenomeArchiveList().isEmpty();
  
          } catch (IOException iOException) {
              // Ignore
@@@ -1301,13 -1296,13 +1365,23 @@@
  
  
          menuItems.add(new HistoryMenu("Go to"));
++<<<<<<< HEAD
 +
  
++=======
+ 
++
++>>>>>>> upstream/1.5.56
          // Add to IGVPanel menu
          MenuAction dataMenuAction = new MenuAction("View", null, KeyEvent.VK_V);
          return MenuAndToolbarUtils.createMenu(menuItems, dataMenuAction);
  
  
++<<<<<<< HEAD
++    }
++
++    private JMenu createToolsMenu() {
++=======
      }
  
      private JMenu createToolsMenu() {
@@@ -1331,11 -1326,11 +1405,35 @@@
  
  
      private JMenu createExtrasMenu() {
++>>>>>>> upstream/1.5.56
++
++        List<JComponent> menuItems = new ArrayList<JComponent>();
++        MenuAction menuAction = null;
++
++<<<<<<< HEAD
++        // Sort Context
++        menuAction = new SortTracksMenuAction("Launch Tools...", KeyEvent.VK_T, this) {
++            @Override
++            public void actionPerformed(ActionEvent e) {
++                IgvToolsGui.launch(false, session.getViewContext().getGenomeId());
++            }
++        };
++        menuItems.add(MenuAndToolbarUtils.createMenuItem(menuAction));
++
++        MenuAction toolsMenuAction = new MenuAction("Tools", null, KeyEvent.VK_T);
++        return MenuAndToolbarUtils.createMenu(menuItems, toolsMenuAction);
++
++    }
++
++
++    private JMenu createExtrasMenu() {
  
          List<JComponent> menuItems = new ArrayList<JComponent>();
  
          MenuAction menuAction = null;
  
++=======
++>>>>>>> upstream/1.5.56
          // Preferences reset
          menuAction = new ResetPreferencesAction("Reset Preferences", this);
          menuItems.add(MenuAndToolbarUtils.createMenuItem(menuAction));
@@@ -1693,10 -1688,11 +1791,18 @@@
          final CheckListDialog dlg = new CheckListDialog(this, allAttributes, hiddenAttributes, false);
          dlg.setVisible(true);
  
++<<<<<<< HEAD
 +
 +        AttributeManager.getInstance().setHiddenAttributes(dlg.getNonSelections());
 +        doRefresh();
 +        getContentPane().repaint();
++=======
+         if (!dlg.isCanceled()) {
+             AttributeManager.getInstance().setHiddenAttributes(dlg.getNonSelections());
+             doRefresh();
+             getContentPane().repaint();
+         }
++>>>>>>> upstream/1.5.56
  
      }
  
@@@ -1944,10 -1940,8 +2050,15 @@@
      public void createNewSession(String sessionName) {
          LRUCache.clearCaches();
  
++<<<<<<< HEAD
 +        session = new Session(sessionName);
 +
 +        AttributeManager.getInstance().clearAllAttributes();
 +
++=======
+         AttributeManager.getInstance().clearAllAttributes();
+ 
++>>>>>>> upstream/1.5.56
          setTitle(UIConstants.APPLICATION_NAME);
  
          if (filterTracksAction != null) {
@@@ -1955,7 -1949,8 +2066,12 @@@
          }
  
          AttributeManager.getInstance().clearAllAttributes();
++<<<<<<< HEAD
 +        session = new Session(null);
++=======
+         session = new Session(sessionName);
+ 
++>>>>>>> upstream/1.5.56
  
          // Remove user added panels
          for (TrackPanelScrollPane tsp : trackManager.getTrackPanelScrollPanes()) {
@@@ -2121,6 -2116,20 +2237,23 @@@
          return sp;
      }
  
++<<<<<<< HEAD
++=======
+     /**
+      * Return an ordered list of track panels.  This method is provided primarily for storing sessions, where
+      * the track panels need to be stored in order.
+      */
+     public List<TrackPanel> getTrackPanels() {
+         ArrayList panels = new ArrayList();
+         for (Component c : centerSplitPane.getComponents()) {
+             if (c instanceof TrackPanelScrollPane) {
+                 panels.add(((TrackPanelScrollPane) c).getTrackPanel());
+             }
+         }
+         return panels;
+     }
+ 
++>>>>>>> upstream/1.5.56
      public void tweakPanelDivider() {
          UIUtilities.invokeOnEventThread(new Runnable() {
  
@@@ -2338,7 -2347,7 +2471,11 @@@
              CursorToken token = WaitCursorManager.showWaitCursor();
              try {
                  inputStream = new BufferedInputStream(new FileInputStream(sessionFile));
++<<<<<<< HEAD
 +                doRestoreSession(inputStream, sessionFile.toString(), locus, false);
++=======
+                 doRestoreSession(inputStream, sessionFile.getAbsolutePath(), locus, false);
++>>>>>>> upstream/1.5.56
  
                  String sessionFilePath = sessionFile.getAbsolutePath();
                  if (!recentSessionList.contains(sessionFilePath)) {
@@@ -2385,7 -2394,7 +2522,7 @@@
              InputStream inputStream = null;
              try {
                  inputStream = new BufferedInputStream(sessionURL.openStream());
-                 doRestoreSession(inputStream, URLDecoder.decode(sessionURL.getFile(), "UTF-8"), locus, false);
+                 doRestoreSession(inputStream, sessionURL.toString(), locus, false);
              } catch (Exception e) {
                  String message = "Failed to load session! : " + sessionURL;
                  MessageUtils.showAndLogErrorMessage(IGVMainFrame.this, message, log, e);
@@@ -2420,7 -2429,7 +2557,7 @@@
      }
  
      final public void doRestoreSession(final InputStream inputStream,
-                                        final String sessionName,
+                                        final String sessionPath,
                                         final String locus,
                                         boolean merge) {
  
@@@ -2428,22 -2437,22 +2565,38 @@@
              setStatusBarMessage("Opening session...");
  
              if (!merge) {
++<<<<<<< HEAD
 +                createNewSession(sessionName);
 +            }
 +
 +            (new SessionReader()).loadSession(inputStream, session, sessionName);
++=======
+                 createNewSession(sessionPath);
+             }
+ 
+             (new SessionReader()).loadSession(inputStream, session, sessionPath);
++>>>>>>> upstream/1.5.56
              String searchText = locus == null ? session.getLocus() : locus;
  
              // NOTE: Nothing to do if chr == all
              if (searchText != null && !searchText.equals(Globals.CHR_ALL) && searchText.trim().length() > 0) {
                  igvCommandBar.searchByLocus(searchText);
              }
++<<<<<<< HEAD
 +            
 +            setTitle(UIConstants.APPLICATION_NAME + " - Session: " + sessionName);
 +            LRUCache.clearCaches();
 +            doRefresh();
 +        } catch (Exception e) {
 +            String message = "Failed to load session! : " + sessionName;
++=======
+ 
+             setTitle(UIConstants.APPLICATION_NAME + " - Session: " + sessionPath);
+             LRUCache.clearCaches();
+             doRefresh();
+         } catch (Exception e) {
+             String message = "Failed to load session! : " + sessionPath;
++>>>>>>> upstream/1.5.56
              MessageUtils.showAndLogErrorMessage(IGVMainFrame.this, message, log, e);
          } finally {
  
@@@ -2533,7 -2542,7 +2686,11 @@@
          System.setProperty("http.agent", Globals.applicationString());
  
          FileUtils.addRollingAppenderToRootLogger();
++<<<<<<< HEAD
 +        log.info("Default User Directory: " + UIConstants.getDefaultUserDirectory());
++=======
+         log.info("Default User Directory: " + UIConstants.getUserDirectory());
++>>>>>>> upstream/1.5.56
  
          Thread.setDefaultUncaughtExceptionHandler(new DefaultExceptionHandler());
  
@@@ -2614,6 -2623,7 +2771,10 @@@
          String dataFileString = null;
          String locusString = null;
          String propertyFile = null;
++<<<<<<< HEAD
++=======
+         String genomeId = null;
++>>>>>>> upstream/1.5.56
  
          IGVArgs(String[] args) {
              parseArgs(args);
@@@ -2627,16 -2637,18 +2788,31 @@@
              CmdLineParser parser = new CmdLineParser();
              CmdLineParser.Option propertyFileOption = parser.addStringOption('p', "preferences");
              CmdLineParser.Option batchFileOption = parser.addStringOption('b', "batch");
++<<<<<<< HEAD
 +            propertyFile = (String) parser.getOptionValue(propertyFileOption);
 +            batchFile = (String) parser.getOptionValue(batchFileOption);
 +
 +            try {
 +                parser.parse(args);
 +            } catch (CmdLineParser.IllegalOptionValueException e) {
 +                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
 +            } catch (CmdLineParser.UnknownOptionException e) {
 +                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
 +            }
++=======
+             CmdLineParser.Option genomeOption = parser.addStringOption('g', "genome");
+             try {
+                 parser.parse(args);
+             } catch (CmdLineParser.IllegalOptionValueException e) {
+                 e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+             } catch (CmdLineParser.UnknownOptionException e) {
+                 e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+             }
+ 
+             propertyFile = (String) parser.getOptionValue(propertyFileOption);
+             batchFile = (String) parser.getOptionValue(batchFileOption);
+             genomeId = (String) parser.getOptionValue(genomeOption);
++>>>>>>> upstream/1.5.56
  
              String[] nonOptionArgs = parser.getRemainingArgs();
              if (nonOptionArgs != null && nonOptionArgs.length > 0) {
@@@ -2683,11 -2695,11 +2859,19 @@@
  
              // Load the last genome and chromosome
              String genomeId = PreferenceManager.getInstance().getDefaultGenome();
++<<<<<<< HEAD
 +            setGenomeId(genomeId);
 +
 +            String chrName = PreferenceManager.getInstance().getLastChromosomeViewed();
 +            getViewContext().setChromosomeName(chrName);
 +            getViewContext().history.push(chrName);
++=======
+ 
+             if (genomeId == null) {
+                 genomeId = GenomeManager.getInstance().getTopGenomeListItem().getId();
+             }
+             setGenomeId(genomeId);
++>>>>>>> upstream/1.5.56
  
              monitor.fireProgressChange(50);
  
@@@ -2709,13 -2721,13 +2893,23 @@@
              if (igvArgs.propertyFile != null) {
  
              }
++<<<<<<< HEAD
+ 
+             //If there is an argument assume it is a session file or url
+             if (igvArgs.sessionFile != null || igvArgs.dataFileString != null) {
+ 
+                 System.out.println("Session file = " + igvArgs.sessionFile);
+                 System.out.println("Locus = " + igvArgs.locusString);
+ 
++=======
 +
 +            //If there is an argument assume it is a session file or url
 +            if (igvArgs.sessionFile != null || igvArgs.dataFileString != null) {
 +
 +                System.out.println("Session file = " + igvArgs.sessionFile);
 +                System.out.println("Locus = " + igvArgs.locusString);
 +
++>>>>>>> upstream/1.5.56
                  if (log.isDebugEnabled()) {
                      log.debug("Loadding session data");
                  }
@@@ -2733,29 -2745,39 +2927,88 @@@
                          log.debug("Calling restore session");
                      }
  
 +                    if (igvArgs.sessionFile != null) {
 +                        if (igvArgs.sessionFile.startsWith("http:") ||
 +                                igvArgs.sessionFile.startsWith("https:") ||
 +                                igvArgs.sessionFile.startsWith("file:")) {
 +                            URL url = new URL(igvArgs.sessionFile);
 +                            doRestoreSession(url, igvArgs.locusString);
 +                        } else {
 +                            File sf = new File(igvArgs.sessionFile);
 +                            if (sf.exists()) {
 +                                doRestoreSession(sf, igvArgs.locusString);
 +                            }
 +                        }
 +                    } else if (igvArgs.dataFileString != null) {
 +                        // Not an xml file, assume its a list of data files
 +                        String[] tokens = igvArgs.dataFileString.split(",");
 +                        List<ResourceLocator> locators = new ArrayList();
 +                        for (String p : tokens) {
 +                            locators.add(new ResourceLocator(p));
 +                        }
 +                        IGVMainFrame.getInstance().getTrackManager().loadResources(locators);
 +                    }
 +
++<<<<<<< HEAD
++                    if (igvArgs.locusString != null) {
++                        goToLocus(igvArgs.locusString);
++                    }
++
++                } catch (Exception ex) {
++                    String tmp = igvArgs.sessionFile != null ? igvArgs.sessionFile : igvArgs.dataFileString;
++                    JOptionPane.showMessageDialog(IGVMainFrame.this, "<html>Error loading session: " + tmp + "<br>" + ex.toString());
++                    log.error("Error loading session: " + tmp, ex);
++                }
++
++
++                indefMonitor.stop();
++                closeWindow(bar2);
++            }
++
++            UIUtilities.invokeOnEventThread(new Runnable() {
++                public void run() {
++                    setVisible(true);
++                }
++            });
++
++
++            return null;
++        }
++
+ 
++=======
+                     if (igvArgs.genomeId != null) {
+                         selectGenomeFromList(igvArgs.genomeId);
+                     }
+ 
+                     if (igvArgs.sessionFile != null) {
+                         log.info("Loading session " + igvArgs.sessionFile);
+                         if (igvArgs.sessionFile.startsWith("http:") ||
+                                 igvArgs.sessionFile.startsWith("https:") ||
+                                 igvArgs.sessionFile.startsWith("file:")) {
+                             URL url = new URL(igvArgs.sessionFile);
+                             doRestoreSession(url, igvArgs.locusString);
+                         } else {
+                             File sf = new File(igvArgs.sessionFile);
+                             if (sf.exists()) {
+                                 doRestoreSession(sf, igvArgs.locusString);
+                             }
+                         }
+                         doRefresh();
+                     } else if (igvArgs.dataFileString != null) {
+                         // Not an xml file, assume its a list of data files
+                         log.info("Loading session " + igvArgs.dataFileString);
+                         String[] tokens = igvArgs.dataFileString.split(",");
+                         List<ResourceLocator> locators = new ArrayList();
+                         for (String p : tokens) {
+                             locators.add(new ResourceLocator(p));
+                         }
+                         getTrackManager().loadResources(locators);
+                         doRefresh();
+                     }
+ 
                      if (igvArgs.locusString != null) {
+                         log.info("Goto " + igvArgs.locusString);
                          goToLocus(igvArgs.locusString);
                      }
  
@@@ -2768,6 -2790,18 +3021,18 @@@
  
                  indefMonitor.stop();
                  closeWindow(bar2);
+             } else {
+                 String chrName = PreferenceManager.getInstance().getLastChromosomeViewed();
+                 //Check that this chromosome exists
+                 Genome genome = ViewContext.getInstance().getGenome();
+                 if (genome != null) {
+                     if (genome.getChromosome(chrName) != null) {
+                         goToLocus(chrName);
+                     } else {
+                         goToLocus(genome.getHomeChromosome());
+                     }
+                 }
+ 
              }
  
              UIUtilities.invokeOnEventThread(new Runnable() {
@@@ -2781,13 -2815,13 +3046,18 @@@
          }
  
  
++>>>>>>> upstream/1.5.56
          /**
           * Called when the background thread is complete (IGV window is open and data loaded).
           */
          @Override
          protected void done() {
              if (igvArgs.batchFile != null) {
++<<<<<<< HEAD
 +                // TODO -- execute batch thread here
++=======
+                 LongRunningTask.submit(new BatchRunner(igvArgs.batchFile));
++>>>>>>> upstream/1.5.56
              }
          }
  
diff --combined src/org/broad/igv/ui/PreferencesEditor.java
index 8c1a0cc,acba82a..bfeecf6
--- a/src/org/broad/igv/ui/PreferencesEditor.java
+++ b/src/org/broad/igv/ui/PreferencesEditor.java
@@@ -18,9 -18,9 +18,15 @@@
  package org.broad.igv.ui;
  
  import java.awt.*;
++<<<<<<< HEAD
 +import java.awt.Component;
 +import java.awt.event.*;
 +import javax.swing.border.*;
++=======
+ import java.awt.event.*;
+ import javax.swing.border.*;
+ 
++>>>>>>> upstream/1.5.56
  import com.jidesoft.dialog.*;
  import com.jidesoft.swing.*;
  import org.broad.igv.PreferenceManager;
@@@ -34,11 -34,13 +40,15 @@@ import org.broad.igv.util.IGVHttpUtils
  import org.broad.igv.util.Utilities;
  
  import javax.swing.*;
+ import java.util.Arrays;
  import java.util.HashMap;
  import java.util.Map;
 +import org.jdesktop.layout.GroupLayout;
 +import org.jdesktop.layout.LayoutStyle;
  
+ import org.jdesktop.layout.GroupLayout;
+ import org.jdesktop.layout.LayoutStyle;
+ 
  /**
   * @author jrobinso
   */
@@@ -49,19 -51,24 +59,39 @@@ public class PreferencesEditor extends 
      PreferenceManager prefMgr = PreferenceManager.getInstance();
      boolean updateOverlays = false;
      boolean inputValidated = true;
++<<<<<<< HEAD
 +    int initialSamMaxLevel = 0;
 +    int initialSamQualityThreshold = 0;
 +    float initialAlleleFreqThreshold;
 +    boolean initialShowDuplicates = false;
 +    boolean initialFilterFailedReads = true;
++=======
++>>>>>>> upstream/1.5.56
      private static int lastSelectedIndex = 0;
      boolean proxySettingsChanged;
  
  
++<<<<<<< HEAD
 +
 +    private void normalizeCoverageCBFocusLost(FocusEvent e) {
 +        // TODO add your code here
 +    }
++=======
+     private void normalizeCoverageCBFocusLost(FocusEvent e) {
+         // TODO add your code here
+     }
+ 
+     private void clearAllProxyButtonActionPerformed(ActionEvent e) {
+         if (MessageUtils.confirm("This will immediately clear all proxy settings.  Are you sure?")) {
+             this.proxyHostField.setText("");
+             this.proxyPortField.setText("");
+             this.proxyUsernameField.setText("");
+             this.proxyPasswordField.setText("");
+             this.useProxyCB.setSelected(false);
+             PreferenceManager.getInstance().clearProxySettings();
+         }
+     }
++>>>>>>> upstream/1.5.56
  
      public PreferencesEditor(java.awt.Frame parent, boolean modal) {
          super(parent, modal);
@@@ -133,7 -140,7 +163,11 @@@
          alignmentPanel = new JPanel();
          jPanel1 = new JPanel();
          jPanel11 = new JPanel();
++<<<<<<< HEAD
 +        samMaxLevelField = new JTextField();
++=======
+         samMaxLevelsField = new JTextField();
++>>>>>>> upstream/1.5.56
          snpThresholdField = new JTextField();
          jLabel11 = new JLabel();
          jLabel26 = new JLabel();
@@@ -187,7 -194,7 +221,11 @@@
          jPanel9 = new JPanel();
          useByteRangeCB = new JCheckBox();
          jLabel25 = new JLabel();
++<<<<<<< HEAD
 +        jPanel14 = new JPanel();
++=======
+         proxyPanel = new JPanel();
++>>>>>>> upstream/1.5.56
          jPanel15 = new JPanel();
          jPanel16 = new JPanel();
          proxyUsernameField = new JTextField();
@@@ -201,6 -208,8 +239,11 @@@
          jLabel27 = new JLabel();
          jLabel23 = new JLabel();
          useProxyCB = new JCheckBox();
++<<<<<<< HEAD
++=======
+         label3 = new JLabel();
+         clearAllProxyButton = new JButton();
++>>>>>>> upstream/1.5.56
          okCancelButtonPanel = new ButtonPanel();
          okButton = new JButton();
          cancelButton = new JButton();
@@@ -277,45 -286,45 +320,87 @@@
                      GroupLayout jPanel10Layout = new GroupLayout(jPanel10);
                      jPanel10.setLayout(jPanel10Layout);
                      jPanel10Layout.setHorizontalGroup(
++<<<<<<< HEAD
 +                        jPanel10Layout.createParallelGroup()
 +                            .add(jPanel10Layout.createSequentialGroup()
 +                                .addContainerGap()
 +                                .add(jPanel10Layout.createParallelGroup()
 +                                    .add(jPanel10Layout.createSequentialGroup()
 +                                        .add(35, 35, 35)
 +                                        .add(missingDataExplanation, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                    .add(showMissingDataCB)
 +                                    .add(combinePanelsCB)
 +                                    .add(joinSegmentsCB)
 +                                    .add(searchZoomCB)
 +                                    .add(showAttributesDisplayCheckBox)
 +                                    .add(jPanel10Layout.createSequentialGroup()
 +                                        .add(44, 44, 44)
 +                                        .add(jPanel10Layout.createParallelGroup(GroupLayout.TRAILING)
 +                                            .add(missingDataExplanation7, GroupLayout.PREFERRED_SIZE, 508, GroupLayout.PREFERRED_SIZE)
 +                                            .add(missingDataExplanation6, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))))
 +                                .addContainerGap(50, Short.MAX_VALUE))
 +                    );
 +                    jPanel10Layout.setVerticalGroup(
 +                        jPanel10Layout.createParallelGroup()
 +                            .add(jPanel10Layout.createSequentialGroup()
 +                                .addContainerGap()
 +                                .add(showMissingDataCB)
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(missingDataExplanation, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                .add(18, 18, 18)
 +                                .add(combinePanelsCB)
 +                                .add(26, 26, 26)
 +                                .add(joinSegmentsCB)
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(missingDataExplanation6, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                .add(18, 18, 18)
 +                                .add(showAttributesDisplayCheckBox)
 +                                .add(28, 28, 28)
 +                                .add(searchZoomCB)
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(missingDataExplanation7, GroupLayout.PREFERRED_SIZE, 78, GroupLayout.PREFERRED_SIZE)
 +                                .addContainerGap(53, Short.MAX_VALUE))
++=======
+                             jPanel10Layout.createParallelGroup()
+                                     .add(jPanel10Layout.createSequentialGroup()
+                                     .addContainerGap()
+                                     .add(jPanel10Layout.createParallelGroup()
+                                             .add(jPanel10Layout.createSequentialGroup()
+                                                     .add(35, 35, 35)
+                                                     .add(missingDataExplanation, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                             .add(showMissingDataCB)
+                                             .add(combinePanelsCB)
+                                             .add(joinSegmentsCB)
+                                             .add(searchZoomCB)
+                                             .add(showAttributesDisplayCheckBox)
+                                             .add(jPanel10Layout.createSequentialGroup()
+                                             .add(44, 44, 44)
+                                             .add(jPanel10Layout.createParallelGroup(GroupLayout.TRAILING)
+                                             .add(missingDataExplanation7, GroupLayout.PREFERRED_SIZE, 508, GroupLayout.PREFERRED_SIZE)
+                                             .add(missingDataExplanation6, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))))
+                                     .addContainerGap(50, Short.MAX_VALUE))
+                     );
+                     jPanel10Layout.setVerticalGroup(
+                             jPanel10Layout.createParallelGroup()
+                                     .add(jPanel10Layout.createSequentialGroup()
+                                     .addContainerGap()
+                                     .add(showMissingDataCB)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(missingDataExplanation, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                     .add(18, 18, 18)
+                                     .add(combinePanelsCB)
+                                     .add(26, 26, 26)
+                                     .add(joinSegmentsCB)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(missingDataExplanation6, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                     .add(18, 18, 18)
+                                     .add(showAttributesDisplayCheckBox)
+                                     .add(28, 28, 28)
+                                     .add(searchZoomCB)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(missingDataExplanation7, GroupLayout.PREFERRED_SIZE, 78, GroupLayout.PREFERRED_SIZE)
+                                     .addContainerGap(53, Short.MAX_VALUE))
++>>>>>>> upstream/1.5.56
                      );
                  }
                  generalPanel.add(jPanel10);
@@@ -323,7 -332,7 +408,11 @@@
  
                  { // compute preferred size
                      Dimension preferredSize = new Dimension();
++<<<<<<< HEAD
 +                    for(int i = 0; i < generalPanel.getComponentCount(); i++) {
++=======
+                     for (int i = 0; i < generalPanel.getComponentCount(); i++) {
++>>>>>>> upstream/1.5.56
                          Rectangle bounds = generalPanel.getComponent(i).getBounds();
                          preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
                          preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
@@@ -334,1176 -343,1176 +423,2349 @@@
                      generalPanel.setMinimumSize(preferredSize);
                      generalPanel.setPreferredSize(preferredSize);
                  }
++<<<<<<< HEAD
 +            }
 +            tabbedPane.addTab("General", generalPanel);
 +
 +
 +            //======== tracksPanel ========
 +            {
 +                tracksPanel.setLayout(null);
 +
 +                //======== jPanel6 ========
 +                {
 +
 +                    //---- jLabel5 ----
 +                    jLabel5.setText("Default Track Height, Charts (Pixels)");
 +
 +                    //---- defaultChartTrackHeightField ----
 +                    defaultChartTrackHeightField.setText("40");
 +                    defaultChartTrackHeightField.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            defaultChartTrackHeightFieldActionPerformed(e);
 +                        }
 +                    });
 +                    defaultChartTrackHeightField.addFocusListener(new FocusAdapter() {
 +                        @Override
 +                        public void focusLost(FocusEvent e) {
 +                            defaultChartTrackHeightFieldFocusLost(e);
 +                        }
 +                    });
 +
 +                    //---- trackNameAttributeLabel ----
 +                    trackNameAttributeLabel.setText("Track Name Attribute");
 +
 +                    //---- trackNameAttributeField ----
 +                    trackNameAttributeField.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            trackNameAttributeFieldActionPerformed(e);
 +                        }
 +                    });
 +                    trackNameAttributeField.addFocusListener(new FocusAdapter() {
 +                        @Override
 +                        public void focusLost(FocusEvent e) {
 +                            trackNameAttributeFieldFocusLost(e);
 +                        }
 +                    });
 +
 +                    //---- missingDataExplanation2 ----
 +                    missingDataExplanation2.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
 +                    missingDataExplanation2.setText("<html>Name of an attribute to be used to label  tracks.  If provided tracks will be labeled with the corresponding attribute values from the sample information file");
 +                    missingDataExplanation2.setVerticalAlignment(SwingConstants.TOP);
 +
 +                    //---- jLabel8 ----
 +                    jLabel8.setText("Default Track Height, Other (Pixels)");
 +
 +                    //---- defaultTrackHeightField ----
 +                    defaultTrackHeightField.setText("15");
 +                    defaultTrackHeightField.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            defaultTrackHeightFieldActionPerformed(e);
 +                        }
 +                    });
 +                    defaultTrackHeightField.addFocusListener(new FocusAdapter() {
 +                        @Override
 +                        public void focusLost(FocusEvent e) {
 +                            defaultTrackHeightFieldFocusLost(e);
 +                        }
 +                    });
 +
 +                    //---- missingDataExplanation4 ----
 +                    missingDataExplanation4.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
 +                    missingDataExplanation4.setText("<html>Default height of chart tracks (barcharts, scatterplots, etc)");
 +
 +                    //---- missingDataExplanation5 ----
 +                    missingDataExplanation5.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
 +                    missingDataExplanation5.setText("<html>Default height of all other tracks");
 +
 +                    //---- missingDataExplanation3 ----
 +                    missingDataExplanation3.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
 +                    missingDataExplanation3.setText("<html><i> If selected feature tracks are expanded by default.");
 +
 +                    //---- expandCB ----
 +                    expandCB.setText("Expand Feature Tracks");
 +                    expandCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            expandCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- normalizeCoverageCB ----
 +                    normalizeCoverageCB.setText("Normalize Coverage Data");
 +                    normalizeCoverageCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            normalizeCoverageCBActionPerformed(e);
 +                        }
 +                    });
 +                    normalizeCoverageCB.addFocusListener(new FocusAdapter() {
 +                        @Override
 +                        public void focusLost(FocusEvent e) {
 +                            normalizeCoverageCBFocusLost(e);
 +                        }
 +                    });
 +
 +                    //---- missingDataExplanation8 ----
 +                    missingDataExplanation8.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
 +                    missingDataExplanation8.setText("<html><i> Applies to coverage tracks computed with igvtools (.tdf files).  If selected coverage values are scaled by (1,000,000 / totalCount),  where totalCount is the total number of features or alignments.");
 +                    missingDataExplanation8.setVerticalAlignment(SwingConstants.TOP);
 +
 +                    //---- expandIconCB ----
 +                    expandIconCB.setText("Show Expand Icon");
 +                    expandIconCB.setToolTipText("If checked displays an expand/collapse icon on feature tracks.");
 +                    expandIconCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            expandIconCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    GroupLayout jPanel6Layout = new GroupLayout(jPanel6);
 +                    jPanel6.setLayout(jPanel6Layout);
 +                    jPanel6Layout.setHorizontalGroup(
 +                        jPanel6Layout.createParallelGroup()
 +                            .add(jPanel6Layout.createSequentialGroup()
 +                                .add(jPanel6Layout.createParallelGroup()
 +                                    .add(jPanel6Layout.createSequentialGroup()
 +                                        .addContainerGap()
 +                                        .add(jPanel6Layout.createParallelGroup()
 +                                            .add(jPanel6Layout.createSequentialGroup()
 +                                                .add(24, 24, 24)
 +                                                .add(missingDataExplanation4, GroupLayout.PREFERRED_SIZE, 354, GroupLayout.PREFERRED_SIZE))
 +                                            .add(jPanel6Layout.createSequentialGroup()
 +                                                .add(trackNameAttributeLabel)
 +                                                .addPreferredGap(LayoutStyle.RELATED)
 +                                                .add(trackNameAttributeField, GroupLayout.PREFERRED_SIZE, 216, GroupLayout.PREFERRED_SIZE))
 +                                            .add(jPanel6Layout.createSequentialGroup()
 +                                                .add(jLabel8)
 +                                                .add(39, 39, 39)
 +                                                .add(defaultTrackHeightField, GroupLayout.PREFERRED_SIZE, 57, GroupLayout.PREFERRED_SIZE))
 +                                            .add(jPanel6Layout.createSequentialGroup()
 +                                                .add(24, 24, 24)
 +                                                .add(missingDataExplanation5, GroupLayout.DEFAULT_SIZE, 1141, Short.MAX_VALUE))
 +                                            .add(jPanel6Layout.createSequentialGroup()
 +                                                .add(jLabel5)
 +                                                .add(36, 36, 36)
 +                                                .add(defaultChartTrackHeightField, GroupLayout.PREFERRED_SIZE, 57, GroupLayout.PREFERRED_SIZE))))
 +                                    .add(jPanel6Layout.createSequentialGroup()
 +                                        .addContainerGap()
 +                                        .add(expandIconCB)
 +                                        .add(724, 724, 724)
 +                                        .add(missingDataExplanation3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                    .add(jPanel6Layout.createSequentialGroup()
 +                                        .add(63, 63, 63)
 +                                        .add(missingDataExplanation2, GroupLayout.PREFERRED_SIZE, 578, GroupLayout.PREFERRED_SIZE))
 +                                    .add(jPanel6Layout.createSequentialGroup()
 +                                        .addContainerGap()
 +                                        .add(expandCB))
 +                                    .add(jPanel6Layout.createSequentialGroup()
 +                                        .addContainerGap()
 +                                        .add(normalizeCoverageCB))
 +                                    .add(jPanel6Layout.createSequentialGroup()
 +                                        .add(50, 50, 50)
 +                                        .add(missingDataExplanation8, GroupLayout.PREFERRED_SIZE, 608, GroupLayout.PREFERRED_SIZE)))
 +                                .addContainerGap())
 +                    );
 +                    jPanel6Layout.setVerticalGroup(
 +                        jPanel6Layout.createParallelGroup()
 +                            .add(jPanel6Layout.createSequentialGroup()
 +                                .addContainerGap()
 +                                .add(jPanel6Layout.createParallelGroup(GroupLayout.BASELINE)
 +                                    .add(jLabel5)
 +                                    .add(defaultChartTrackHeightField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(missingDataExplanation4, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE)
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(jPanel6Layout.createParallelGroup(GroupLayout.BASELINE)
 +                                    .add(jLabel8)
 +                                    .add(defaultTrackHeightField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(missingDataExplanation5, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE)
 +                                .add(26, 26, 26)
 +                                .add(jPanel6Layout.createParallelGroup(GroupLayout.BASELINE)
 +                                    .add(trackNameAttributeLabel)
 +                                    .add(trackNameAttributeField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(missingDataExplanation2, GroupLayout.PREFERRED_SIZE, 54, GroupLayout.PREFERRED_SIZE)
 +                                .add(28, 28, 28)
 +                                .add(expandCB)
 +                                .add(23, 23, 23)
 +                                .add(jPanel6Layout.createParallelGroup()
 +                                    .add(missingDataExplanation3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                    .add(expandIconCB))
 +                                .addPreferredGap(LayoutStyle.RELATED, 31, Short.MAX_VALUE)
 +                                .add(normalizeCoverageCB)
 +                                .add(18, 18, 18)
 +                                .add(missingDataExplanation8, GroupLayout.PREFERRED_SIZE, 52, GroupLayout.PREFERRED_SIZE)
 +                                .add(15, 15, 15))
 +                    );
 +                }
 +                tracksPanel.add(jPanel6);
 +                jPanel6.setBounds(40, 20, 690, 480);
 +
 +                { // compute preferred size
 +                    Dimension preferredSize = new Dimension();
 +                    for(int i = 0; i < tracksPanel.getComponentCount(); i++) {
 +                        Rectangle bounds = tracksPanel.getComponent(i).getBounds();
 +                        preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
 +                        preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
 +                    }
 +                    Insets insets = tracksPanel.getInsets();
 +                    preferredSize.width += insets.right;
 +                    preferredSize.height += insets.bottom;
 +                    tracksPanel.setMinimumSize(preferredSize);
 +                    tracksPanel.setPreferredSize(preferredSize);
 +                }
 +            }
 +            tabbedPane.addTab("Tracks", tracksPanel);
 +
 +
 +            //======== overlaysPanel ========
 +            {
 +
 +                //======== jPanel5 ========
 +                {
 +
 +                    //---- jLabel3 ----
 +                    jLabel3.setText("Overlay tracks based on attribute:");
 +
 +                    //---- overlayAttributeTextField ----
 +                    overlayAttributeTextField.setText("LINKING_ID");
 +                    overlayAttributeTextField.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            overlayAttributeTextFieldActionPerformed(e);
 +                        }
 +                    });
 +                    overlayAttributeTextField.addFocusListener(new FocusAdapter() {
 +                        @Override
 +                        public void focusLost(FocusEvent e) {
 +                            overlayAttributeTextFieldFocusLost(e);
 +                        }
 +                    });
 +                    overlayAttributeTextField.addKeyListener(new KeyAdapter() {
 +                        @Override
 +                        public void keyTyped(KeyEvent e) {
 +                            overlayAttributeTextFieldKeyTyped(e);
 +                        }
 +                    });
 +
 +                    //---- overlayTrackCB ----
 +                    overlayTrackCB.setSelected(true);
 +                    overlayTrackCB.setText("Overlay mutation tracks");
 +                    overlayTrackCB.setActionCommand("overlayTracksCB");
 +                    overlayTrackCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            overlayTrackCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- jLabel2 ----
 +                    jLabel2.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
 +
 +                    //---- displayTracksCB ----
 +                    displayTracksCB.setText("Display mutation data as distinct tracks");
 +                    displayTracksCB.setActionCommand("displayTracksCB");
 +                    displayTracksCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            displayTracksCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- jLabel4 ----
 +                    jLabel4.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
 +
 +                    //---- colorOverlyCB ----
 +                    colorOverlyCB.setText("Color code overlay");
 +                    colorOverlyCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            colorOverlyCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- chooseOverlayColorsButton ----
 +                    chooseOverlayColorsButton.setForeground(new Color(0, 0, 247));
 +                    chooseOverlayColorsButton.setText("Choose colors");
 +                    chooseOverlayColorsButton.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
 +                    chooseOverlayColorsButton.setVerticalAlignment(SwingConstants.BOTTOM);
 +                    chooseOverlayColorsButton.setVerticalTextPosition(SwingConstants.BOTTOM);
 +                    chooseOverlayColorsButton.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            chooseOverlayColorsButtonActionPerformed(e);
 +                        }
 +                    });
 +
 +                    GroupLayout jPanel5Layout = new GroupLayout(jPanel5);
 +                    jPanel5.setLayout(jPanel5Layout);
 +                    jPanel5Layout.setHorizontalGroup(
 +                        jPanel5Layout.createParallelGroup()
 +                            .add(jPanel5Layout.createSequentialGroup()
 +                                .addContainerGap()
 +                                .add(jPanel5Layout.createParallelGroup()
 +                                    .add(displayTracksCB)
 +                                    .add(jLabel4)
 +                                    .add(overlayTrackCB)
 +                                    .add(jLabel2)
 +                                    .add(jPanel5Layout.createSequentialGroup()
 +                                        .add(59, 59, 59)
 +                                        .add(jPanel5Layout.createParallelGroup()
 +                                            .add(jPanel5Layout.createSequentialGroup()
 +                                                .add(colorOverlyCB)
 +                                                .addPreferredGap(LayoutStyle.RELATED)
 +                                                .add(chooseOverlayColorsButton, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                            .add(jPanel5Layout.createSequentialGroup()
 +                                                .add(jLabel3)
 +                                                .addPreferredGap(LayoutStyle.RELATED)
 +                                                .add(overlayAttributeTextField, GroupLayout.PREFERRED_SIZE, 228, GroupLayout.PREFERRED_SIZE)))))
 +                                .addContainerGap())
 +                    );
 +                    jPanel5Layout.setVerticalGroup(
 +                        jPanel5Layout.createParallelGroup()
 +                            .add(jPanel5Layout.createSequentialGroup()
 +                                .addContainerGap()
 +                                .add(jLabel2)
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(jLabel4)
 +                                .add(39, 39, 39)
 +                                .add(overlayTrackCB)
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(jPanel5Layout.createParallelGroup(GroupLayout.BASELINE)
 +                                    .add(jLabel3)
 +                                    .add(overlayAttributeTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                .add(6, 6, 6)
 +                                .add(jPanel5Layout.createParallelGroup(GroupLayout.TRAILING)
 +                                    .add(colorOverlyCB)
 +                                    .add(chooseOverlayColorsButton, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                .add(36, 36, 36)
 +                                .add(displayTracksCB)
 +                                .addContainerGap(30, Short.MAX_VALUE))
 +                    );
 +                }
 +
 +                GroupLayout overlaysPanelLayout = new GroupLayout(overlaysPanel);
 +                overlaysPanel.setLayout(overlaysPanelLayout);
 +                overlaysPanelLayout.setHorizontalGroup(
 +                    overlaysPanelLayout.createParallelGroup()
 +                        .add(overlaysPanelLayout.createSequentialGroup()
 +                            .add(28, 28, 28)
 +                            .add(jPanel5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                            .addContainerGap(235, Short.MAX_VALUE))
 +                );
 +                overlaysPanelLayout.setVerticalGroup(
 +                    overlaysPanelLayout.createParallelGroup()
 +                        .add(overlaysPanelLayout.createSequentialGroup()
 +                            .add(55, 55, 55)
 +                            .add(jPanel5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                            .addContainerGap(225, Short.MAX_VALUE))
 +                );
 +            }
 +            tabbedPane.addTab("Mutations", overlaysPanel);
 +
 +
 +            //======== chartPanel ========
 +            {
 +                chartPanel.setLayout(null);
 +
 +                //======== jPanel4 ========
 +                {
 +
 +                    //---- topBorderCB ----
 +                    topBorderCB.setText("Draw Top Border");
 +                    topBorderCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            topBorderCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- label1 ----
 +                    label1.setFont(label1.getFont());
 +                    label1.setText("Default settings for barcharts and scatterplots:");
 +
 +                    //---- chartDrawTrackNameCB ----
 +                    chartDrawTrackNameCB.setText("Draw Track Label");
 +                    chartDrawTrackNameCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            chartDrawTrackNameCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- bottomBorderCB ----
 +                    bottomBorderCB.setText("Draw Bottom Border");
 +                    bottomBorderCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            bottomBorderCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- jLabel7 ----
 +                    jLabel7.setText("<html><i>If selected charts are dynamically rescaled to the range of the data in view.");
 +
 +                    //---- colorBordersCB ----
 +                    colorBordersCB.setText("Color Borders");
 +                    colorBordersCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            colorBordersCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- labelYAxisCB ----
 +                    labelYAxisCB.setText("Label Y Axis");
 +                    labelYAxisCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            labelYAxisCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- autoscaleCB ----
 +                    autoscaleCB.setText("Continuous Autoscale");
 +                    autoscaleCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            autoscaleCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- jLabel9 ----
 +                    jLabel9.setText("<html><i>Draw a label centered over the track provided<br>the track height is at least 25 pixels. ");
 +
 +                    //---- showDatarangeCB ----
 +                    showDatarangeCB.setText("Show Data Range");
 +                    showDatarangeCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            showDatarangeCBActionPerformed(e);
 +                        }
 +                    });
 +                    showDatarangeCB.addFocusListener(new FocusAdapter() {
 +                        @Override
 +                        public void focusLost(FocusEvent e) {
 +                            showDatarangeCBFocusLost(e);
 +                        }
 +                    });
 +
 +                    GroupLayout jPanel4Layout = new GroupLayout(jPanel4);
 +                    jPanel4.setLayout(jPanel4Layout);
 +                    jPanel4Layout.setHorizontalGroup(
 +                        jPanel4Layout.createParallelGroup()
 +                            .add(jPanel4Layout.createParallelGroup()
 +                                .add(GroupLayout.TRAILING, jPanel4Layout.createSequentialGroup()
 +                                    .addContainerGap(221, Short.MAX_VALUE)
 +                                    .add(jLabel9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                    .add(84, 84, 84)))
 +                            .add(jPanel4Layout.createSequentialGroup()
 +                                .addContainerGap()
 +                                .add(jPanel4Layout.createParallelGroup()
 +                                    .add(label1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                    .add(jPanel4Layout.createSequentialGroup()
 +                                        .add(20, 20, 20)
 +                                        .add(jPanel4Layout.createParallelGroup()
 +                                            .add(jPanel4Layout.createSequentialGroup()
 +                                                .add(jPanel4Layout.createParallelGroup()
 +                                                    .add(autoscaleCB)
 +                                                    .add(showDatarangeCB))
 +                                                .add(18, 18, 18)
 +                                                .add(jLabel7, GroupLayout.DEFAULT_SIZE, 371, Short.MAX_VALUE))
 +                                            .add(jPanel4Layout.createSequentialGroup()
 +                                                .add(jPanel4Layout.createParallelGroup()
 +                                                    .add(topBorderCB)
 +                                                    .add(colorBordersCB)
 +                                                    .add(bottomBorderCB)
 +                                                    .add(labelYAxisCB)
 +                                                    .add(chartDrawTrackNameCB))
 +                                                .addPreferredGap(LayoutStyle.RELATED, 403, Short.MAX_VALUE)))))
 +                                .addContainerGap())
 +                    );
 +                    jPanel4Layout.setVerticalGroup(
 +                        jPanel4Layout.createParallelGroup()
 +                            .add(jPanel4Layout.createParallelGroup()
 +                                .add(jPanel4Layout.createSequentialGroup()
 +                                    .add(131, 131, 131)
 +                                    .add(jLabel9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                    .addContainerGap(181, Short.MAX_VALUE)))
 +                            .add(jPanel4Layout.createSequentialGroup()
 +                                .addContainerGap()
 +                                .add(label1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(topBorderCB)
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(bottomBorderCB)
 +                                .add(7, 7, 7)
 +                                .add(colorBordersCB)
 +                                .add(18, 18, 18)
 +                                .add(chartDrawTrackNameCB)
 +                                .add(23, 23, 23)
 +                                .add(labelYAxisCB)
 +                                .add(18, 18, 18)
 +                                .add(jPanel4Layout.createParallelGroup(GroupLayout.BASELINE)
 +                                    .add(autoscaleCB)
 +                                    .add(jLabel7, GroupLayout.PREFERRED_SIZE, 50, GroupLayout.PREFERRED_SIZE))
 +                                .addPreferredGap(LayoutStyle.UNRELATED)
 +                                .add(showDatarangeCB)
 +                                .add(36, 36, 36))
 +                    );
 +                }
 +                chartPanel.add(jPanel4);
 +                jPanel4.setBounds(20, 30, 590, 340);
 +
 +                { // compute preferred size
 +                    Dimension preferredSize = new Dimension();
 +                    for(int i = 0; i < chartPanel.getComponentCount(); i++) {
 +                        Rectangle bounds = chartPanel.getComponent(i).getBounds();
 +                        preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
 +                        preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
 +                    }
 +                    Insets insets = chartPanel.getInsets();
 +                    preferredSize.width += insets.right;
 +                    preferredSize.height += insets.bottom;
 +                    chartPanel.setMinimumSize(preferredSize);
 +                    chartPanel.setPreferredSize(preferredSize);
 +                }
 +            }
 +            tabbedPane.addTab("Charts", chartPanel);
 +
 +
 +            //======== alignmentPanel ========
 +            {
 +                alignmentPanel.setLayout(null);
 +
 +                //======== jPanel1 ========
 +                {
 +                    jPanel1.setLayout(null);
 +
 +                    //======== jPanel11 ========
 +                    {
 +                        jPanel11.setLayout(null);
 +
 +                        //---- samMaxLevelField ----
 +                        samMaxLevelField.setText("jTextField1");
 +                        samMaxLevelField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                samMaxLevelFieldActionPerformed(e);
 +                            }
 +                        });
 +                        samMaxLevelField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                samMaxLevelFieldFocusLost(e);
 +                            }
 +                        });
 +                        jPanel11.add(samMaxLevelField);
 +                        samMaxLevelField.setBounds(new Rectangle(new Point(206, 41), samMaxLevelField.getPreferredSize()));
 +
 +                        //---- snpThresholdField ----
 +                        snpThresholdField.setText("0");
 +                        snpThresholdField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                snpThresholdFieldActionPerformed(e);
 +                            }
 +                        });
 +                        snpThresholdField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                snpThresholdFieldFocusLost(e);
 +                            }
 +                        });
 +                        jPanel11.add(snpThresholdField);
 +                        snpThresholdField.setBounds(206, 144, 84, snpThresholdField.getPreferredSize().height);
 +
 +                        //---- jLabel11 ----
 +                        jLabel11.setText("Visibility range threshold (kb)");
 +                        jPanel11.add(jLabel11);
 +                        jLabel11.setBounds(new Rectangle(new Point(6, 12), jLabel11.getPreferredSize()));
 +
 +                        //---- jLabel26 ----
 +                        jLabel26.setText("Coverage allele-freq threshold");
 +                        jPanel11.add(jLabel26);
 +                        jLabel26.setBounds(6, 150, 200, jLabel26.getPreferredSize().height);
 +
 +                        //---- jLabel17 ----
 +                        jLabel17.setText("Insert size flagging threshold:");
 +                        jPanel11.add(jLabel17);
 +                        jLabel17.setBounds(6, 116, 200, jLabel17.getPreferredSize().height);
 +
 +                        //---- jLabel16 ----
 +                        jLabel16.setText("<html><i>Reads with qualities  below the threshold are not shown.");
 +                        jPanel11.add(jLabel16);
 +                        jLabel16.setBounds(new Rectangle(new Point(296, 82), jLabel16.getPreferredSize()));
 +
 +                        //---- mappingQualityThresholdField ----
 +                        mappingQualityThresholdField.setText("0");
 +                        mappingQualityThresholdField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                mappingQualityThresholdFieldActionPerformed(e);
 +                            }
 +                        });
 +                        mappingQualityThresholdField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                mappingQualityThresholdFieldFocusLost(e);
 +                            }
 +                        });
 +                        jPanel11.add(mappingQualityThresholdField);
 +                        mappingQualityThresholdField.setBounds(206, 76, 84, mappingQualityThresholdField.getPreferredSize().height);
 +
 +                        //---- jLabel14 ----
 +                        jLabel14.setText("<html><i>Maximum number of rows of alignments to display.");
 +                        jPanel11.add(jLabel14);
 +                        jLabel14.setBounds(296, 40, 390, 30);
 +
 +                        //---- insertSizeThresholdField ----
 +                        insertSizeThresholdField.setText("0");
 +                        insertSizeThresholdField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                insertSizeThresholdFieldActionPerformed(e);
 +                            }
 +                        });
 +                        insertSizeThresholdField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                insertSizeThresholdFieldFocusLost(e);
 +                            }
 +                        });
 +                        jPanel11.add(insertSizeThresholdField);
 +                        insertSizeThresholdField.setBounds(206, 110, 84, insertSizeThresholdField.getPreferredSize().height);
 +
 +                        //---- jLabel13 ----
 +                        jLabel13.setText("Maximum read depth");
 +                        jPanel11.add(jLabel13);
 +                        jLabel13.setBounds(new Rectangle(new Point(6, 47), jLabel13.getPreferredSize()));
 +
 +                        //---- jLabel15 ----
 +                        jLabel15.setText("Mapping quality threshold:");
 +                        jPanel11.add(jLabel15);
 +                        jLabel15.setBounds(new Rectangle(new Point(6, 82), jLabel15.getPreferredSize()));
 +
 +                        //---- jLabel18 ----
 +                        jLabel18.setText("<html><i>Paired end alignments with insert sizes > this value are flagged.");
 +                        jPanel11.add(jLabel18);
 +                        jLabel18.setBounds(296, 110, 414, 40);
 +
 +                        //---- samMaxWindowSizeField ----
 +                        samMaxWindowSizeField.setText("jTextField1");
 +                        samMaxWindowSizeField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                samMaxWindowSizeFieldActionPerformed(e);
 +                            }
 +                        });
 +                        samMaxWindowSizeField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                samMaxWindowSizeFieldFocusLost(e);
 +                            }
 +                        });
 +                        jPanel11.add(samMaxWindowSizeField);
 +                        samMaxWindowSizeField.setBounds(new Rectangle(new Point(206, 6), samMaxWindowSizeField.getPreferredSize()));
 +
 +                        //---- jLabel12 ----
 +                        jLabel12.setText("<html><i>Nominal window size at which alignments become visible");
 +                        jPanel11.add(jLabel12);
 +                        jLabel12.setBounds(new Rectangle(new Point(296, 12), jLabel12.getPreferredSize()));
 +
 +                        { // compute preferred size
 +                            Dimension preferredSize = new Dimension();
 +                            for(int i = 0; i < jPanel11.getComponentCount(); i++) {
 +                                Rectangle bounds = jPanel11.getComponent(i).getBounds();
 +                                preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
 +                                preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
 +                            }
 +                            Insets insets = jPanel11.getInsets();
 +                            preferredSize.width += insets.right;
 +                            preferredSize.height += insets.bottom;
 +                            jPanel11.setMinimumSize(preferredSize);
 +                            jPanel11.setPreferredSize(preferredSize);
 +                        }
 +                    }
 +                    jPanel1.add(jPanel11);
 +                    jPanel11.setBounds(new Rectangle(new Point(6, 20), jPanel11.getPreferredSize()));
 +
 +                    //======== jPanel12 ========
 +                    {
 +                        jPanel12.setLayout(null);
 +
 +                        //---- samMinBaseQualityField ----
 +                        samMinBaseQualityField.setText("0");
 +                        samMinBaseQualityField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                samMinBaseQualityFieldActionPerformed(e);
 +                            }
 +                        });
 +                        samMinBaseQualityField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                samMinBaseQualityFieldFocusLost(e);
 +                            }
 +                        });
 +                        jPanel12.add(samMinBaseQualityField);
 +                        samMinBaseQualityField.setBounds(325, 140, 50, samMinBaseQualityField.getPreferredSize().height);
 +
 +                        //---- samShadeMismatchedBaseCB ----
 +                        samShadeMismatchedBaseCB.setText("Shade mismatched bases by quality. ");
 +                        samShadeMismatchedBaseCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                samShadeMismatchedBaseCBActionPerformed(e);
 +                            }
 +                        });
 +                        jPanel12.add(samShadeMismatchedBaseCB);
 +                        samShadeMismatchedBaseCB.setBounds(6, 146, 290, samShadeMismatchedBaseCB.getPreferredSize().height);
 +
 +                        //---- samMaxBaseQualityField ----
 +                        samMaxBaseQualityField.setText("0");
 +                        samMaxBaseQualityField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                samMaxBaseQualityFieldActionPerformed(e);
 +                            }
 +                        });
 +                        samMaxBaseQualityField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                samMaxBaseQualityFieldFocusLost(e);
 +                            }
 +                        });
 +                        jPanel12.add(samMaxBaseQualityField);
 +                        samMaxBaseQualityField.setBounds(455, 140, 50, samMaxBaseQualityField.getPreferredSize().height);
 +
 +                        //---- showCovTrackCB ----
 +                        showCovTrackCB.setText("Show coverage track");
 +                        showCovTrackCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                showCovTrackCBActionPerformed(e);
 +                            }
 +                        });
 +                        jPanel12.add(showCovTrackCB);
 +                        showCovTrackCB.setBounds(385, 76, 270, showCovTrackCB.getPreferredSize().height);
 +
 +                        //---- samFilterDuplicatesCB ----
 +                        samFilterDuplicatesCB.setText("Filter duplicate reads");
 +                        samFilterDuplicatesCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                samShowDuplicatesCBActionPerformed(e);
 +                            }
 +                        });
 +                        jPanel12.add(samFilterDuplicatesCB);
 +                        samFilterDuplicatesCB.setBounds(6, 6, 290, samFilterDuplicatesCB.getPreferredSize().height);
 +
 +                        //---- showRefSeqCB ----
 +                        showRefSeqCB.setText("Show reference sequence");
 +                        showRefSeqCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                showRefSeqCBActionPerformed(e);
 +                            }
 +                        });
 +                        jPanel12.add(showRefSeqCB);
 +                        showRefSeqCB.setBounds(385, 6, 270, showRefSeqCB.getPreferredSize().height);
 +
 +                        //---- jLabel19 ----
 +                        jLabel19.setText("Min: ");
 +                        jPanel12.add(jLabel19);
 +                        jLabel19.setBounds(new Rectangle(new Point(285, 145), jLabel19.getPreferredSize()));
 +
 +                        //---- filterCB ----
 +                        filterCB.setText("Filter alignments");
 +                        filterCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                filterCBActionPerformed(e);
 +                            }
 +                        });
 +                        jPanel12.add(filterCB);
 +                        filterCB.setBounds(6, 181, 144, filterCB.getPreferredSize().height);
 +
 +                        //---- filterURL ----
 +                        filterURL.setText("URL or path to filter file");
 +                        filterURL.setEnabled(false);
 +                        filterURL.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                filterURLActionPerformed(e);
 +                            }
 +                        });
 +                        filterURL.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                filterURLFocusLost(e);
 +                            }
 +                        });
 +                        jPanel12.add(filterURL);
 +                        filterURL.setBounds(190, 185, 482, filterURL.getPreferredSize().height);
 +
 +                        //---- samFlagUnmappedPairCB ----
 +                        samFlagUnmappedPairCB.setText("Flag unmapped pairs");
 +                        samFlagUnmappedPairCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                samFlagUnmappedPairCBActionPerformed(e);
 +                            }
 +                        });
 +                        jPanel12.add(samFlagUnmappedPairCB);
 +                        samFlagUnmappedPairCB.setBounds(6, 76, 310, samFlagUnmappedPairCB.getPreferredSize().height);
 +
 +                        //---- shadeCenterCB ----
 +                        shadeCenterCB.setText("Shade alignments intersecting center");
 +                        shadeCenterCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                shadeCenterCBActionPerformed(e);
 +                            }
 +                        });
 +                        jPanel12.add(shadeCenterCB);
 +                        shadeCenterCB.setBounds(385, 41, 450, shadeCenterCB.getPreferredSize().height);
 +
 +                        //---- jLabel10 ----
 +                        jLabel10.setText("<html>Chromosome color legend &nbsp;&nbsp;&nbsp;<i>Used to flag paired end reads with mates on other chromosomes");
 +                        jPanel12.add(jLabel10);
 +                        jLabel10.setBounds(5, 230, 640, 30);
 +
 +                        //======== legendPanel ========
 +                        {
 +
 +                            GroupLayout legendPanelLayout = new GroupLayout(legendPanel);
 +                            legendPanel.setLayout(legendPanelLayout);
 +                            legendPanelLayout.setHorizontalGroup(
 +                                legendPanelLayout.createParallelGroup()
 +                                    .add(0, 602, Short.MAX_VALUE)
 +                            );
 +                            legendPanelLayout.setVerticalGroup(
 +                                legendPanelLayout.createParallelGroup()
 +                                    .add(0, 25, Short.MAX_VALUE)
 +                            );
 +                        }
 +                        jPanel12.add(legendPanel);
 +                        legendPanel.setBounds(new Rectangle(new Point(5, 270), legendPanel.getPreferredSize()));
 +
 +                        //---- filterFailedReadsCB ----
 +                        filterFailedReadsCB.setText("Filter vendor failed reads");
 +                        filterFailedReadsCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                filterVendorFailedReadsCBActionPerformed(e);
 +                            }
 +                        });
 +                        jPanel12.add(filterFailedReadsCB);
 +                        filterFailedReadsCB.setBounds(new Rectangle(new Point(6, 41), filterFailedReadsCB.getPreferredSize()));
 +
 +                        //---- label2 ----
 +                        label2.setText("Max:");
 +                        jPanel12.add(label2);
 +                        label2.setBounds(new Rectangle(new Point(400, 145), label2.getPreferredSize()));
 +
 +                        //---- showSoftClippedCB ----
 +                        showSoftClippedCB.setText("Show soft-clipped bases");
 +                        showSoftClippedCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                showSoftClippedCBActionPerformed(e);
 +                            }
 +                        });
 +                        jPanel12.add(showSoftClippedCB);
 +                        showSoftClippedCB.setBounds(new Rectangle(new Point(6, 111), showSoftClippedCB.getPreferredSize()));
 +
 +                        { // compute preferred size
 +                            Dimension preferredSize = new Dimension();
 +                            for(int i = 0; i < jPanel12.getComponentCount(); i++) {
 +                                Rectangle bounds = jPanel12.getComponent(i).getBounds();
 +                                preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
 +                                preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
 +                            }
 +                            Insets insets = jPanel12.getInsets();
 +                            preferredSize.width += insets.right;
 +                            preferredSize.height += insets.bottom;
 +                            jPanel12.setMinimumSize(preferredSize);
 +                            jPanel12.setPreferredSize(preferredSize);
 +                        }
 +                    }
 +                    jPanel1.add(jPanel12);
 +                    jPanel12.setBounds(6, 198, 740, 297);
 +
 +                    { // compute preferred size
 +                        Dimension preferredSize = new Dimension();
 +                        for(int i = 0; i < jPanel1.getComponentCount(); i++) {
 +                            Rectangle bounds = jPanel1.getComponent(i).getBounds();
 +                            preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
 +                            preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
 +                        }
 +                        Insets insets = jPanel1.getInsets();
 +                        preferredSize.width += insets.right;
 +                        preferredSize.height += insets.bottom;
 +                        jPanel1.setMinimumSize(preferredSize);
 +                        jPanel1.setPreferredSize(preferredSize);
 +                    }
 +                }
 +                alignmentPanel.add(jPanel1);
 +                jPanel1.setBounds(0, 0, 760, 510);
 +
 +                { // compute preferred size
 +                    Dimension preferredSize = new Dimension();
 +                    for(int i = 0; i < alignmentPanel.getComponentCount(); i++) {
 +                        Rectangle bounds = alignmentPanel.getComponent(i).getBounds();
 +                        preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
 +                        preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
 +                    }
 +                    Insets insets = alignmentPanel.getInsets();
 +                    preferredSize.width += insets.right;
 +                    preferredSize.height += insets.bottom;
 +                    alignmentPanel.setMinimumSize(preferredSize);
 +                    alignmentPanel.setPreferredSize(preferredSize);
 +                }
 +            }
 +            tabbedPane.addTab("Alignments", alignmentPanel);
 +
 +
 +            //======== expressionPane ========
 +            {
 +                expressionPane.setLayout(null);
 +
 +                //======== jPanel8 ========
 +                {
 +
 +                    //---- expMapToGeneCB ----
 +                    expMapToGeneCB.setText("Map probes to genes");
 +                    expMapToGeneCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            expMapToGeneCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- jLabel24 ----
 +                    jLabel24.setText("Expression probe mapping options: ");
 +
 +                    //---- expMapToLociCB ----
 +                    expMapToLociCB.setText("<html>Map probes to target loci");
 +                    expMapToLociCB.addActionListener(new ActionListener() {
 +                        public void actionPerformed(ActionEvent e) {
 +                            expMapToLociCBActionPerformed(e);
 +                        }
 +                    });
 +
 +                    //---- jLabel21 ----
 +                    jLabel21.setText("<html><i>Note: Changes will not affect currently loaded datasets.");
 +
 +                    GroupLayout jPanel8Layout = new GroupLayout(jPanel8);
 +                    jPanel8.setLayout(jPanel8Layout);
 +                    jPanel8Layout.setHorizontalGroup(
 +                        jPanel8Layout.createParallelGroup()
 +                            .add(jPanel8Layout.createSequentialGroup()
 +                                .add(jPanel8Layout.createParallelGroup()
 +                                    .add(jPanel8Layout.createSequentialGroup()
 +                                        .add(45, 45, 45)
 +                                        .add(jPanel8Layout.createParallelGroup()
 +                                            .add(expMapToLociCB, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                            .add(expMapToGeneCB)))
 +                                    .add(jPanel8Layout.createSequentialGroup()
 +                                        .addContainerGap()
 +                                        .add(jPanel8Layout.createParallelGroup()
 +                                            .add(jPanel8Layout.createSequentialGroup()
 +                                                .add(24, 24, 24)
 +                                                .add(jLabel21, GroupLayout.PREFERRED_SIZE, 497, GroupLayout.PREFERRED_SIZE))
 +                                            .add(jLabel24))))
 +                                .addContainerGap(193, Short.MAX_VALUE))
 +                    );
 +                    jPanel8Layout.setVerticalGroup(
 +                        jPanel8Layout.createParallelGroup()
 +                            .add(jPanel8Layout.createSequentialGroup()
 +                                .addContainerGap()
 +                                .add(jLabel24)
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(jLabel21, GroupLayout.PREFERRED_SIZE, 44, GroupLayout.PREFERRED_SIZE)
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(expMapToLociCB, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                .add(14, 14, 14)
 +                                .add(expMapToGeneCB)
 +                                .addContainerGap(172, Short.MAX_VALUE))
 +                    );
 +                }
 +                expressionPane.add(jPanel8);
 +                jPanel8.setBounds(10, 30, 720, 310);
 +
 +                { // compute preferred size
 +                    Dimension preferredSize = new Dimension();
 +                    for(int i = 0; i < expressionPane.getComponentCount(); i++) {
 +                        Rectangle bounds = expressionPane.getComponent(i).getBounds();
 +                        preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
 +                        preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
 +                    }
 +                    Insets insets = expressionPane.getInsets();
 +                    preferredSize.width += insets.right;
 +                    preferredSize.height += insets.bottom;
 +                    expressionPane.setMinimumSize(preferredSize);
 +                    expressionPane.setPreferredSize(preferredSize);
 +                }
 +            }
 +            tabbedPane.addTab("Probes", expressionPane);
 +
 +
 +            //======== advancedPanel ========
 +            {
 +                advancedPanel.setBorder(new EmptyBorder(1, 10, 1, 10));
 +                advancedPanel.setLayout(null);
 +
 +                //======== jPanel3 ========
 +                {
 +
 +                    //======== jPanel2 ========
 +                    {
 +
 +                        //---- jLabel1 ----
 +                        jLabel1.setText("Genome Server URL");
 +
 +                        //---- genomeServerURLTextField ----
 +                        genomeServerURLTextField.setText("jTextField1");
 +                        genomeServerURLTextField.setEnabled(false);
 +                        genomeServerURLTextField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                genomeServerURLTextFieldActionPerformed(e);
 +                            }
 +                        });
 +                        genomeServerURLTextField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                genomeServerURLTextFieldFocusLost(e);
 +                            }
 +                        });
 +
 +                        //---- jLabel6 ----
 +                        jLabel6.setText("Data Registry URL");
 +
 +                        //---- dataServerURLTextField ----
 +                        dataServerURLTextField.setEnabled(false);
 +                        dataServerURLTextField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                dataServerURLTextFieldActionPerformed(e);
 +                            }
 +                        });
 +                        dataServerURLTextField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                dataServerURLTextFieldFocusLost(e);
 +                            }
 +                        });
 +
 +                        //---- editServerPropertiesCB ----
 +                        editServerPropertiesCB.setText("Edit server properties");
 +                        editServerPropertiesCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                editServerPropertiesCBActionPerformed(e);
 +                            }
 +                        });
 +
 +                        //---- clearGenomeCacheButton ----
 +                        clearGenomeCacheButton.setText("Clear Genome Cache");
 +                        clearGenomeCacheButton.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                clearGenomeCacheButtonActionPerformed(e);
 +                            }
 +                        });
 +
 +                        //---- jButton1 ----
 +                        jButton1.setText("Reset to Defaults");
 +                        jButton1.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                jButton1ActionPerformed(e);
 +                            }
 +                        });
 +
 +                        GroupLayout jPanel2Layout = new GroupLayout(jPanel2);
 +                        jPanel2.setLayout(jPanel2Layout);
 +                        jPanel2Layout.setHorizontalGroup(
 +                            jPanel2Layout.createParallelGroup()
 +                                .add(jPanel2Layout.createSequentialGroup()
 +                                    .addContainerGap()
 +                                    .add(jPanel2Layout.createParallelGroup()
 +                                        .add(jPanel2Layout.createSequentialGroup()
 +                                            .add(29, 29, 29)
 +                                            .add(jPanel2Layout.createParallelGroup()
 +                                                .add(jLabel1)
 +                                                .add(jPanel2Layout.createSequentialGroup()
 +                                                    .add(jLabel6)
 +                                                    .add(44, 44, 44)
 +                                                    .add(jPanel2Layout.createParallelGroup(GroupLayout.LEADING, false)
 +                                                        .add(dataServerURLTextField)
 +                                                        .add(genomeServerURLTextField, GroupLayout.PREFERRED_SIZE, 494, GroupLayout.PREFERRED_SIZE)))))
 +                                        .add(jPanel2Layout.createSequentialGroup()
 +                                            .add(editServerPropertiesCB)
 +                                            .add(18, 18, 18)
 +                                            .add(jButton1))
 +                                        .add(clearGenomeCacheButton))
 +                                    .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 +                        );
 +                        jPanel2Layout.setVerticalGroup(
 +                            jPanel2Layout.createParallelGroup()
 +                                .add(jPanel2Layout.createSequentialGroup()
 +                                    .addContainerGap()
 +                                    .add(jPanel2Layout.createParallelGroup(GroupLayout.BASELINE)
 +                                        .add(editServerPropertiesCB)
 +                                        .add(jButton1))
 +                                    .addPreferredGap(LayoutStyle.RELATED)
 +                                    .add(jPanel2Layout.createParallelGroup(GroupLayout.CENTER)
 +                                        .add(jLabel1)
 +                                        .add(genomeServerURLTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                    .addPreferredGap(LayoutStyle.RELATED)
 +                                    .add(jPanel2Layout.createParallelGroup(GroupLayout.BASELINE)
 +                                        .add(jLabel6)
 +                                        .add(dataServerURLTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                    .add(18, 18, 18)
 +                                    .add(clearGenomeCacheButton)
 +                                    .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 +                        );
 +                    }
 +
 +                    //======== jPanel7 ========
 +                    {
 +
 +                        //---- enablePortCB ----
 +                        enablePortCB.setText("Enable port");
 +                        enablePortCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                enablePortCBActionPerformed(e);
 +                            }
 +                        });
 +
 +                        //---- portField ----
 +                        portField.setText("60151");
 +                        portField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                portFieldActionPerformed(e);
 +                            }
 +                        });
 +                        portField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                portFieldFocusLost(e);
 +                            }
 +                        });
 +
 +                        //---- jLabel22 ----
 +                        jLabel22.setFont(new Font("Lucida Grande", Font.ITALIC, 13));
 +                        jLabel22.setText("Enable port to send commands and http requests to IGV. ");
 +
 +                        GroupLayout jPanel7Layout = new GroupLayout(jPanel7);
 +                        jPanel7.setLayout(jPanel7Layout);
 +                        jPanel7Layout.setHorizontalGroup(
 +                            jPanel7Layout.createParallelGroup()
 +                                .add(jPanel7Layout.createSequentialGroup()
 +                                    .add(jPanel7Layout.createParallelGroup()
 +                                        .add(jPanel7Layout.createSequentialGroup()
 +                                            .addContainerGap()
 +                                            .add(enablePortCB)
 +                                            .add(39, 39, 39)
 +                                            .add(portField, GroupLayout.PREFERRED_SIZE, 126, GroupLayout.PREFERRED_SIZE))
 +                                        .add(jPanel7Layout.createSequentialGroup()
 +                                            .add(48, 48, 48)
 +                                            .add(jLabel22)))
 +                                    .addContainerGap(330, Short.MAX_VALUE))
 +                        );
 +                        jPanel7Layout.setVerticalGroup(
 +                            jPanel7Layout.createParallelGroup()
 +                                .add(jPanel7Layout.createSequentialGroup()
 +                                    .add(28, 28, 28)
 +                                    .add(jPanel7Layout.createParallelGroup(GroupLayout.CENTER)
 +                                        .add(enablePortCB)
 +                                        .add(portField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                    .addPreferredGap(LayoutStyle.UNRELATED)
 +                                    .add(jLabel22)
 +                                    .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 +                        );
 +                    }
 +
 +                    GroupLayout jPanel3Layout = new GroupLayout(jPanel3);
 +                    jPanel3.setLayout(jPanel3Layout);
 +                    jPanel3Layout.setHorizontalGroup(
 +                        jPanel3Layout.createParallelGroup()
 +                            .add(jPanel3Layout.createSequentialGroup()
 +                                .addContainerGap()
 +                                .add(jPanel3Layout.createParallelGroup()
 +                                    .add(jPanel7, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 +                                    .add(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                .addContainerGap())
 +                    );
 +                    jPanel3Layout.setVerticalGroup(
 +                        jPanel3Layout.createParallelGroup()
 +                            .add(jPanel3Layout.createSequentialGroup()
 +                                .add(20, 20, 20)
 +                                .add(jPanel7, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                .addPreferredGap(LayoutStyle.RELATED, 58, Short.MAX_VALUE)
 +                                .add(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                .addContainerGap())
++=======
+             }
+             tabbedPane.addTab("General", generalPanel);
+ 
+ 
+             //======== tracksPanel ========
+             {
+                 tracksPanel.setLayout(null);
+ 
+                 //======== jPanel6 ========
+                 {
+ 
+                     //---- jLabel5 ----
+                     jLabel5.setText("Default Track Height, Charts (Pixels)");
+ 
+                     //---- defaultChartTrackHeightField ----
+                     defaultChartTrackHeightField.setText("40");
+                     defaultChartTrackHeightField.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             defaultChartTrackHeightFieldActionPerformed(e);
+                         }
+                     });
+                     defaultChartTrackHeightField.addFocusListener(new FocusAdapter() {
+                         @Override
+                         public void focusLost(FocusEvent e) {
+                             defaultChartTrackHeightFieldFocusLost(e);
+                         }
+                     });
+ 
+                     //---- trackNameAttributeLabel ----
+                     trackNameAttributeLabel.setText("Track Name Attribute");
+ 
+                     //---- trackNameAttributeField ----
+                     trackNameAttributeField.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             trackNameAttributeFieldActionPerformed(e);
+                         }
+                     });
+                     trackNameAttributeField.addFocusListener(new FocusAdapter() {
+                         @Override
+                         public void focusLost(FocusEvent e) {
+                             trackNameAttributeFieldFocusLost(e);
+                         }
+                     });
+ 
+                     //---- missingDataExplanation2 ----
+                     missingDataExplanation2.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
+                     missingDataExplanation2.setText("<html>Name of an attribute to be used to label  tracks.  If provided tracks will be labeled with the corresponding attribute values from the sample information file");
+                     missingDataExplanation2.setVerticalAlignment(SwingConstants.TOP);
+ 
+                     //---- jLabel8 ----
+                     jLabel8.setText("Default Track Height, Other (Pixels)");
+ 
+                     //---- defaultTrackHeightField ----
+                     defaultTrackHeightField.setText("15");
+                     defaultTrackHeightField.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             defaultTrackHeightFieldActionPerformed(e);
+                         }
+                     });
+                     defaultTrackHeightField.addFocusListener(new FocusAdapter() {
+                         @Override
+                         public void focusLost(FocusEvent e) {
+                             defaultTrackHeightFieldFocusLost(e);
+                         }
+                     });
+ 
+                     //---- missingDataExplanation4 ----
+                     missingDataExplanation4.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
+                     missingDataExplanation4.setText("<html>Default height of chart tracks (barcharts, scatterplots, etc)");
+ 
+                     //---- missingDataExplanation5 ----
+                     missingDataExplanation5.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
+                     missingDataExplanation5.setText("<html>Default height of all other tracks");
+ 
+                     //---- missingDataExplanation3 ----
+                     missingDataExplanation3.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
+                     missingDataExplanation3.setText("<html><i> If selected feature tracks are expanded by default.");
+ 
+                     //---- expandCB ----
+                     expandCB.setText("Expand Feature Tracks");
+                     expandCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             expandCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- normalizeCoverageCB ----
+                     normalizeCoverageCB.setText("Normalize Coverage Data");
+                     normalizeCoverageCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             normalizeCoverageCBActionPerformed(e);
+                         }
+                     });
+                     normalizeCoverageCB.addFocusListener(new FocusAdapter() {
+                         @Override
+                         public void focusLost(FocusEvent e) {
+                             normalizeCoverageCBFocusLost(e);
+                         }
+                     });
+ 
+                     //---- missingDataExplanation8 ----
+                     missingDataExplanation8.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
+                     missingDataExplanation8.setText("<html><i> Applies to coverage tracks computed with igvtools (.tdf files).  If selected coverage values are scaled by (1,000,000 / totalCount),  where totalCount is the total number of features or alignments.");
+                     missingDataExplanation8.setVerticalAlignment(SwingConstants.TOP);
+ 
+                     //---- expandIconCB ----
+                     expandIconCB.setText("Show Expand Icon");
+                     expandIconCB.setToolTipText("If checked displays an expand/collapse icon on feature tracks.");
+                     expandIconCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             expandIconCBActionPerformed(e);
+                         }
+                     });
+ 
+                     GroupLayout jPanel6Layout = new GroupLayout(jPanel6);
+                     jPanel6.setLayout(jPanel6Layout);
+                     jPanel6Layout.setHorizontalGroup(
+                             jPanel6Layout.createParallelGroup()
+                                     .add(jPanel6Layout.createSequentialGroup()
+                                     .add(jPanel6Layout.createParallelGroup()
+                                             .add(jPanel6Layout.createSequentialGroup()
+                                                     .addContainerGap()
+                                                     .add(jPanel6Layout.createParallelGroup()
+                                                     .add(jPanel6Layout.createSequentialGroup()
+                                                             .add(24, 24, 24)
+                                                             .add(missingDataExplanation4, GroupLayout.PREFERRED_SIZE, 354, GroupLayout.PREFERRED_SIZE))
+                                                     .add(jPanel6Layout.createSequentialGroup()
+                                                             .add(trackNameAttributeLabel)
+                                                             .addPreferredGap(LayoutStyle.RELATED)
+                                                             .add(trackNameAttributeField, GroupLayout.PREFERRED_SIZE, 216, GroupLayout.PREFERRED_SIZE))
+                                                     .add(jPanel6Layout.createSequentialGroup()
+                                                             .add(jLabel8)
+                                                             .add(39, 39, 39)
+                                                             .add(defaultTrackHeightField, GroupLayout.PREFERRED_SIZE, 57, GroupLayout.PREFERRED_SIZE))
+                                                     .add(jPanel6Layout.createSequentialGroup()
+                                                             .add(24, 24, 24)
+                                                             .add(missingDataExplanation5, GroupLayout.DEFAULT_SIZE, 1141, Short.MAX_VALUE))
+                                                     .add(jPanel6Layout.createSequentialGroup()
+                                                     .add(jLabel5)
+                                                     .add(36, 36, 36)
+                                                     .add(defaultChartTrackHeightField, GroupLayout.PREFERRED_SIZE, 57, GroupLayout.PREFERRED_SIZE))))
+                                             .add(jPanel6Layout.createSequentialGroup()
+                                                     .addContainerGap()
+                                                     .add(expandIconCB)
+                                                     .add(724, 724, 724)
+                                                     .add(missingDataExplanation3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                             .add(jPanel6Layout.createSequentialGroup()
+                                                     .add(63, 63, 63)
+                                                     .add(missingDataExplanation2, GroupLayout.PREFERRED_SIZE, 578, GroupLayout.PREFERRED_SIZE))
+                                             .add(jPanel6Layout.createSequentialGroup()
+                                                     .addContainerGap()
+                                                     .add(expandCB))
+                                             .add(jPanel6Layout.createSequentialGroup()
+                                                     .addContainerGap()
+                                                     .add(normalizeCoverageCB))
+                                             .add(jPanel6Layout.createSequentialGroup()
+                                             .add(50, 50, 50)
+                                             .add(missingDataExplanation8, GroupLayout.PREFERRED_SIZE, 608, GroupLayout.PREFERRED_SIZE)))
+                                     .addContainerGap())
+                     );
+                     jPanel6Layout.setVerticalGroup(
+                             jPanel6Layout.createParallelGroup()
+                                     .add(jPanel6Layout.createSequentialGroup()
+                                     .addContainerGap()
+                                     .add(jPanel6Layout.createParallelGroup(GroupLayout.BASELINE)
+                                             .add(jLabel5)
+                                             .add(defaultChartTrackHeightField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(missingDataExplanation4, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(jPanel6Layout.createParallelGroup(GroupLayout.BASELINE)
+                                             .add(jLabel8)
+                                             .add(defaultTrackHeightField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(missingDataExplanation5, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE)
+                                     .add(26, 26, 26)
+                                     .add(jPanel6Layout.createParallelGroup(GroupLayout.BASELINE)
+                                             .add(trackNameAttributeLabel)
+                                             .add(trackNameAttributeField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(missingDataExplanation2, GroupLayout.PREFERRED_SIZE, 54, GroupLayout.PREFERRED_SIZE)
+                                     .add(28, 28, 28)
+                                     .add(expandCB)
+                                     .add(23, 23, 23)
+                                     .add(jPanel6Layout.createParallelGroup()
+                                             .add(missingDataExplanation3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                             .add(expandIconCB))
+                                     .addPreferredGap(LayoutStyle.RELATED, 31, Short.MAX_VALUE)
+                                     .add(normalizeCoverageCB)
+                                     .add(18, 18, 18)
+                                     .add(missingDataExplanation8, GroupLayout.PREFERRED_SIZE, 52, GroupLayout.PREFERRED_SIZE)
+                                     .add(15, 15, 15))
+                     );
+                 }
+                 tracksPanel.add(jPanel6);
+                 jPanel6.setBounds(40, 20, 690, 480);
+ 
+                 { // compute preferred size
+                     Dimension preferredSize = new Dimension();
+                     for (int i = 0; i < tracksPanel.getComponentCount(); i++) {
+                         Rectangle bounds = tracksPanel.getComponent(i).getBounds();
+                         preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
+                         preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
+                     }
+                     Insets insets = tracksPanel.getInsets();
+                     preferredSize.width += insets.right;
+                     preferredSize.height += insets.bottom;
+                     tracksPanel.setMinimumSize(preferredSize);
+                     tracksPanel.setPreferredSize(preferredSize);
+                 }
+             }
+             tabbedPane.addTab("Tracks", tracksPanel);
+ 
+ 
+             //======== overlaysPanel ========
+             {
+ 
+                 //======== jPanel5 ========
+                 {
+ 
+                     //---- jLabel3 ----
+                     jLabel3.setText("Overlay tracks based on attribute:");
+ 
+                     //---- overlayAttributeTextField ----
+                     overlayAttributeTextField.setText("LINKING_ID");
+                     overlayAttributeTextField.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             overlayAttributeTextFieldActionPerformed(e);
+                         }
+                     });
+                     overlayAttributeTextField.addFocusListener(new FocusAdapter() {
+                         @Override
+                         public void focusLost(FocusEvent e) {
+                             overlayAttributeTextFieldFocusLost(e);
+                         }
+                     });
+                     overlayAttributeTextField.addKeyListener(new KeyAdapter() {
+                         @Override
+                         public void keyTyped(KeyEvent e) {
+                             overlayAttributeTextFieldKeyTyped(e);
+                         }
+                     });
+ 
+                     //---- overlayTrackCB ----
+                     overlayTrackCB.setSelected(true);
+                     overlayTrackCB.setText("Overlay mutation tracks");
+                     overlayTrackCB.setActionCommand("overlayTracksCB");
+                     overlayTrackCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             overlayTrackCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- jLabel2 ----
+                     jLabel2.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
+ 
+                     //---- displayTracksCB ----
+                     displayTracksCB.setText("Display mutation data as distinct tracks");
+                     displayTracksCB.setActionCommand("displayTracksCB");
+                     displayTracksCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             displayTracksCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- jLabel4 ----
+                     jLabel4.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
+ 
+                     //---- colorOverlyCB ----
+                     colorOverlyCB.setText("Color code overlay");
+                     colorOverlyCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             colorOverlyCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- chooseOverlayColorsButton ----
+                     chooseOverlayColorsButton.setForeground(new Color(0, 0, 247));
+                     chooseOverlayColorsButton.setText("Choose colors");
+                     chooseOverlayColorsButton.setFont(new Font("Lucida Grande", Font.ITALIC, 12));
+                     chooseOverlayColorsButton.setVerticalAlignment(SwingConstants.BOTTOM);
+                     chooseOverlayColorsButton.setVerticalTextPosition(SwingConstants.BOTTOM);
+                     chooseOverlayColorsButton.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             chooseOverlayColorsButtonActionPerformed(e);
+                         }
+                     });
+ 
+                     GroupLayout jPanel5Layout = new GroupLayout(jPanel5);
+                     jPanel5.setLayout(jPanel5Layout);
+                     jPanel5Layout.setHorizontalGroup(
+                             jPanel5Layout.createParallelGroup()
+                                     .add(jPanel5Layout.createSequentialGroup()
+                                     .addContainerGap()
+                                     .add(jPanel5Layout.createParallelGroup()
+                                             .add(displayTracksCB)
+                                             .add(jLabel4)
+                                             .add(overlayTrackCB)
+                                             .add(jLabel2)
+                                             .add(jPanel5Layout.createSequentialGroup()
+                                             .add(59, 59, 59)
+                                             .add(jPanel5Layout.createParallelGroup()
+                                             .add(jPanel5Layout.createSequentialGroup()
+                                                     .add(colorOverlyCB)
+                                                     .addPreferredGap(LayoutStyle.RELATED)
+                                                     .add(chooseOverlayColorsButton, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                             .add(jPanel5Layout.createSequentialGroup()
+                                             .add(jLabel3)
+                                             .addPreferredGap(LayoutStyle.RELATED)
+                                             .add(overlayAttributeTextField, GroupLayout.PREFERRED_SIZE, 228, GroupLayout.PREFERRED_SIZE)))))
+                                     .addContainerGap())
+                     );
+                     jPanel5Layout.setVerticalGroup(
+                             jPanel5Layout.createParallelGroup()
+                                     .add(jPanel5Layout.createSequentialGroup()
+                                     .addContainerGap()
+                                     .add(jLabel2)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(jLabel4)
+                                     .add(39, 39, 39)
+                                     .add(overlayTrackCB)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(jPanel5Layout.createParallelGroup(GroupLayout.BASELINE)
+                                             .add(jLabel3)
+                                             .add(overlayAttributeTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                     .add(6, 6, 6)
+                                     .add(jPanel5Layout.createParallelGroup(GroupLayout.TRAILING)
+                                             .add(colorOverlyCB)
+                                             .add(chooseOverlayColorsButton, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                     .add(36, 36, 36)
+                                     .add(displayTracksCB)
+                                     .addContainerGap(30, Short.MAX_VALUE))
+                     );
+                 }
+ 
+                 GroupLayout overlaysPanelLayout = new GroupLayout(overlaysPanel);
+                 overlaysPanel.setLayout(overlaysPanelLayout);
+                 overlaysPanelLayout.setHorizontalGroup(
+                         overlaysPanelLayout.createParallelGroup()
+                                 .add(overlaysPanelLayout.createSequentialGroup()
+                                 .add(28, 28, 28)
+                                 .add(jPanel5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                 .addContainerGap(235, Short.MAX_VALUE))
+                 );
+                 overlaysPanelLayout.setVerticalGroup(
+                         overlaysPanelLayout.createParallelGroup()
+                                 .add(overlaysPanelLayout.createSequentialGroup()
+                                 .add(55, 55, 55)
+                                 .add(jPanel5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                 .addContainerGap(225, Short.MAX_VALUE))
+                 );
+             }
+             tabbedPane.addTab("Mutations", overlaysPanel);
+ 
+ 
+             //======== chartPanel ========
+             {
+                 chartPanel.setLayout(null);
+ 
+                 //======== jPanel4 ========
+                 {
+ 
+                     //---- topBorderCB ----
+                     topBorderCB.setText("Draw Top Border");
+                     topBorderCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             topBorderCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- label1 ----
+                     label1.setFont(label1.getFont());
+                     label1.setText("Default settings for barcharts and scatterplots:");
+ 
+                     //---- chartDrawTrackNameCB ----
+                     chartDrawTrackNameCB.setText("Draw Track Label");
+                     chartDrawTrackNameCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             chartDrawTrackNameCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- bottomBorderCB ----
+                     bottomBorderCB.setText("Draw Bottom Border");
+                     bottomBorderCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             bottomBorderCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- jLabel7 ----
+                     jLabel7.setText("<html><i>If selected charts are dynamically rescaled to the range of the data in view.");
+ 
+                     //---- colorBordersCB ----
+                     colorBordersCB.setText("Color Borders");
+                     colorBordersCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             colorBordersCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- labelYAxisCB ----
+                     labelYAxisCB.setText("Label Y Axis");
+                     labelYAxisCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             labelYAxisCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- autoscaleCB ----
+                     autoscaleCB.setText("Continuous Autoscale");
+                     autoscaleCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             autoscaleCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- jLabel9 ----
+                     jLabel9.setText("<html><i>Draw a label centered over the track provided<br>the track height is at least 25 pixels. ");
+ 
+                     //---- showDatarangeCB ----
+                     showDatarangeCB.setText("Show Data Range");
+                     showDatarangeCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             showDatarangeCBActionPerformed(e);
+                         }
+                     });
+                     showDatarangeCB.addFocusListener(new FocusAdapter() {
+                         @Override
+                         public void focusLost(FocusEvent e) {
+                             showDatarangeCBFocusLost(e);
+                         }
+                     });
+ 
+                     GroupLayout jPanel4Layout = new GroupLayout(jPanel4);
+                     jPanel4.setLayout(jPanel4Layout);
+                     jPanel4Layout.setHorizontalGroup(
+                             jPanel4Layout.createParallelGroup()
+                                     .add(jPanel4Layout.createParallelGroup()
+                                             .add(GroupLayout.TRAILING, jPanel4Layout.createSequentialGroup()
+                                             .addContainerGap(221, Short.MAX_VALUE)
+                                             .add(jLabel9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                             .add(84, 84, 84)))
+                                     .add(jPanel4Layout.createSequentialGroup()
+                                     .addContainerGap()
+                                     .add(jPanel4Layout.createParallelGroup()
+                                             .add(label1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                             .add(jPanel4Layout.createSequentialGroup()
+                                             .add(20, 20, 20)
+                                             .add(jPanel4Layout.createParallelGroup()
+                                             .add(jPanel4Layout.createSequentialGroup()
+                                                     .add(jPanel4Layout.createParallelGroup()
+                                                             .add(autoscaleCB)
+                                                             .add(showDatarangeCB))
+                                                     .add(18, 18, 18)
+                                                     .add(jLabel7, GroupLayout.DEFAULT_SIZE, 371, Short.MAX_VALUE))
+                                             .add(jPanel4Layout.createSequentialGroup()
+                                             .add(jPanel4Layout.createParallelGroup()
+                                                     .add(topBorderCB)
+                                                     .add(colorBordersCB)
+                                                     .add(bottomBorderCB)
+                                                     .add(labelYAxisCB)
+                                                     .add(chartDrawTrackNameCB))
+                                             .addPreferredGap(LayoutStyle.RELATED, 403, Short.MAX_VALUE)))))
+                                     .addContainerGap())
+                     );
+                     jPanel4Layout.setVerticalGroup(
+                             jPanel4Layout.createParallelGroup()
+                                     .add(jPanel4Layout.createParallelGroup()
+                                             .add(jPanel4Layout.createSequentialGroup()
+                                             .add(131, 131, 131)
+                                             .add(jLabel9, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                             .addContainerGap(181, Short.MAX_VALUE)))
+                                     .add(jPanel4Layout.createSequentialGroup()
+                                     .addContainerGap()
+                                     .add(label1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(topBorderCB)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(bottomBorderCB)
+                                     .add(7, 7, 7)
+                                     .add(colorBordersCB)
+                                     .add(18, 18, 18)
+                                     .add(chartDrawTrackNameCB)
+                                     .add(23, 23, 23)
+                                     .add(labelYAxisCB)
+                                     .add(18, 18, 18)
+                                     .add(jPanel4Layout.createParallelGroup(GroupLayout.BASELINE)
+                                             .add(autoscaleCB)
+                                             .add(jLabel7, GroupLayout.PREFERRED_SIZE, 50, GroupLayout.PREFERRED_SIZE))
+                                     .addPreferredGap(LayoutStyle.UNRELATED)
+                                     .add(showDatarangeCB)
+                                     .add(36, 36, 36))
+                     );
+                 }
+                 chartPanel.add(jPanel4);
+                 jPanel4.setBounds(20, 30, 590, 340);
+ 
+                 { // compute preferred size
+                     Dimension preferredSize = new Dimension();
+                     for (int i = 0; i < chartPanel.getComponentCount(); i++) {
+                         Rectangle bounds = chartPanel.getComponent(i).getBounds();
+                         preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
+                         preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
+                     }
+                     Insets insets = chartPanel.getInsets();
+                     preferredSize.width += insets.right;
+                     preferredSize.height += insets.bottom;
+                     chartPanel.setMinimumSize(preferredSize);
+                     chartPanel.setPreferredSize(preferredSize);
+                 }
+             }
+             tabbedPane.addTab("Charts", chartPanel);
+ 
+ 
+             //======== alignmentPanel ========
+             {
+                 alignmentPanel.setLayout(null);
+ 
+                 //======== jPanel1 ========
+                 {
+                     jPanel1.setLayout(null);
+ 
+                     //======== jPanel11 ========
+                     {
+                         jPanel11.setLayout(null);
+ 
+                         //---- samMaxLevelsField ----
+                         samMaxLevelsField.setText("jTextField1");
+                         samMaxLevelsField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 samMaxLevelFieldActionPerformed(e);
+                             }
+                         });
+                         samMaxLevelsField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 samMaxLevelFieldFocusLost(e);
+                             }
+                         });
+                         jPanel11.add(samMaxLevelsField);
+                         samMaxLevelsField.setBounds(new Rectangle(new Point(206, 41), samMaxLevelsField.getPreferredSize()));
+ 
+                         //---- snpThresholdField ----
+                         snpThresholdField.setText("0");
+                         snpThresholdField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 snpThresholdFieldActionPerformed(e);
+                             }
+                         });
+                         snpThresholdField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 snpThresholdFieldFocusLost(e);
+                             }
+                         });
+                         jPanel11.add(snpThresholdField);
+                         snpThresholdField.setBounds(206, 144, 84, snpThresholdField.getPreferredSize().height);
+ 
+                         //---- jLabel11 ----
+                         jLabel11.setText("Visibility range threshold (kb)");
+                         jPanel11.add(jLabel11);
+                         jLabel11.setBounds(new Rectangle(new Point(6, 12), jLabel11.getPreferredSize()));
+ 
+                         //---- jLabel26 ----
+                         jLabel26.setText("Coverage allele-freq threshold");
+                         jPanel11.add(jLabel26);
+                         jLabel26.setBounds(6, 150, 200, jLabel26.getPreferredSize().height);
+ 
+                         //---- jLabel17 ----
+                         jLabel17.setText("Insert size flagging threshold:");
+                         jPanel11.add(jLabel17);
+                         jLabel17.setBounds(6, 116, 200, jLabel17.getPreferredSize().height);
+ 
+                         //---- jLabel16 ----
+                         jLabel16.setText("<html><i>Reads with qualities  below the threshold are not shown.");
+                         jPanel11.add(jLabel16);
+                         jLabel16.setBounds(new Rectangle(new Point(296, 82), jLabel16.getPreferredSize()));
+ 
+                         //---- mappingQualityThresholdField ----
+                         mappingQualityThresholdField.setText("0");
+                         mappingQualityThresholdField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 mappingQualityThresholdFieldActionPerformed(e);
+                             }
+                         });
+                         mappingQualityThresholdField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 mappingQualityThresholdFieldFocusLost(e);
+                             }
+                         });
+                         jPanel11.add(mappingQualityThresholdField);
+                         mappingQualityThresholdField.setBounds(206, 76, 84, mappingQualityThresholdField.getPreferredSize().height);
+ 
+                         //---- jLabel14 ----
+                         jLabel14.setText("<html><i>Maximum depth of reads to display.");
+                         jPanel11.add(jLabel14);
+                         jLabel14.setBounds(296, 40, 390, 30);
+ 
+                         //---- insertSizeThresholdField ----
+                         insertSizeThresholdField.setText("0");
+                         insertSizeThresholdField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 insertSizeThresholdFieldActionPerformed(e);
+                             }
+                         });
+                         insertSizeThresholdField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 insertSizeThresholdFieldFocusLost(e);
+                             }
+                         });
+                         jPanel11.add(insertSizeThresholdField);
+                         insertSizeThresholdField.setBounds(206, 110, 84, insertSizeThresholdField.getPreferredSize().height);
+ 
+                         //---- jLabel13 ----
+                         jLabel13.setText("Maximum read depth:");
+                         jPanel11.add(jLabel13);
+                         jLabel13.setBounds(new Rectangle(new Point(6, 47), jLabel13.getPreferredSize()));
+ 
+                         //---- jLabel15 ----
+                         jLabel15.setText("Mapping quality threshold:");
+                         jPanel11.add(jLabel15);
+                         jLabel15.setBounds(new Rectangle(new Point(6, 82), jLabel15.getPreferredSize()));
+ 
+                         //---- jLabel18 ----
+                         jLabel18.setText("<html><i>Paired end alignments with insert sizes > this value are flagged.");
+                         jPanel11.add(jLabel18);
+                         jLabel18.setBounds(296, 110, 414, 40);
+ 
+                         //---- samMaxWindowSizeField ----
+                         samMaxWindowSizeField.setText("jTextField1");
+                         samMaxWindowSizeField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 samMaxWindowSizeFieldActionPerformed(e);
+                             }
+                         });
+                         samMaxWindowSizeField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 samMaxWindowSizeFieldFocusLost(e);
+                             }
+                         });
+                         jPanel11.add(samMaxWindowSizeField);
+                         samMaxWindowSizeField.setBounds(new Rectangle(new Point(206, 6), samMaxWindowSizeField.getPreferredSize()));
+ 
+                         //---- jLabel12 ----
+                         jLabel12.setText("<html><i>Nominal window size at which alignments become visible");
+                         jPanel11.add(jLabel12);
+                         jLabel12.setBounds(new Rectangle(new Point(296, 12), jLabel12.getPreferredSize()));
+ 
+                         { // compute preferred size
+                             Dimension preferredSize = new Dimension();
+                             for (int i = 0; i < jPanel11.getComponentCount(); i++) {
+                                 Rectangle bounds = jPanel11.getComponent(i).getBounds();
+                                 preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
+                                 preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
+                             }
+                             Insets insets = jPanel11.getInsets();
+                             preferredSize.width += insets.right;
+                             preferredSize.height += insets.bottom;
+                             jPanel11.setMinimumSize(preferredSize);
+                             jPanel11.setPreferredSize(preferredSize);
+                         }
+                     }
+                     jPanel1.add(jPanel11);
+                     jPanel11.setBounds(new Rectangle(new Point(6, 20), jPanel11.getPreferredSize()));
+ 
+                     //======== jPanel12 ========
+                     {
+                         jPanel12.setLayout(null);
+ 
+                         //---- samMinBaseQualityField ----
+                         samMinBaseQualityField.setText("0");
+                         samMinBaseQualityField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 samMinBaseQualityFieldActionPerformed(e);
+                             }
+                         });
+                         samMinBaseQualityField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 samMinBaseQualityFieldFocusLost(e);
+                             }
+                         });
+                         jPanel12.add(samMinBaseQualityField);
+                         samMinBaseQualityField.setBounds(325, 140, 50, samMinBaseQualityField.getPreferredSize().height);
+ 
+                         //---- samShadeMismatchedBaseCB ----
+                         samShadeMismatchedBaseCB.setText("Shade mismatched bases by quality. ");
+                         samShadeMismatchedBaseCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 samShadeMismatchedBaseCBActionPerformed(e);
+                             }
+                         });
+                         jPanel12.add(samShadeMismatchedBaseCB);
+                         samShadeMismatchedBaseCB.setBounds(6, 146, 290, samShadeMismatchedBaseCB.getPreferredSize().height);
+ 
+                         //---- samMaxBaseQualityField ----
+                         samMaxBaseQualityField.setText("0");
+                         samMaxBaseQualityField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 samMaxBaseQualityFieldActionPerformed(e);
+                             }
+                         });
+                         samMaxBaseQualityField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 samMaxBaseQualityFieldFocusLost(e);
+                             }
+                         });
+                         jPanel12.add(samMaxBaseQualityField);
+                         samMaxBaseQualityField.setBounds(455, 140, 50, samMaxBaseQualityField.getPreferredSize().height);
+ 
+                         //---- showCovTrackCB ----
+                         showCovTrackCB.setText("Show coverage track");
+                         showCovTrackCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 showCovTrackCBActionPerformed(e);
+                             }
+                         });
+                         jPanel12.add(showCovTrackCB);
+                         showCovTrackCB.setBounds(385, 76, 270, showCovTrackCB.getPreferredSize().height);
+ 
+                         //---- samFilterDuplicatesCB ----
+                         samFilterDuplicatesCB.setText("Filter duplicate reads");
+                         samFilterDuplicatesCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 samShowDuplicatesCBActionPerformed(e);
+                             }
+                         });
+                         jPanel12.add(samFilterDuplicatesCB);
+                         samFilterDuplicatesCB.setBounds(6, 6, 290, samFilterDuplicatesCB.getPreferredSize().height);
+ 
+                         //---- showRefSeqCB ----
+                         showRefSeqCB.setText("Show reference sequence");
+                         showRefSeqCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 showRefSeqCBActionPerformed(e);
+                             }
+                         });
+                         jPanel12.add(showRefSeqCB);
+                         showRefSeqCB.setBounds(385, 6, 270, showRefSeqCB.getPreferredSize().height);
+ 
+                         //---- jLabel19 ----
+                         jLabel19.setText("Min: ");
+                         jPanel12.add(jLabel19);
+                         jLabel19.setBounds(new Rectangle(new Point(285, 145), jLabel19.getPreferredSize()));
+ 
+                         //---- filterCB ----
+                         filterCB.setText("Filter alignments");
+                         filterCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 filterCBActionPerformed(e);
+                             }
+                         });
+                         jPanel12.add(filterCB);
+                         filterCB.setBounds(6, 181, 144, filterCB.getPreferredSize().height);
+ 
+                         //---- filterURL ----
+                         filterURL.setText("URL or path to filter file");
+                         filterURL.setEnabled(false);
+                         filterURL.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 filterURLActionPerformed(e);
+                             }
+                         });
+                         filterURL.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 filterURLFocusLost(e);
+                             }
+                         });
+                         jPanel12.add(filterURL);
+                         filterURL.setBounds(190, 185, 482, filterURL.getPreferredSize().height);
+ 
+                         //---- samFlagUnmappedPairCB ----
+                         samFlagUnmappedPairCB.setText("Flag unmapped pairs");
+                         samFlagUnmappedPairCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 samFlagUnmappedPairCBActionPerformed(e);
+                             }
+                         });
+                         jPanel12.add(samFlagUnmappedPairCB);
+                         samFlagUnmappedPairCB.setBounds(6, 76, 310, samFlagUnmappedPairCB.getPreferredSize().height);
+ 
+                         //---- shadeCenterCB ----
+                         shadeCenterCB.setText("Shade alignments intersecting center");
+                         shadeCenterCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 shadeCenterCBActionPerformed(e);
+                             }
+                         });
+                         jPanel12.add(shadeCenterCB);
+                         shadeCenterCB.setBounds(385, 41, 450, shadeCenterCB.getPreferredSize().height);
+ 
+                         //---- jLabel10 ----
+                         jLabel10.setText("<html>Chromosome color legend &nbsp;&nbsp;&nbsp;<i>Used to flag paired end reads with mates on other chromosomes");
+                         jPanel12.add(jLabel10);
+                         jLabel10.setBounds(5, 230, 640, 30);
+ 
+                         //======== legendPanel ========
+                         {
+ 
+                             GroupLayout legendPanelLayout = new GroupLayout(legendPanel);
+                             legendPanel.setLayout(legendPanelLayout);
+                             legendPanelLayout.setHorizontalGroup(
+                                     legendPanelLayout.createParallelGroup()
+                                             .add(0, 602, Short.MAX_VALUE)
+                             );
+                             legendPanelLayout.setVerticalGroup(
+                                     legendPanelLayout.createParallelGroup()
+                                             .add(0, 25, Short.MAX_VALUE)
+                             );
+                         }
+                         jPanel12.add(legendPanel);
+                         legendPanel.setBounds(new Rectangle(new Point(5, 270), legendPanel.getPreferredSize()));
+ 
+                         //---- filterFailedReadsCB ----
+                         filterFailedReadsCB.setText("Filter vendor failed reads");
+                         filterFailedReadsCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 filterVendorFailedReadsCBActionPerformed(e);
+                             }
+                         });
+                         jPanel12.add(filterFailedReadsCB);
+                         filterFailedReadsCB.setBounds(new Rectangle(new Point(6, 41), filterFailedReadsCB.getPreferredSize()));
+ 
+                         //---- label2 ----
+                         label2.setText("Max:");
+                         jPanel12.add(label2);
+                         label2.setBounds(new Rectangle(new Point(400, 145), label2.getPreferredSize()));
+ 
+                         //---- showSoftClippedCB ----
+                         showSoftClippedCB.setText("Show soft-clipped bases");
+                         showSoftClippedCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 showSoftClippedCBActionPerformed(e);
+                             }
+                         });
+                         jPanel12.add(showSoftClippedCB);
+                         showSoftClippedCB.setBounds(new Rectangle(new Point(6, 111), showSoftClippedCB.getPreferredSize()));
+ 
+                         { // compute preferred size
+                             Dimension preferredSize = new Dimension();
+                             for (int i = 0; i < jPanel12.getComponentCount(); i++) {
+                                 Rectangle bounds = jPanel12.getComponent(i).getBounds();
+                                 preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
+                                 preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
+                             }
+                             Insets insets = jPanel12.getInsets();
+                             preferredSize.width += insets.right;
+                             preferredSize.height += insets.bottom;
+                             jPanel12.setMinimumSize(preferredSize);
+                             jPanel12.setPreferredSize(preferredSize);
+                         }
+                     }
+                     jPanel1.add(jPanel12);
+                     jPanel12.setBounds(6, 198, 740, 297);
+ 
+                     { // compute preferred size
+                         Dimension preferredSize = new Dimension();
+                         for (int i = 0; i < jPanel1.getComponentCount(); i++) {
+                             Rectangle bounds = jPanel1.getComponent(i).getBounds();
+                             preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
+                             preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
+                         }
+                         Insets insets = jPanel1.getInsets();
+                         preferredSize.width += insets.right;
+                         preferredSize.height += insets.bottom;
+                         jPanel1.setMinimumSize(preferredSize);
+                         jPanel1.setPreferredSize(preferredSize);
+                     }
+                 }
+                 alignmentPanel.add(jPanel1);
+                 jPanel1.setBounds(0, 0, 760, 510);
+ 
+                 { // compute preferred size
+                     Dimension preferredSize = new Dimension();
+                     for (int i = 0; i < alignmentPanel.getComponentCount(); i++) {
+                         Rectangle bounds = alignmentPanel.getComponent(i).getBounds();
+                         preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
+                         preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
+                     }
+                     Insets insets = alignmentPanel.getInsets();
+                     preferredSize.width += insets.right;
+                     preferredSize.height += insets.bottom;
+                     alignmentPanel.setMinimumSize(preferredSize);
+                     alignmentPanel.setPreferredSize(preferredSize);
+                 }
+             }
+             tabbedPane.addTab("Alignments", alignmentPanel);
+ 
+ 
+             //======== expressionPane ========
+             {
+                 expressionPane.setLayout(null);
+ 
+                 //======== jPanel8 ========
+                 {
+ 
+                     //---- expMapToGeneCB ----
+                     expMapToGeneCB.setText("Map probes to genes");
+                     expMapToGeneCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             expMapToGeneCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- jLabel24 ----
+                     jLabel24.setText("Expression probe mapping options: ");
+ 
+                     //---- expMapToLociCB ----
+                     expMapToLociCB.setText("<html>Map probes to target loci");
+                     expMapToLociCB.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             expMapToLociCBActionPerformed(e);
+                         }
+                     });
+ 
+                     //---- jLabel21 ----
+                     jLabel21.setText("<html><i>Note: Changes will not affect currently loaded datasets.");
+ 
+                     GroupLayout jPanel8Layout = new GroupLayout(jPanel8);
+                     jPanel8.setLayout(jPanel8Layout);
+                     jPanel8Layout.setHorizontalGroup(
+                             jPanel8Layout.createParallelGroup()
+                                     .add(jPanel8Layout.createSequentialGroup()
+                                     .add(jPanel8Layout.createParallelGroup()
+                                             .add(jPanel8Layout.createSequentialGroup()
+                                                     .add(45, 45, 45)
+                                                     .add(jPanel8Layout.createParallelGroup()
+                                                     .add(expMapToLociCB, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                                     .add(expMapToGeneCB)))
+                                             .add(jPanel8Layout.createSequentialGroup()
+                                             .addContainerGap()
+                                             .add(jPanel8Layout.createParallelGroup()
+                                             .add(jPanel8Layout.createSequentialGroup()
+                                                     .add(24, 24, 24)
+                                                     .add(jLabel21, GroupLayout.PREFERRED_SIZE, 497, GroupLayout.PREFERRED_SIZE))
+                                             .add(jLabel24))))
+                                     .addContainerGap(193, Short.MAX_VALUE))
+                     );
+                     jPanel8Layout.setVerticalGroup(
+                             jPanel8Layout.createParallelGroup()
+                                     .add(jPanel8Layout.createSequentialGroup()
+                                     .addContainerGap()
+                                     .add(jLabel24)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(jLabel21, GroupLayout.PREFERRED_SIZE, 44, GroupLayout.PREFERRED_SIZE)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(expMapToLociCB, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                     .add(14, 14, 14)
+                                     .add(expMapToGeneCB)
+                                     .addContainerGap(172, Short.MAX_VALUE))
+                     );
+                 }
+                 expressionPane.add(jPanel8);
+                 jPanel8.setBounds(10, 30, 720, 310);
+ 
+                 { // compute preferred size
+                     Dimension preferredSize = new Dimension();
+                     for (int i = 0; i < expressionPane.getComponentCount(); i++) {
+                         Rectangle bounds = expressionPane.getComponent(i).getBounds();
+                         preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
+                         preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
+                     }
+                     Insets insets = expressionPane.getInsets();
+                     preferredSize.width += insets.right;
+                     preferredSize.height += insets.bottom;
+                     expressionPane.setMinimumSize(preferredSize);
+                     expressionPane.setPreferredSize(preferredSize);
+                 }
+             }
+             tabbedPane.addTab("Probes", expressionPane);
+ 
+ 
+             //======== advancedPanel ========
+             {
+                 advancedPanel.setBorder(new EmptyBorder(1, 10, 1, 10));
+                 advancedPanel.setLayout(null);
+ 
+                 //======== jPanel3 ========
+                 {
+ 
+                     //======== jPanel2 ========
+                     {
+ 
+                         //---- jLabel1 ----
+                         jLabel1.setText("Genome Server URL");
+ 
+                         //---- genomeServerURLTextField ----
+                         genomeServerURLTextField.setText("jTextField1");
+                         genomeServerURLTextField.setEnabled(false);
+                         genomeServerURLTextField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 genomeServerURLTextFieldActionPerformed(e);
+                             }
+                         });
+                         genomeServerURLTextField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 genomeServerURLTextFieldFocusLost(e);
+                             }
+                         });
+ 
+                         //---- jLabel6 ----
+                         jLabel6.setText("Data Registry URL");
+ 
+                         //---- dataServerURLTextField ----
+                         dataServerURLTextField.setEnabled(false);
+                         dataServerURLTextField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 dataServerURLTextFieldActionPerformed(e);
+                             }
+                         });
+                         dataServerURLTextField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 dataServerURLTextFieldFocusLost(e);
+                             }
+                         });
+ 
+                         //---- editServerPropertiesCB ----
+                         editServerPropertiesCB.setText("Edit server properties");
+                         editServerPropertiesCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 editServerPropertiesCBActionPerformed(e);
+                             }
+                         });
+ 
+                         //---- clearGenomeCacheButton ----
+                         clearGenomeCacheButton.setText("Clear Genome Cache");
+                         clearGenomeCacheButton.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 clearGenomeCacheButtonActionPerformed(e);
+                             }
+                         });
+ 
+                         //---- jButton1 ----
+                         jButton1.setText("Reset to Defaults");
+                         jButton1.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 jButton1ActionPerformed(e);
+                             }
+                         });
+ 
+                         GroupLayout jPanel2Layout = new GroupLayout(jPanel2);
+                         jPanel2.setLayout(jPanel2Layout);
+                         jPanel2Layout.setHorizontalGroup(
+                                 jPanel2Layout.createParallelGroup()
+                                         .add(jPanel2Layout.createSequentialGroup()
+                                         .addContainerGap()
+                                         .add(jPanel2Layout.createParallelGroup()
+                                                 .add(jPanel2Layout.createSequentialGroup()
+                                                         .add(29, 29, 29)
+                                                         .add(jPanel2Layout.createParallelGroup()
+                                                         .add(jLabel1)
+                                                         .add(jPanel2Layout.createSequentialGroup()
+                                                         .add(jLabel6)
+                                                         .add(44, 44, 44)
+                                                         .add(jPanel2Layout.createParallelGroup(GroupLayout.LEADING, false)
+                                                         .add(dataServerURLTextField)
+                                                         .add(genomeServerURLTextField, GroupLayout.PREFERRED_SIZE, 494, GroupLayout.PREFERRED_SIZE)))))
+                                                 .add(jPanel2Layout.createSequentialGroup()
+                                                         .add(editServerPropertiesCB)
+                                                         .add(18, 18, 18)
+                                                         .add(jButton1))
+                                                 .add(clearGenomeCacheButton))
+                                         .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                         );
+                         jPanel2Layout.setVerticalGroup(
+                                 jPanel2Layout.createParallelGroup()
+                                         .add(jPanel2Layout.createSequentialGroup()
+                                         .addContainerGap()
+                                         .add(jPanel2Layout.createParallelGroup(GroupLayout.BASELINE)
+                                                 .add(editServerPropertiesCB)
+                                                 .add(jButton1))
+                                         .addPreferredGap(LayoutStyle.RELATED)
+                                         .add(jPanel2Layout.createParallelGroup(GroupLayout.CENTER)
+                                                 .add(jLabel1)
+                                                 .add(genomeServerURLTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                         .addPreferredGap(LayoutStyle.RELATED)
+                                         .add(jPanel2Layout.createParallelGroup(GroupLayout.BASELINE)
+                                                 .add(jLabel6)
+                                                 .add(dataServerURLTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                         .add(18, 18, 18)
+                                         .add(clearGenomeCacheButton)
+                                         .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                         );
+                     }
+ 
+                     //======== jPanel7 ========
+                     {
+ 
+                         //---- enablePortCB ----
+                         enablePortCB.setText("Enable port");
+                         enablePortCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 enablePortCBActionPerformed(e);
+                             }
+                         });
+ 
+                         //---- portField ----
+                         portField.setText("60151");
+                         portField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 portFieldActionPerformed(e);
+                             }
+                         });
+                         portField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 portFieldFocusLost(e);
+                             }
+                         });
+ 
+                         //---- jLabel22 ----
+                         jLabel22.setFont(new Font("Lucida Grande", Font.ITALIC, 13));
+                         jLabel22.setText("Enable port to send commands and http requests to IGV. ");
+ 
+                         GroupLayout jPanel7Layout = new GroupLayout(jPanel7);
+                         jPanel7.setLayout(jPanel7Layout);
+                         jPanel7Layout.setHorizontalGroup(
+                                 jPanel7Layout.createParallelGroup()
+                                         .add(jPanel7Layout.createSequentialGroup()
+                                         .add(jPanel7Layout.createParallelGroup()
+                                                 .add(jPanel7Layout.createSequentialGroup()
+                                                         .addContainerGap()
+                                                         .add(enablePortCB)
+                                                         .add(39, 39, 39)
+                                                         .add(portField, GroupLayout.PREFERRED_SIZE, 126, GroupLayout.PREFERRED_SIZE))
+                                                 .add(jPanel7Layout.createSequentialGroup()
+                                                 .add(48, 48, 48)
+                                                 .add(jLabel22)))
+                                         .addContainerGap(330, Short.MAX_VALUE))
+                         );
+                         jPanel7Layout.setVerticalGroup(
+                                 jPanel7Layout.createParallelGroup()
+                                         .add(jPanel7Layout.createSequentialGroup()
+                                         .add(28, 28, 28)
+                                         .add(jPanel7Layout.createParallelGroup(GroupLayout.CENTER)
+                                                 .add(enablePortCB)
+                                                 .add(portField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                         .addPreferredGap(LayoutStyle.UNRELATED)
+                                         .add(jLabel22)
+                                         .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                         );
+                     }
+ 
+                     GroupLayout jPanel3Layout = new GroupLayout(jPanel3);
+                     jPanel3.setLayout(jPanel3Layout);
+                     jPanel3Layout.setHorizontalGroup(
+                             jPanel3Layout.createParallelGroup()
+                                     .add(jPanel3Layout.createSequentialGroup()
+                                     .addContainerGap()
+                                     .add(jPanel3Layout.createParallelGroup()
+                                             .add(jPanel7, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                             .add(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                     .addContainerGap())
+                     );
+                     jPanel3Layout.setVerticalGroup(
+                             jPanel3Layout.createParallelGroup()
+                                     .add(jPanel3Layout.createSequentialGroup()
+                                     .add(20, 20, 20)
+                                     .add(jPanel7, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                     .addPreferredGap(LayoutStyle.RELATED, 58, Short.MAX_VALUE)
+                                     .add(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                     .addContainerGap())
++>>>>>>> upstream/1.5.56
                      );
                  }
                  advancedPanel.add(jPanel3);
@@@ -1527,25 -1536,25 +2789,47 @@@
                      GroupLayout jPanel9Layout = new GroupLayout(jPanel9);
                      jPanel9.setLayout(jPanel9Layout);
                      jPanel9Layout.setHorizontalGroup(
++<<<<<<< HEAD
 +                        jPanel9Layout.createParallelGroup()
 +                            .add(jPanel9Layout.createSequentialGroup()
 +                                .add(jPanel9Layout.createParallelGroup()
 +                                    .add(jPanel9Layout.createSequentialGroup()
 +                                        .add(44, 44, 44)
 +                                        .add(jLabel25, GroupLayout.PREFERRED_SIZE, 601, GroupLayout.PREFERRED_SIZE))
 +                                    .add(jPanel9Layout.createSequentialGroup()
 +                                        .addContainerGap()
 +                                        .add(useByteRangeCB)))
 +                                .addContainerGap(65, Short.MAX_VALUE))
 +                    );
 +                    jPanel9Layout.setVerticalGroup(
 +                        jPanel9Layout.createParallelGroup()
 +                            .add(jPanel9Layout.createSequentialGroup()
 +                                .addContainerGap()
 +                                .add(useByteRangeCB, GroupLayout.PREFERRED_SIZE, 38, GroupLayout.PREFERRED_SIZE)
 +                                .addPreferredGap(LayoutStyle.RELATED)
 +                                .add(jLabel25, GroupLayout.DEFAULT_SIZE, 64, Short.MAX_VALUE)
 +                                .add(6, 6, 6))
++=======
+                             jPanel9Layout.createParallelGroup()
+                                     .add(jPanel9Layout.createSequentialGroup()
+                                     .add(jPanel9Layout.createParallelGroup()
+                                             .add(jPanel9Layout.createSequentialGroup()
+                                                     .add(44, 44, 44)
+                                                     .add(jLabel25, GroupLayout.PREFERRED_SIZE, 601, GroupLayout.PREFERRED_SIZE))
+                                             .add(jPanel9Layout.createSequentialGroup()
+                                             .addContainerGap()
+                                             .add(useByteRangeCB)))
+                                     .addContainerGap(65, Short.MAX_VALUE))
+                     );
+                     jPanel9Layout.setVerticalGroup(
+                             jPanel9Layout.createParallelGroup()
+                                     .add(jPanel9Layout.createSequentialGroup()
+                                     .addContainerGap()
+                                     .add(useByteRangeCB, GroupLayout.PREFERRED_SIZE, 38, GroupLayout.PREFERRED_SIZE)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(jLabel25, GroupLayout.DEFAULT_SIZE, 64, Short.MAX_VALUE)
+                                     .add(6, 6, 6))
++>>>>>>> upstream/1.5.56
                      );
                  }
                  advancedPanel.add(jPanel9);
@@@ -1553,7 -1562,7 +2837,11 @@@
  
                  { // compute preferred size
                      Dimension preferredSize = new Dimension();
++<<<<<<< HEAD
 +                    for(int i = 0; i < advancedPanel.getComponentCount(); i++) {
++=======
+                     for (int i = 0; i < advancedPanel.getComponentCount(); i++) {
++>>>>>>> upstream/1.5.56
                          Rectangle bounds = advancedPanel.getComponent(i).getBounds();
                          preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
                          preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
@@@ -1568,8 -1577,9 +2856,14 @@@
              tabbedPane.addTab("Advanced", advancedPanel);
  
  
++<<<<<<< HEAD
 +            //======== jPanel14 ========
 +            {
++=======
+             //======== proxyPanel ========
+             {
+                 proxyPanel.setLayout(new BoxLayout(proxyPanel, BoxLayout.X_AXIS));
++>>>>>>> upstream/1.5.56
  
                  //======== jPanel15 ========
                  {
@@@ -1580,6 -1590,17 +2874,20 @@@
                          //---- proxyUsernameField ----
                          proxyUsernameField.setText("jTextField1");
                          proxyUsernameField.setEnabled(false);
++<<<<<<< HEAD
++=======
+                         proxyUsernameField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 proxyUsernameFieldActionPerformed(e);
+                             }
+                         });
+                         proxyUsernameField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 proxyUsernameFieldFocusLost(e);
+                             }
+                         });
++>>>>>>> upstream/1.5.56
  
                          //---- jLabel28 ----
                          jLabel28.setText("Username");
@@@ -1607,165 -1628,168 +2915,329 @@@
                          GroupLayout jPanel16Layout = new GroupLayout(jPanel16);
                          jPanel16.setLayout(jPanel16Layout);
                          jPanel16Layout.setHorizontalGroup(
++<<<<<<< HEAD
 +                            jPanel16Layout.createParallelGroup()
 +                                .add(jPanel16Layout.createSequentialGroup()
 +                                    .add(jPanel16Layout.createParallelGroup()
 +                                        .add(jPanel16Layout.createSequentialGroup()
 +                                            .add(28, 28, 28)
 +                                            .add(jPanel16Layout.createParallelGroup()
 +                                                .add(jLabel28)
 +                                                .add(jLabel29))
 +                                            .add(37, 37, 37)
 +                                            .add(jPanel16Layout.createParallelGroup(GroupLayout.LEADING, false)
 +                                                .add(proxyPasswordField)
 +                                                .add(proxyUsernameField, GroupLayout.DEFAULT_SIZE, 261, Short.MAX_VALUE)))
 +                                        .add(jPanel16Layout.createSequentialGroup()
 +                                            .addContainerGap()
 +                                            .add(authenticateProxyCB)))
 +                                    .addContainerGap(219, Short.MAX_VALUE))
 +                        );
 +                        jPanel16Layout.setVerticalGroup(
 +                            jPanel16Layout.createParallelGroup()
 +                                .add(jPanel16Layout.createSequentialGroup()
 +                                    .add(17, 17, 17)
 +                                    .add(authenticateProxyCB)
 +                                    .addPreferredGap(LayoutStyle.RELATED)
 +                                    .add(jPanel16Layout.createParallelGroup(GroupLayout.BASELINE)
 +                                        .add(jLabel28)
 +                                        .add(proxyUsernameField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                    .addPreferredGap(LayoutStyle.RELATED)
 +                                    .add(jPanel16Layout.createParallelGroup(GroupLayout.BASELINE)
 +                                        .add(jLabel29)
 +                                        .add(proxyPasswordField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                    .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 +                        );
 +                    }
 +
 +                    //======== jPanel17 ========
 +                    {
 +
 +                        //---- proxyHostField ----
 +                        proxyHostField.setText("jTextField1");
 +                        proxyHostField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                proxyHostFieldActionPerformed(e);
 +                            }
 +                        });
 +                        proxyHostField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                proxyHostFieldFocusLost(e);
 +                            }
 +                        });
 +
 +                        //---- proxyPortField ----
 +                        proxyPortField.setText("jTextField1");
 +                        proxyPortField.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                proxyPortFieldActionPerformed(e);
 +                            }
 +                        });
 +                        proxyPortField.addFocusListener(new FocusAdapter() {
 +                            @Override
 +                            public void focusLost(FocusEvent e) {
 +                                proxyPortFieldFocusLost(e);
 +                            }
 +                        });
 +
 +                        //---- jLabel27 ----
 +                        jLabel27.setText("Proxy port");
 +
 +                        //---- jLabel23 ----
 +                        jLabel23.setText("Proxy host");
 +
 +                        //---- useProxyCB ----
 +                        useProxyCB.setText("Use proxy");
 +                        useProxyCB.addActionListener(new ActionListener() {
 +                            public void actionPerformed(ActionEvent e) {
 +                                useProxyCBActionPerformed(e);
 +                            }
 +                        });
 +
 +                        GroupLayout jPanel17Layout = new GroupLayout(jPanel17);
 +                        jPanel17.setLayout(jPanel17Layout);
 +                        jPanel17Layout.setHorizontalGroup(
 +                            jPanel17Layout.createParallelGroup()
 +                                .add(jPanel17Layout.createSequentialGroup()
 +                                    .add(jPanel17Layout.createParallelGroup()
 +                                        .add(jPanel17Layout.createSequentialGroup()
 +                                            .addContainerGap()
 +                                            .add(jPanel17Layout.createParallelGroup()
 +                                                .add(jLabel27)
 +                                                .add(jLabel23))
 +                                            .add(28, 28, 28)
 +                                            .add(jPanel17Layout.createParallelGroup()
 +                                                .add(proxyPortField, GroupLayout.PREFERRED_SIZE, 108, GroupLayout.PREFERRED_SIZE)
 +                                                .add(proxyHostField, GroupLayout.PREFERRED_SIZE, 485, GroupLayout.PREFERRED_SIZE)))
 +                                        .add(jPanel17Layout.createSequentialGroup()
 +                                            .add(9, 9, 9)
 +                                            .add(useProxyCB)))
 +                                    .addContainerGap(21, Short.MAX_VALUE))
 +                        );
 +                        jPanel17Layout.setVerticalGroup(
 +                            jPanel17Layout.createParallelGroup()
 +                                .add(GroupLayout.TRAILING, jPanel17Layout.createSequentialGroup()
 +                                    .addContainerGap(29, Short.MAX_VALUE)
 +                                    .add(useProxyCB)
 +                                    .add(18, 18, 18)
 +                                    .add(jPanel17Layout.createParallelGroup(GroupLayout.BASELINE)
 +                                        .add(jLabel23)
 +                                        .add(proxyHostField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                    .addPreferredGap(LayoutStyle.RELATED)
 +                                    .add(jPanel17Layout.createParallelGroup(GroupLayout.BASELINE)
 +                                        .add(jLabel27)
 +                                        .add(proxyPortField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
 +                                    .addContainerGap())
 +                        );
 +                    }
++=======
+                                 jPanel16Layout.createParallelGroup()
+                                         .add(jPanel16Layout.createSequentialGroup()
+                                         .add(jPanel16Layout.createParallelGroup()
+                                                 .add(jPanel16Layout.createSequentialGroup()
+                                                         .add(28, 28, 28)
+                                                         .add(jPanel16Layout.createParallelGroup()
+                                                                 .add(jLabel28)
+                                                                 .add(jLabel29))
+                                                         .add(37, 37, 37)
+                                                         .add(jPanel16Layout.createParallelGroup(GroupLayout.LEADING, false)
+                                                         .add(proxyPasswordField)
+                                                         .add(proxyUsernameField, GroupLayout.DEFAULT_SIZE, 261, Short.MAX_VALUE)))
+                                                 .add(jPanel16Layout.createSequentialGroup()
+                                                 .addContainerGap()
+                                                 .add(authenticateProxyCB)))
+                                         .addContainerGap(354, Short.MAX_VALUE))
+                         );
+                         jPanel16Layout.setVerticalGroup(
+                                 jPanel16Layout.createParallelGroup()
+                                         .add(jPanel16Layout.createSequentialGroup()
+                                         .add(17, 17, 17)
+                                         .add(authenticateProxyCB)
+                                         .addPreferredGap(LayoutStyle.RELATED)
+                                         .add(jPanel16Layout.createParallelGroup(GroupLayout.BASELINE)
+                                                 .add(jLabel28)
+                                                 .add(proxyUsernameField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                         .addPreferredGap(LayoutStyle.RELATED)
+                                         .add(jPanel16Layout.createParallelGroup(GroupLayout.BASELINE)
+                                                 .add(jLabel29)
+                                                 .add(proxyPasswordField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                         .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                         );
+                     }
+ 
+                     //======== jPanel17 ========
+                     {
+ 
+                         //---- proxyHostField ----
+                         proxyHostField.setText("jTextField1");
+                         proxyHostField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 proxyHostFieldActionPerformed(e);
+                             }
+                         });
+                         proxyHostField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 proxyHostFieldFocusLost(e);
+                             }
+                         });
+ 
+                         //---- proxyPortField ----
+                         proxyPortField.setText("jTextField1");
+                         proxyPortField.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 proxyPortFieldActionPerformed(e);
+                             }
+                         });
+                         proxyPortField.addFocusListener(new FocusAdapter() {
+                             @Override
+                             public void focusLost(FocusEvent e) {
+                                 proxyPortFieldFocusLost(e);
+                             }
+                         });
+ 
+                         //---- jLabel27 ----
+                         jLabel27.setText("Proxy port");
+ 
+                         //---- jLabel23 ----
+                         jLabel23.setText("Proxy host");
+ 
+                         //---- useProxyCB ----
+                         useProxyCB.setText("Use proxy");
+                         useProxyCB.addActionListener(new ActionListener() {
+                             public void actionPerformed(ActionEvent e) {
+                                 useProxyCBActionPerformed(e);
+                             }
+                         });
+ 
+                         GroupLayout jPanel17Layout = new GroupLayout(jPanel17);
+                         jPanel17.setLayout(jPanel17Layout);
+                         jPanel17Layout.setHorizontalGroup(
+                                 jPanel17Layout.createParallelGroup()
+                                         .add(jPanel17Layout.createSequentialGroup()
+                                         .add(jPanel17Layout.createParallelGroup()
+                                                 .add(jPanel17Layout.createSequentialGroup()
+                                                         .addContainerGap()
+                                                         .add(jPanel17Layout.createParallelGroup()
+                                                                 .add(jLabel27)
+                                                                 .add(jLabel23))
+                                                         .add(28, 28, 28)
+                                                         .add(jPanel17Layout.createParallelGroup()
+                                                         .add(proxyPortField, GroupLayout.PREFERRED_SIZE, 108, GroupLayout.PREFERRED_SIZE)
+                                                         .add(proxyHostField, GroupLayout.PREFERRED_SIZE, 485, GroupLayout.PREFERRED_SIZE)))
+                                                 .add(jPanel17Layout.createSequentialGroup()
+                                                 .add(9, 9, 9)
+                                                 .add(useProxyCB)))
+                                         .addContainerGap(21, Short.MAX_VALUE))
+                         );
+                         jPanel17Layout.setVerticalGroup(
+                                 jPanel17Layout.createParallelGroup()
+                                         .add(GroupLayout.TRAILING, jPanel17Layout.createSequentialGroup()
+                                         .addContainerGap(29, Short.MAX_VALUE)
+                                         .add(useProxyCB)
+                                         .add(18, 18, 18)
+                                         .add(jPanel17Layout.createParallelGroup(GroupLayout.BASELINE)
+                                                 .add(jLabel23)
+                                                 .add(proxyHostField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                         .addPreferredGap(LayoutStyle.RELATED)
+                                         .add(jPanel17Layout.createParallelGroup(GroupLayout.BASELINE)
+                                                 .add(jLabel27)
+                                                 .add(proxyPortField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                                         .addContainerGap())
+                         );
+                     }
+ 
+                     //---- label3 ----
+                     label3.setText("<html>Note:  do not use these settings unless you receive error or warning messages about server connections.  On most systems the correct settings will be automatically copied from your web browser.");
+ 
+                     //---- clearAllProxyButton ----
+                     clearAllProxyButton.setText("Clear All");
+                     clearAllProxyButton.addActionListener(new ActionListener() {
+                         public void actionPerformed(ActionEvent e) {
+                             clearAllProxyButtonActionPerformed(e);
+                         }
+                     });
++>>>>>>> upstream/1.5.56
  
                      GroupLayout jPanel15Layout = new GroupLayout(jPanel15);
                      jPanel15.setLayout(jPanel15Layout);
                      jPanel15Layout.setHorizontalGroup(
++<<<<<<< HEAD
 +                        jPanel15Layout.createParallelGroup()
 +                            .add(jPanel15Layout.createSequentialGroup()
 +                                .addContainerGap()
 +                                .add(jPanel15Layout.createParallelGroup()
 +                                    .add(jPanel15Layout.createSequentialGroup()
 +                                        .add(jPanel17, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                        .addContainerGap())
 +                                    .add(jPanel15Layout.createSequentialGroup()
 +                                        .add(jPanel16, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 +                                        .add(33, 33, 33))))
 +                    );
 +                    jPanel15Layout.setVerticalGroup(
 +                        jPanel15Layout.createParallelGroup()
 +                            .add(jPanel15Layout.createSequentialGroup()
 +                                .add(16, 16, 16)
 +                                .add(jPanel17, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                                .add(18, 18, 18)
 +                                .add(jPanel16, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 +                                .add(39, 39, 39))
 +                    );
 +                }
 +
 +                GroupLayout jPanel14Layout = new GroupLayout(jPanel14);
 +                jPanel14.setLayout(jPanel14Layout);
 +                jPanel14Layout.setHorizontalGroup(
 +                    jPanel14Layout.createParallelGroup()
 +                        .add(jPanel14Layout.createSequentialGroup()
 +                            .addContainerGap()
 +                            .add(jPanel15, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                            .addContainerGap(129, Short.MAX_VALUE))
 +                );
 +                jPanel14Layout.setVerticalGroup(
 +                    jPanel14Layout.createParallelGroup()
 +                        .add(jPanel14Layout.createSequentialGroup()
 +                            .add(28, 28, 28)
 +                            .add(jPanel15, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
 +                            .addContainerGap(153, Short.MAX_VALUE))
 +                );
 +            }
 +            tabbedPane.addTab("Proxy", jPanel14);
++=======
+                             jPanel15Layout.createParallelGroup()
+                                     .add(jPanel15Layout.createSequentialGroup()
+                                             .addContainerGap()
+                                             .add(jPanel15Layout.createParallelGroup()
+                                             .add(jPanel17, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                             .add(jPanel15Layout.createSequentialGroup()
+                                                     .add(jPanel16, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                                     .add(33, 33, 33))
+                                             .add(jPanel15Layout.createSequentialGroup()
+                                             .add(label3, GroupLayout.PREFERRED_SIZE, 674, GroupLayout.PREFERRED_SIZE)
+                                             .addContainerGap())))
+                                     .add(jPanel15Layout.createSequentialGroup()
+                                     .add(17, 17, 17)
+                                     .add(clearAllProxyButton)
+                                     .addContainerGap(667, Short.MAX_VALUE))
+                     );
+                     jPanel15Layout.setVerticalGroup(
+                             jPanel15Layout.createParallelGroup()
+                                     .add(jPanel15Layout.createSequentialGroup()
+                                     .add(label3, GroupLayout.PREFERRED_SIZE, 82, GroupLayout.PREFERRED_SIZE)
+                                     .addPreferredGap(LayoutStyle.RELATED)
+                                     .add(jPanel17, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                     .add(18, 18, 18)
+                                     .add(jPanel16, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                     .add(32, 32, 32)
+                                     .add(clearAllProxyButton)
+                                     .add(87, 87, 87))
+                     );
+                 }
+                 proxyPanel.add(jPanel15);
+             }
+             tabbedPane.addTab("Proxy", proxyPanel);
++>>>>>>> upstream/1.5.56
  
          }
          contentPane.add(tabbedPane, BorderLayout.CENTER);
@@@ -1820,9 -1844,6 +3292,6 @@@
                  }
              }
  
-             // Clear the map that holds recents preference changes
-             updatedPreferenceMap.clear();
- 
              checkForSAMChanges();
  
              // Overlays
@@@ -1835,9 -1856,11 +3304,14 @@@
                  IGVHttpUtils.updateProxySettings();
              }
  
++<<<<<<< HEAD
++=======
+             updatedPreferenceMap.clear();
++>>>>>>> upstream/1.5.56
  
              IGVMainFrame.getInstance().repaint();
              setVisible(false);
+ 
          } else {
              resetValidation();
          }
@@@ -1923,11 -1946,10 +3397,10 @@@
      }//GEN-LAST:event_samMaxLevelFieldFocusLost
  
      private void samMaxLevelFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_samMaxLevelFieldActionPerformed
-         String maxLevelString = samMaxLevelField.getText().trim();
+         String maxLevelString = samMaxLevelsField.getText().trim();
          try {
              Integer.parseInt(maxLevelString);
-             updatedPreferenceMap.put(PreferenceManager.SAMPreferences.MAX_LEVELS,
-                     maxLevelString);
+             updatedPreferenceMap.put(PreferenceManager.SAMPreferences.MAX_LEVELS, maxLevelString);
          } catch (NumberFormatException numberFormatException) {
              inputValidated = false;
              MessageUtils.showMessage("Maximum read depth must be an integer.");
@@@ -1959,15 -1981,14 +3432,18 @@@
          updatedPreferenceMap.put(
                  PreferenceManager.SAMPreferences.SHOW_SOFT_CLIPPED,
                  String.valueOf(showSoftClippedCB.isSelected()));
++<<<<<<< HEAD
 +     }
++=======
+     }
++>>>>>>> upstream/1.5.56
  
  
      private void samMaxWindowSizeFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_samMaxWindowSizeFieldFocusLost
          String maxSAMWindowSize = samMaxWindowSizeField.getText().trim();
          try {
              Float.parseFloat(maxSAMWindowSize);
-             updatedPreferenceMap.put(PreferenceManager.SAMPreferences.MAX_VISIBLE_RANGE,
-                     maxSAMWindowSize);
+             updatedPreferenceMap.put(PreferenceManager.SAMPreferences.MAX_VISIBLE_RANGE, maxSAMWindowSize);
          } catch (NumberFormatException numberFormatException) {
              inputValidated = false;
              MessageUtils.showMessage("Visibility range must be a number.");
@@@ -1978,8 -1999,7 +3454,7 @@@
          String maxSAMWindowSize = String.valueOf(samMaxWindowSizeField.getText());
          try {
              Float.parseFloat(maxSAMWindowSize);
-             updatedPreferenceMap.put(PreferenceManager.SAMPreferences.MAX_VISIBLE_RANGE,
-                     maxSAMWindowSize);
+             updatedPreferenceMap.put(PreferenceManager.SAMPreferences.MAX_VISIBLE_RANGE, maxSAMWindowSize);
          } catch (NumberFormatException numberFormatException) {
              inputValidated = false;
              MessageUtils.showMessage("Visibility range must be a number.");
@@@ -2250,7 -2270,7 +3725,11 @@@
          // TODO add your handling code here:
          PreferenceManager prefMgr = PreferenceManager.getInstance();
          genomeServerURLTextField.setEnabled(true);
++<<<<<<< HEAD
 +        genomeServerURLTextField.setText(UIConstants.DEFAULT_SERVER_GENOME_ARCHIVE_LIST);
++=======
+         genomeServerURLTextField.setText(PreferenceManager.DEFAULT_GENOME_SERVER_URL);
++>>>>>>> upstream/1.5.56
          updatedPreferenceMap.put(PreferenceManager.GENOMES_SEQUENCE_URL, null);
          dataServerURLTextField.setEnabled(true);
          dataServerURLTextField.setText(PreferenceManager.DEFAULT_DATA_SERVER_URL);
@@@ -2273,7 -2293,7 +3752,11 @@@
          showDatarangeCBActionPerformed(null);
      }//GEN-LAST:event_showDatarangeCBFocusLost
  
++<<<<<<< HEAD
 +    private void snpThresholdFieldActionPerformed(java.awt.event.ActionEvent evt) {                                                  
++=======
+     private void snpThresholdFieldActionPerformed(java.awt.event.ActionEvent evt) {
++>>>>>>> upstream/1.5.56
          String snpThreshold = snpThresholdField.getText().trim();
          try {
              Double.parseDouble(snpThreshold);
@@@ -2284,11 -2304,11 +3767,19 @@@
          }
      }
  
++<<<<<<< HEAD
 +    private void snpThresholdFieldFocusLost(java.awt.event.FocusEvent evt) {                                            
 +        snpThresholdFieldActionPerformed(null);
 +    }
 +
 +    private void normalizeCoverageCBActionPerformed(java.awt.event.ActionEvent evt) {                                                    
++=======
+     private void snpThresholdFieldFocusLost(java.awt.event.FocusEvent evt) {
+         snpThresholdFieldActionPerformed(null);
+     }
+ 
+     private void normalizeCoverageCBActionPerformed(java.awt.event.ActionEvent evt) {
++>>>>>>> upstream/1.5.56
          updatedPreferenceMap.put(PreferenceManager.NORMALIZE_COVERAGE, String.valueOf(normalizeCoverageCB.isSelected()));
          portField.setEnabled(enablePortCB.isSelected());
  
@@@ -2297,7 -2317,7 +3788,11 @@@
  
      // Proxy settings
  
++<<<<<<< HEAD
 +    private void useProxyCBActionPerformed(java.awt.event.ActionEvent evt) {                                           
++=======
+     private void useProxyCBActionPerformed(java.awt.event.ActionEvent evt) {
++>>>>>>> upstream/1.5.56
          proxySettingsChanged = true;
          boolean useProxy = useProxyCB.isSelected();
          boolean authenticateProxy = authenticateProxyCB.isSelected();
@@@ -2308,7 -2328,7 +3803,11 @@@
      }
  
  
++<<<<<<< HEAD
 +    private void authenticateProxyCBActionPerformed(java.awt.event.ActionEvent evt) {                                                    
++=======
+     private void authenticateProxyCBActionPerformed(java.awt.event.ActionEvent evt) {
++>>>>>>> upstream/1.5.56
          proxySettingsChanged = true;
          boolean useProxy = useProxyCB.isSelected();
          boolean authenticateProxy = authenticateProxyCB.isSelected();
@@@ -2321,24 -2341,27 +3820,47 @@@
  
      // Host
  
++<<<<<<< HEAD
 +    private void proxyHostFieldFocusLost(java.awt.event.FocusEvent evt) {                                         
 +        proxyHostFieldActionPerformed(null);
 +    }
 +
 +    private void proxyHostFieldActionPerformed(java.awt.event.ActionEvent evt) {                                               
++=======
+     private void proxyHostFieldFocusLost(java.awt.event.FocusEvent evt) {
+         proxyHostFieldActionPerformed(null);
+     }
+ 
+     private void proxyHostFieldActionPerformed(java.awt.event.ActionEvent evt) {
++>>>>>>> upstream/1.5.56
          proxySettingsChanged = true;
          updatedPreferenceMap.put(PreferenceManager.PROXY_HOST, proxyHostField.getText());
      }
  
++<<<<<<< HEAD
 +    private void proxyPortFieldFocusLost(java.awt.event.FocusEvent evt) {                                         
 +        proxyPortFieldActionPerformed(null);
 +    }
 +
 +    private void proxyPortFieldActionPerformed(java.awt.event.ActionEvent evt) {                                               
 +        try {
 +            Integer.parseInt(proxyPortField.getText());
 +            proxySettingsChanged = true;
 +            updatedPreferenceMap.put(PreferenceManager.PROXY_PORT, proxyPortField.getText());
++=======
+     private void proxyPortFieldFocusLost(java.awt.event.FocusEvent evt) {
+         proxyPortFieldActionPerformed(null);
+     }
+ 
+     private void proxyPortFieldActionPerformed(java.awt.event.ActionEvent evt) {
+         try {
+             if (proxyPortField.getText().trim().length() > 0) {
+                 Integer.parseInt(proxyPortField.getText());
+             }
+             proxySettingsChanged = true;
+             updatedPreferenceMap.put(PreferenceManager.PROXY_PORT, proxyPortField.getText());
+ 
++>>>>>>> upstream/1.5.56
          }
          catch (NumberFormatException e) {
              MessageUtils.showMessage("Proxy port must be an integer.");
@@@ -2360,11 -2383,11 +3882,19 @@@
  
      // Password
  
++<<<<<<< HEAD
 +    private void proxyPasswordFieldFocusLost(java.awt.event.FocusEvent evt) {                                             
 +        proxyPasswordFieldActionPerformed(null);
 +    }
 +
 +    private void proxyPasswordFieldActionPerformed(java.awt.event.ActionEvent evt) {                                               
++=======
+     private void proxyPasswordFieldFocusLost(java.awt.event.FocusEvent evt) {
+         proxyPasswordFieldActionPerformed(null);
+     }
+ 
+     private void proxyPasswordFieldActionPerformed(java.awt.event.ActionEvent evt) {
++>>>>>>> upstream/1.5.56
          proxySettingsChanged = true;
          String pw = proxyPasswordField.getText();
          String pwEncoded = Utilities.base64Encode(pw);
@@@ -2434,7 -2457,7 +3964,7 @@@
  
          PreferenceManager.SAMPreferences samPrefs = prefManager.getSAMPreferences();
          samMaxWindowSizeField.setText(String.valueOf(samPrefs.getMaxVisibleRange()));
-         samMaxLevelField.setText(String.valueOf(samPrefs.getMaxLevels()));
+         samMaxLevelsField.setText(String.valueOf(samPrefs.getMaxLevels()));
          mappingQualityThresholdField.setText((String.valueOf(samPrefs.getQualityThreshold())));
          insertSizeThresholdField.setText((String.valueOf(samPrefs.getInsertSizeThreshold())));
          snpThresholdField.setText((String.valueOf(samPrefs.getAlleleFreqThreshold())));
@@@ -2451,11 -2474,6 +3981,14 @@@
          samMaxBaseQualityField.setEnabled(samShadeMismatchedBaseCB.isSelected());
          shadeCenterCB.setSelected(samPrefs.isShadeCenter());
          showCovTrackCB.setSelected(samPrefs.isShowCoverageTrack());
++<<<<<<< HEAD
 +        initialSamMaxLevel = samPrefs.getMaxLevels();
 +        initialSamQualityThreshold = samPrefs.getQualityThreshold();
 +        initialShowDuplicates = samPrefs.isShowDuplicates();
 +        initialFilterFailedReads = samPrefs.isFilterFailedReads();
 +        initialAlleleFreqThreshold = samPrefs.getAlleleFreqThreshold();
++=======
++>>>>>>> upstream/1.5.56
          filterCB.setSelected(samPrefs.isFilterAlignments());
          if (samPrefs.getFilterURL() != null) {
              filterURL.setText(samPrefs.getFilterURL());
@@@ -2471,10 -2489,10 +4004,17 @@@
  
          boolean useProxy = prefMgr.getBooleanPreference(PreferenceManager.USE_PROXY, false);
          useProxyCB.setSelected(useProxy);
++<<<<<<< HEAD
++
++        boolean authenticateProxy = prefMgr.getBooleanPreference(PreferenceManager.PROXY_AUTHENTICATE, false);
++        authenticateProxyCB.setSelected(authenticateProxy);
++
++=======
  
          boolean authenticateProxy = prefMgr.getBooleanPreference(PreferenceManager.PROXY_AUTHENTICATE, false);
          authenticateProxyCB.setSelected(authenticateProxy);
  
++>>>>>>> upstream/1.5.56
          proxyHostField.setText(prefMgr.get(PreferenceManager.PROXY_HOST, ""));
          proxyPortField.setText(prefMgr.get(PreferenceManager.PROXY_PORT, ""));
          proxyUsernameField.setText(prefMgr.get(PreferenceManager.PROXY_USER, ""));
@@@ -2487,18 -2505,16 +4027,31 @@@
      private void checkForSAMChanges() {
          WaitCursorManager.CursorToken token = WaitCursorManager.showWaitCursor();
          try {
++<<<<<<< HEAD
 +            int maxLevel = Integer.parseInt(samMaxLevelField.getText());
 +            int qualThreshold = Integer.parseInt(mappingQualityThresholdField.getText());
 +            boolean showDoops = !samFilterDuplicatesCB.isSelected();
 +            boolean filterFailedReads = filterFailedReadsCB.isSelected();
 +            if (maxLevel > initialSamMaxLevel || qualThreshold != initialSamQualityThreshold ||
 +                    showDoops != initialShowDuplicates  ||
 +                    filterFailedReads != initialFilterFailedReads) {
 +
 +                IGVMainFrame.getInstance().getTrackManager().reloadSAMTracks();
 +                IGVMainFrame.getInstance().repaint();
 +
 +
++=======
+             boolean reloadSAM = false;
+             for (String key : SAM_PREFERENCE_KEYS) {
+                 if (updatedPreferenceMap.containsKey(key)) {
+                     reloadSAM = true;
+                     break;
+                 }
+             }
+             if (reloadSAM) {
+                 IGVMainFrame.getInstance().getTrackManager().reloadSAMTracks();
+                 IGVMainFrame.getInstance().repaint();
++>>>>>>> upstream/1.5.56
              }
          } catch (NumberFormatException numberFormatException) {
          } finally {
@@@ -2596,7 -2612,7 +4149,11 @@@
      private JPanel alignmentPanel;
      private JPanel jPanel1;
      private JPanel jPanel11;
++<<<<<<< HEAD
 +    private JTextField samMaxLevelField;
++=======
+     private JTextField samMaxLevelsField;
++>>>>>>> upstream/1.5.56
      private JTextField snpThresholdField;
      private JLabel jLabel11;
      private JLabel jLabel26;
@@@ -2650,7 -2666,7 +4207,11 @@@
      private JPanel jPanel9;
      private JCheckBox useByteRangeCB;
      private JLabel jLabel25;
++<<<<<<< HEAD
 +    private JPanel jPanel14;
++=======
+     private JPanel proxyPanel;
++>>>>>>> upstream/1.5.56
      private JPanel jPanel15;
      private JPanel jPanel16;
      private JTextField proxyUsernameField;
@@@ -2664,6 -2680,8 +4225,11 @@@
      private JLabel jLabel27;
      private JLabel jLabel23;
      private JCheckBox useProxyCB;
++<<<<<<< HEAD
++=======
+     private JLabel label3;
+     private JButton clearAllProxyButton;
++>>>>>>> upstream/1.5.56
      private ButtonPanel okCancelButtonPanel;
      private JButton okButton;
      private JButton cancelButton;
@@@ -2672,4 -2690,22 +4238,22 @@@
      public boolean isCanceled() {
          return canceled;
      }
+ 
+ 
+     /**
+      * List of keys that affect the alignments loaded.  This list is used to trigger a reload, if required.
+      * Not all alignment preferences need trigger a reload, this is a subset.
+      */
+     static java.util.List<String> SAM_PREFERENCE_KEYS = Arrays.asList(
+             PreferenceManager.SAMPreferences.MAX_VISIBLE_RANGE,
+             PreferenceManager.SAMPreferences.SHOW_ZERO_QUALITY,
+             PreferenceManager.SAMPreferences.SHOW_DUPLICATES,
+             PreferenceManager.SAMPreferences.SHOW_SOFT_CLIPPED,
+             PreferenceManager.SAMPreferences.MAX_LEVELS,
+             PreferenceManager.SAMPreferences.MAX_READS,
+             PreferenceManager.SAMPreferences.ALLELE_THRESHOLD,
+             PreferenceManager.SAMPreferences.QUALITY_THRESHOLD,
+             PreferenceManager.SAMPreferences.FILTER_ALIGNMENTS,
+             PreferenceManager.SAMPreferences.FILTER_URL,
+             PreferenceManager.SAMPreferences.FILTER_FAILED_READS);
  }
diff --combined src/org/broad/igv/ui/PreferencesEditor.jfd
index 08569cb,9fc2a1d..f15358b
--- a/src/org/broad/igv/ui/PreferencesEditor.jfd
+++ b/src/org/broad/igv/ui/PreferencesEditor.jfd
@@@ -1,5 -1,5 +1,9 @@@
  <?xml version="1.0" encoding="UTF-8"?> 
++<<<<<<< HEAD
 +<java version="1.6.0_17" class="java.beans.XMLDecoder"> 
++=======
+ <java version="1.6.0_20" class="java.beans.XMLDecoder"> 
++>>>>>>> upstream/1.5.56
   <object class="com.jformdesigner.model.FormModel"> 
    <void property="contentType"> 
     <string>form/swing</string> 
@@@ -1119,7 -1119,7 +1123,11 @@@
                   <string>jTextField1</string> 
                  </void> 
                  <void property="name"> 
++<<<<<<< HEAD
 +                 <string>samMaxLevelField</string> 
++=======
+                  <string>samMaxLevelsField</string> 
++>>>>>>> upstream/1.5.56
                  </void> 
                  <void method="addEvent"> 
                   <object class="com.jformdesigner.model.FormEvent"> 
@@@ -1341,7 -1341,7 +1349,11 @@@
                  <string>javax.swing.JLabel</string> 
                  <void method="setProperty"> 
                   <string>text</string> 
++<<<<<<< HEAD
 +                 <string>&lt;html&gt;&lt;i&gt;Maximum number of rows of alignments to display.</string> 
++=======
+                  <string>&lt;html&gt;&lt;i&gt;Maximum depth of reads to display.</string> 
++>>>>>>> upstream/1.5.56
                  </void> 
                  <void property="name"> 
                   <string>jLabel14</string> 
@@@ -1415,7 -1415,7 +1427,11 @@@
                  <string>javax.swing.JLabel</string> 
                  <void method="setProperty"> 
                   <string>text</string> 
++<<<<<<< HEAD
 +                 <string>Maximum read depth</string> 
++=======
+                  <string>Maximum read depth:</string> 
++>>>>>>> upstream/1.5.56
                  </void> 
                  <void property="name"> 
                   <string>jLabel13</string> 
@@@ -2682,18 -2682,10 +2698,25 @@@
           <object class="com.jformdesigner.model.FormContainer"> 
            <string>javax.swing.JPanel</string> 
            <object class="com.jformdesigner.model.FormLayoutManager"> 
++<<<<<<< HEAD
 +           <class>org.jdesktop.layout.GroupLayout</class> 
 +           <void method="setProperty"> 
 +            <string>$horizontalGroup</string> 
 +            <string>par l {seq l {space :::p, comp jPanel15:::p::p, space ::129:x}}</string> 
 +           </void> 
 +           <void method="setProperty"> 
 +            <string>$verticalGroup</string> 
 +            <string>par l {seq l {space :p:28:p, comp jPanel15:::p::p, space ::153:x}}</string> 
 +           </void> 
 +          </object> 
 +          <void property="name"> 
 +           <string>jPanel14</string> 
++=======
+            <class>javax.swing.BoxLayout</class> 
+           </object> 
+           <void property="name"> 
+            <string>proxyPanel</string> 
++>>>>>>> upstream/1.5.56
            </void> 
            <void method="add"> 
             <object class="com.jformdesigner.model.FormContainer"> 
@@@ -2702,11 -2694,11 +2725,19 @@@
               <class>org.jdesktop.layout.GroupLayout</class> 
               <void method="setProperty"> 
                <string>$horizontalGroup</string> 
++<<<<<<< HEAD
 +              <string>par l {seq l {space :::p, par l {seq l {comp jPanel17:::p::p:1, space :::p}, seq l {comp jPanel16:::::x:1, space :33:33:p}}}}</string> 
 +             </void> 
 +             <void method="setProperty"> 
 +              <string>$verticalGroup</string> 
 +              <string>par l {seq {space :p:16:p, comp jPanel17:::p::p, space s:::p, comp jPanel16:::::x, space :p:39:p}}</string> 
++=======
+               <string>par l {seq {space :::p, par l {comp jPanel17::l:p::p:1, seq l {comp jPanel16:::::x:1, space :33:33:p}, seq l {comp label3:::p:674:p, space :::p}}}, seq l {space :p:17:p, comp clearAllProxyButton:::p::p, space ::667:x}}</string> 
+              </void> 
+              <void method="setProperty"> 
+               <string>$verticalGroup</string> 
+               <string>par l {seq {comp label3:::p:82:p, space :::p, comp jPanel17:::p::p, space s:::p, comp jPanel16:::::x, space :p:32:p, comp clearAllProxyButton:::p::p, space :p:87:p}}</string> 
++>>>>>>> upstream/1.5.56
               </void> 
              </object> 
              <void property="name"> 
@@@ -2719,7 -2711,7 +2750,11 @@@
                 <class>org.jdesktop.layout.GroupLayout</class> 
                 <void method="setProperty"> 
                  <string>$horizontalGroup</string> 
++<<<<<<< HEAD
 +                <string>par l {seq {par l {seq {space :p:28:p, par l {comp jLabel28::l:p::p, comp jLabel29::l:p::p}, space :p:37:p, par l:::p {comp proxyPasswordField:::::x:1, comp proxyUsernameField::l::261:x:1}}, seq l {space :::p, comp authenticateProxyCB:::p::p}}, space ::219:x}}</string> 
++=======
+                 <string>par l {seq {par l {seq {space :p:28:p, par l {comp jLabel28::l:p::p, comp jLabel29::l:p::p}, space :p:37:p, par l:::p {comp proxyPasswordField:::::x:1, comp proxyUsernameField::l::261:x:1}}, seq l {space :::p, comp authenticateProxyCB:::p::p}}, space ::354:x}}</string> 
++>>>>>>> upstream/1.5.56
                 </void> 
                 <void method="setProperty"> 
                  <string>$verticalGroup</string> 
@@@ -2743,6 -2735,22 +2778,25 @@@
                  <void property="name"> 
                   <string>proxyUsernameField</string> 
                  </void> 
++<<<<<<< HEAD
++=======
+                 <void method="addEvent"> 
+                  <object class="com.jformdesigner.model.FormEvent"> 
+                   <string>java.awt.event.ActionListener</string> 
+                   <string>actionPerformed</string> 
+                   <string>proxyUsernameFieldActionPerformed</string> 
+                   <boolean>true</boolean> 
+                  </object> 
+                 </void> 
+                 <void method="addEvent"> 
+                  <object class="com.jformdesigner.model.FormEvent"> 
+                   <string>java.awt.event.FocusListener</string> 
+                   <string>focusLost</string> 
+                   <string>proxyUsernameFieldFocusLost</string> 
+                   <boolean>true</boolean> 
+                  </object> 
+                 </void> 
++>>>>>>> upstream/1.5.56
                 </object> 
                </void> 
                <void method="add"> 
@@@ -2930,6 -2938,38 +2984,41 @@@
                </void> 
               </object> 
              </void> 
++<<<<<<< HEAD
++=======
+             <void method="add"> 
+              <object class="com.jformdesigner.model.FormComponent"> 
+               <string>javax.swing.JLabel</string> 
+               <void method="setProperty"> 
+                <string>text</string> 
+                <string>&lt;html&gt;Note:  do not use these settings unless you receive error or warning messages about server connections.  On most systems the correct settings will be automatically copied from your web browser.</string> 
+               </void> 
+               <void property="name"> 
+                <string>label3</string> 
+               </void> 
+              </object> 
+             </void> 
+             <void method="add"> 
+              <object class="com.jformdesigner.model.FormComponent"> 
+               <string>javax.swing.JButton</string> 
+               <void method="setProperty"> 
+                <string>text</string> 
+                <string>Clear All</string> 
+               </void> 
+               <void property="name"> 
+                <string>clearAllProxyButton</string> 
+               </void> 
+               <void method="addEvent"> 
+                <object class="com.jformdesigner.model.FormEvent"> 
+                 <string>java.awt.event.ActionListener</string> 
+                 <string>actionPerformed</string> 
+                 <string>clearAllProxyButtonActionPerformed</string> 
+                 <boolean>true</boolean> 
+                </object> 
+               </void> 
+              </object> 
+             </void> 
++>>>>>>> upstream/1.5.56
             </object> 
            </void> 
           </object> 
diff --combined src/org/broad/igv/ui/ShutdownThread.java
index 4b9b76b,fa8c6e4..180de2a
--- a/src/org/broad/igv/ui/ShutdownThread.java
+++ b/src/org/broad/igv/ui/ShutdownThread.java
@@@ -17,10 -17,7 +17,7 @@@
   */
  package org.broad.igv.ui;
  
- //~--- non-JDK imports --------------------------------------------------------
  
- import ncsa.hdf.hdf5lib.H5;
- import ncsa.hdf.hdf5lib.exceptions.HDF5LibraryException;
  import org.apache.log4j.Logger;
  import org.broad.igv.h5.HDF5RemoteReader;
  
@@@ -41,30 -38,25 +38,51 @@@ public class ShutdownThread extends Thr
       */
      @Override
      public void run() {
++<<<<<<< HEAD
 +        try {
 +
 +            // Release local and remote HDF5 resources
 +            log.info("Closing HDF5");
 +            H5.H5close();
 +            HDF5RemoteReader.shutdown();
 +
 +            // Cleanup jnlp files
 +            if (UIConstants.IS_MAC) {
 +                File desktop = new File(System.getProperty("user.home") + "/Desktop");
 +                if (desktop.exists() && desktop.isDirectory()) {
 +                    cleanupJnlpFiles(desktop);
 +                }
 +                File downloads = new File(System.getProperty("user.home") + "/Downloads");
 +                if (downloads.exists() && downloads.isDirectory()) {
 +                    cleanupJnlpFiles(downloads);
 +                }
++=======
++>>>>>>> upstream/1.5.56
  
+         // Release local and remote HDF5 resources
+         //log.info("Closing HDF5");
+         //H5.H5close();
+         HDF5RemoteReader.shutdown();
+ 
+         // Cleanup jnlp files
+         if (UIConstants.IS_MAC) {
+             File desktop = new File(System.getProperty("user.home") + "/Desktop");
+             if (desktop.exists() && desktop.isDirectory()) {
+                 cleanupJnlpFiles(desktop);
              }
++<<<<<<< HEAD
 +        } catch (HDF5LibraryException ex) {
 +            // Ignore these, unimportant
 +            log.info("HDF5 not properly shut down.  Unsupported platform?");
++=======
+             File downloads = new File(System.getProperty("user.home") + "/Downloads");
+             if (downloads.exists() && downloads.isDirectory()) {
+                 cleanupJnlpFiles(downloads);
+             }
++>>>>>>> upstream/1.5.56
  
          }
+ 
      }
  
      /**
diff --combined src/org/broad/igv/ui/UIConstants.java
index 3024c44,3bf3b0b..cb04dd9
--- a/src/org/broad/igv/ui/UIConstants.java
+++ b/src/org/broad/igv/ui/UIConstants.java
@@@ -28,10 -28,12 +28,19 @@@ import org.broad.igv.Globals
  import org.broad.igv.exceptions.DataLoadException;
  import org.broad.igv.track.TrackType;
  
++<<<<<<< HEAD
 +import javax.swing.filechooser.FileSystemView;
 +import java.awt.*;
 +import java.io.File;
 +import java.util.Properties;
++=======
+ import javax.swing.*;
+ import javax.swing.filechooser.FileSystemView;
+ import java.awt.*;
+ import java.io.File;
+ import java.io.IOException;
+ import java.util.prefs.Preferences;
++>>>>>>> upstream/1.5.56
  
  /**
   * @author jrobinso
@@@ -43,61 -45,31 +52,88 @@@ public class UIConstants 
       * Field description
       */
      final public static int groupGap = 10;
++<<<<<<< HEAD
 +    /**
 +     * Field description
 +     */
 +    final public static String APPLICATION_NAME = "IGV";
 +    /**
 +     * Field description
 +     */
 +    final public static String APPLICATION_LONG_NAME = "Integrative Genomics Viewer";
 +    /**
 +     * Field description
 +     */
 +    final public static boolean IS_WINDOWS =
 +            System.getProperty("os.name").toLowerCase().startsWith("windows");
 +    /**
 +     * Field description
 +     */
 +    final public static boolean IS_MAC =
 +            System.getProperty("os.name").toLowerCase().startsWith("mac");
 +    /**
 +     * Field description
 +     */
 +    final public static boolean IS_LINUX =
 +            System.getProperty("os.name").toLowerCase().startsWith("linux");
 +    /**
 +     * Field description
 +     */
 +    final public static Dimension preferredSize = new Dimension(1000, 750);
 +    // To support mutation track overlay.  Generalize later.  Cancer specific option.
 +    public static TrackType overlayTrackType = TrackType.MUTATION;
 +    // Default user folder
 +    /**
 +     * Field description
 +     */
 +    private static String DEFAULT_USER_DIRECTORY;
 +
 +
 +    private static int doubleClickInterval = -1;
 +    // General
 +    final static public String CLICK_ITEM_TO_EDIT_TOOLTIP = "Click this item bring up its editor";// Toolbar Menu Item Tooltips
 +    final static public String JUMP_TO_WHOLE_GENOME_VIEW_TOOLTIP = "Jump to whole genome view";
 +    final static public String JUMP_TO_LOCUS_TOOLTIP = "Jump to Gene or Locus";
 +    final static public String SELECT_CHROMOSOME_TOOLTIP = "Select a chromosome to view";
 +    final static public String ZOOM_TOOL_TOOLTIP = "Click + to zoom in - Click - to zoom out";// File Menu Item Tooltips
 +    final static public String LOAD_TRACKS_TOOLTIP = "Load data, features or sample information";
 +    final static public String LOAD_SERVER_DATA_TOOLTIP = "Load data, features or sample information from a server";
 +    final static public String LOAD_ATTRIBUTES_TOOLTIP = "Load track attributes";
 +    final static public String SAVE_IMAGE_TOOLTIP = "Capture and save an image";
 +    final static public String NEW_SESSION_TOOLTIP = "Create a new session";
 +    final static public String SAVE_SESSION_TOOLTIP = "Save the current session";
 +    final static public String SAVE_SESSION_AS_TOOLTIP = "Save the current session to the specified file";
++=======
+     final public static String APPLICATION_NAME = "IGV";
+     final public static String APPLICATION_LONG_NAME = "Integrative Genomics Viewer";
+     final public static boolean IS_WINDOWS =
+             System.getProperty("os.name").toLowerCase().startsWith("windows");
+     final public static boolean IS_MAC =
+             System.getProperty("os.name").toLowerCase().startsWith("mac");
+     final public static boolean IS_LINUX =
+             System.getProperty("os.name").toLowerCase().startsWith("linux");
+     final public static Dimension preferredSize = new Dimension(1000, 750);
+ 
+     // To support mutation track overlay.  Generalize later.  Cancer specific option.
+     public static TrackType overlayTrackType = TrackType.MUTATION;
+ 
+     private static int doubleClickInterval = -1;
+     // General
+     final static public String CLICK_ITEM_TO_EDIT_TOOLTIP = "Click this item bring up its editor";
+     final static public String LOAD_TRACKS_TOOLTIP = "Load data, features or sample information";
+     final static public String LOAD_SERVER_DATA_TOOLTIP = "Load data, features or sample information from a server";
+     final static public String SAVE_IMAGE_TOOLTIP = "Capture and save an image";
+     final static public String NEW_SESSION_TOOLTIP = "Create a new session";
+     final static public String SAVE_SESSION_TOOLTIP = "Save the current session";
++>>>>>>> upstream/1.5.56
      final static public String RESTORE_SESSION_TOOLTIP = "Reload the named session";
      final static public String EXIT_TOOLTIP = "Exit the application";
      final static public String EXPORT_REGION_TOOLTIP = "Allows currently selected regions to be exported to a file";
      final static public String IMPORT_REGION_TOOLTIP = "Allows previously exported regions to be reloaded";
++<<<<<<< HEAD
 +    final static public String CLEAR_REGION_TOOLTIP = "Clear all regions of interest";// Edit Menu Item Tooltips
++=======
++>>>>>>> upstream/1.5.56
      final static public String CHANGE_GENOME_TOOLTIP = "Switch the current genome";
      final static public String IMPORT_GENOME_TOOLTIP =
              "Create a user-defined genome and makes it available for use in the application";
@@@ -106,137 -78,203 +142,337 @@@
      final static public String REMOVE_USER_DEFINE_GENOME_TOOLTIP =
              "Removes user-defined genomes from the drop-down list";
      final static public String CLEAR_GENOME_CACHE_TOOLTIP =
++<<<<<<< HEAD
 +            "Clears locally cached versions of IGV hosted genomes.";// IGVPanel Menu Item Tooltips
 +    final static public String PREFERENCE_TOOLTIP =
 +            "Set user specific preferences";
 +    final static public String SHOW_ATTRIBUTE_DISPLAY_TOOLTIP =
 +            "Show or hide the attribute display";
 +    final static public String ENABLE_REGIONS_OF_INTEREST_TOOLTIP =
 +            "Enable the \"Region of Interest\" tool";
 +    final static public String REFRESH_TOOLTIP =
 +            "Refresh the application's display";
 +    final static public String SHOW_HEATMAP_LEGEND_TOOLTIP =
 +            "IGVPanel or edit color legends and scales";
 +    final static public String SELECT_DISPLAYABLE_ATTRIBUTES_TOOLTIP =
 +            "Customize attribute display to show only checked attributes";
 +    final static public String USE_IMAGE_CACHING_TOOLTIP =
 +            "Use image caching to improve display performance";
 +    final static public String DIRECT_DRAW_DISABLED_TOOLTIP =
 +            "Checked this item to prevent the use of direct draw" +
 +                    " when rendering images - Uncheck it to use the default system behavior";// Tracks Menu Item Tooltips
 +    final static public String SORT_TRACKS_TOOLTIP =
 +            "Sort tracks by attribute value";
 +    final static public String GROUP_TRACKS_TOOLTIP =
 +            "Group tracks";
 +    final static public String FILTER_TRACKS_TOOLTIP =
 +            "Filter tracks by attribute value";
 +    final static public String RESET_DEFAULT_TRACK_HEIGHT_TOOLTIP =
 +            "Reset all track to the default track height";
 +    final static public String SET_DEFAULT_TRACK_HEIGHT_TOOLTIP =
 +            "Set the height for all tracks";
 +    final static public String FIT_DATA_TO_WINDOW_TOOLTIP =
 +            "Resizes all track heights in order to make all tracks visible in " +
 +                    "their display with no vertical scrolling";// Help Menu Item Tooltips
 +    final static public String HELP_TOOLTIP =
 +            "Open web help page";
 +    final static public String TUTORIAL_TOOLTIP =
 +            "Open tutorial web page";
 +    final static public String ABOUT_TOOLTIP =
 +            "Display application information";// Tool Menu
 +    final static public String MACRO_SNAPSHOTS =
 +            "Macro Snapshots";
 +    final static public String RESET_FACTORY_TOOLTIP =
 +            "Restores all user preferences to their default settings.";
 +
 +    public static int getDoubleClickInterval() {
 +
 +        if (doubleClickInterval < 0) {
 +            try {
 +                Number obj = (Number) Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
 +                doubleClickInterval = obj.intValue();
 +            } catch (Exception e) {
 +                log.info("Error retrieving doubleClickInterval", e);
 +                doubleClickInterval = 500;
 +            }
 +
 +        }
 +        return doubleClickInterval;
 +    }
 +
 +    public static synchronized String getDefaultUserDirectory() {
 +        if (DEFAULT_USER_DIRECTORY == null) {
 +
 +            if (UIConstants.IS_WINDOWS) {
 +                DEFAULT_USER_DIRECTORY =
 +                        FileSystemView.getFileSystemView().getDefaultDirectory().getAbsolutePath();
 +            } else {
 +                DEFAULT_USER_DIRECTORY =
 +                        FileSystemView.getFileSystemView().getDefaultDirectory().getAbsolutePath();
 +            }
 +        }
 +        return DEFAULT_USER_DIRECTORY;
 +    }
 +
 +    // Default user folder
 +    /**
 +     * Field description
 +     */
 +    final public static String DEFAULT_IGV_DIRECTORY;
 +    final public static File GENOME_CACHE_DIRECTORY;
 +    final public static File IGV_TEMP_DIRECTORY;
 +
 +    static {
 +
 +        StringBuffer path = new StringBuffer();
 +        Properties properties = System.getProperties();
 +        path.append(properties.getProperty("user.home"));
 +        path.append(properties.getProperty("file.separator"));
 +
 +        if (UIConstants.IS_MAC) {
 +            path.append(".igv");
 +        } else {
 +            path.append("igv");
 +        }
 +        DEFAULT_IGV_DIRECTORY = path.toString().trim();
 +
 +        //Check that Dir is accessible
 +        File defaultUserDirectory = new File(DEFAULT_IGV_DIRECTORY);
 +        if (!defaultUserDirectory.exists()) {
 +            defaultUserDirectory.mkdir();
 +        }
 +        if (!defaultUserDirectory.canRead()){
 +            throw new DataLoadException("Cannot read from user directory", defaultUserDirectory.getAbsolutePath());
 +        }
 +        else if (!defaultUserDirectory.canWrite()){
 +            throw new DataLoadException("Cannot write to user directory", defaultUserDirectory.getAbsolutePath());
 +        }
 +
 +        //Create the Genome Cache
 +        GENOME_CACHE_DIRECTORY = new File(DEFAULT_IGV_DIRECTORY + properties.getProperty("file.separator")
 +                + Globals.GENOME_CACHE_FOLDER_NAME);
 +        if (!GENOME_CACHE_DIRECTORY.exists()) {
 +            GENOME_CACHE_DIRECTORY.mkdir();
 +        }
 +        if (!GENOME_CACHE_DIRECTORY.canRead()){
 +            throw new DataLoadException("Cannot read from user directory", GENOME_CACHE_DIRECTORY.getAbsolutePath());
 +        }
 +        else if (!GENOME_CACHE_DIRECTORY.canWrite()){
 +            throw new DataLoadException("Cannot write to user directory", GENOME_CACHE_DIRECTORY.getAbsolutePath());
 +        }
 +
 +        //Create the Temp Directory
 +        path = new StringBuffer();
 +        path.append(System.getProperty("java.io.tmpdir"));
 +        IGV_TEMP_DIRECTORY = new File(path.toString());
 +        if (!IGV_TEMP_DIRECTORY.exists()) {
 +            IGV_TEMP_DIRECTORY.mkdir();
 +        }
 +        if (!IGV_TEMP_DIRECTORY.canRead()){
 +            throw new DataLoadException("Cannot read from user directory", IGV_TEMP_DIRECTORY.getAbsolutePath());
 +        }
 +        else if (!IGV_TEMP_DIRECTORY.canWrite()){
 +            throw new DataLoadException("Cannot write to user directory", IGV_TEMP_DIRECTORY.getAbsolutePath());
 +        }
++=======
+             "Clears locally cached versions of IGV hosted genomes.";
+     final static public String PREFERENCE_TOOLTIP = "Set user specific preferences";
+     final static public String SHOW_ATTRIBUTE_DISPLAY_TOOLTIP = "Show or hide the attribute display";
+     final static public String REFRESH_TOOLTIP = "Refresh the application's display";
+     final static public String SHOW_HEATMAP_LEGEND_TOOLTIP = "IGVPanel or edit color legends and scales";
+     final static public String SELECT_DISPLAYABLE_ATTRIBUTES_TOOLTIP = "Customize attribute display to show only checked attributes";
+     final static public String DIRECT_DRAW_DISABLED_TOOLTIP = "Checked this item to prevent the use of direct draw" +
+             " when rendering images - Uncheck it to use the default system behavior";
+     final static public String SORT_TRACKS_TOOLTIP = "Sort tracks by attribute value";
+     final static public String GROUP_TRACKS_TOOLTIP = "Group tracks";
+     final static public String FILTER_TRACKS_TOOLTIP = "Filter tracks by attribute value";
+     final static public String SET_DEFAULT_TRACK_HEIGHT_TOOLTIP = "Set the height for all tracks";
+     final static public String FIT_DATA_TO_WINDOW_TOOLTIP = "Resizes all track heights in order to make all tracks visible in " +
+             "their display with no vertical scrolling";
+     final static public String HELP_TOOLTIP = "Open web help page";
+     final static public String TUTORIAL_TOOLTIP = "Open tutorial web page";
+     final static public String ABOUT_TOOLTIP = "Display application information";
+     final static public String MACRO_SNAPSHOTS = "Macro Snapshots";
+     final static public String RESET_FACTORY_TOOLTIP = "Restores all user preferences to their default settings.";
+ 
+     private static File DEFAULT_USER_DIRECTORY;
+     private static File DEFAULT_IGV_DIRECTORY;
+     private static File GENOME_CACHE_DIRECTORY;
+     private static File IGV_TEMP_DIRECTORY;
+     public static final String IGV_DIR_USERPREF = "igvDir";
+ 
+     public static int getDoubleClickInterval() {
+ 
+         if (doubleClickInterval < 0) {
+             try {
+                 Number obj = (Number) Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
+                 doubleClickInterval = obj.intValue();
+             } catch (Exception e) {
+                 log.info("Error retrieving doubleClickInterval", e);
+                 doubleClickInterval = 500;
+             }
+ 
+         }
+         return doubleClickInterval;
+     }
+ 
+     public static synchronized File getUserDirectory() {
+         if (DEFAULT_USER_DIRECTORY == null) {
+             DEFAULT_USER_DIRECTORY = FileSystemView.getFileSystemView().getDefaultDirectory();
+         }
+         return DEFAULT_USER_DIRECTORY;
+     }
+ 
+     public static File getIgvDirectory() {
+ 
+         // Hack for know Java bug
+         if (System.getProperty("os.name").equals("Windows XP")) {
+             try {
+                 Runtime.getRuntime().exec("attrib -r \"" + getUserDirectory().getAbsolutePath() + "\"");
+             } catch (IOException e) {
+                 // Oh well, we tried
+ 
+             }
+         }
+ 
+         if (DEFAULT_IGV_DIRECTORY == null)
+ 
+         {
+ 
+             // See if an override is stored in preferences.  Try to create a directory if it is.  If there is an
+             // error (the log is likely not available yet) and try to use the standard directory
+             try {
+                 Preferences prefs = Preferences.userNodeForPackage(UIConstants.class);
+                 String userDir = prefs.get(IGV_DIR_USERPREF, null);
+                 if (userDir != null) {
+                     DEFAULT_IGV_DIRECTORY = new File(userDir);
+                     if (!DEFAULT_IGV_DIRECTORY.exists()) {
+                         DEFAULT_IGV_DIRECTORY = null;
+                         prefs.remove(IGV_DIR_USERPREF);
+                     }
+                 }
+             } catch (Exception e) {
+                 Preferences prefs = Preferences.userNodeForPackage(UIConstants.class);
+                 prefs.remove(IGV_DIR_USERPREF);
+                 System.err.println("Error creating user directory");
+                 e.printStackTrace();
+             }
+ 
+             // No overide, try the default place
+             if (DEFAULT_IGV_DIRECTORY == null) {
+                 String userHomeString = System.getProperty("user.home");
+                 File rootDir = new File(userHomeString);
+                 if (!(rootDir.exists() && canWrite(rootDir))) {
+                     rootDir = getUserDirectory();
+                 }
+                 if (UIConstants.IS_MAC) {
+                     DEFAULT_IGV_DIRECTORY = new File(rootDir, ".igv");
+                 } else {
+                     DEFAULT_IGV_DIRECTORY = new File(rootDir, "igv");
+                 }
+                 if (!DEFAULT_IGV_DIRECTORY.exists()) {
+                     try {
+                         DEFAULT_IGV_DIRECTORY.mkdir();
+                     }
+                     catch (Exception e) {
+                         System.err.println("Error creating user directory");
+                         e.printStackTrace();
+                     }
+                 }
+             }
+ 
+             // The IGV directory either doesn't exist or isn't writeable.  This situation can arise with Windows Vista
+             // and Windows 7 due to a Java bug (http://bugs.sun.com/view_bug.do?bug_id=4787931)
+             if (!(DEFAULT_IGV_DIRECTORY.exists() && DEFAULT_IGV_DIRECTORY.canRead() && canWrite(DEFAULT_IGV_DIRECTORY))) {
+                 int option = JOptionPane.showConfirmDialog(null,
+                         "<html>The default IGV directory (" + DEFAULT_IGV_DIRECTORY + ") " +
+                                 "cannot be accessed.  Click Yes to choose a new folder or No to exit.<br>" +
+                                 "This folder will be used to store user preferences and cached genomes.",
+                         "IGV Directory Error", JOptionPane.YES_NO_OPTION);
+ 
+                 if (option == JOptionPane.YES_OPTION) {
+                     final JFileChooser fc = new JFileChooser();
+                     fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+                     int retValue = fc.showOpenDialog(null);
+                     if (retValue == JFileChooser.APPROVE_OPTION) {
+                         DEFAULT_IGV_DIRECTORY = fc.getSelectedFile();
+                         Preferences prefs = Preferences.userNodeForPackage(UIConstants.class);
+                         prefs.put(IGV_DIR_USERPREF, DEFAULT_IGV_DIRECTORY.getAbsolutePath());
+                     }
+                 }
+             }
+ 
+ 
+             if (!DEFAULT_IGV_DIRECTORY.canRead()) {
+                 throw new DataLoadException("Cannot read from user directory", DEFAULT_IGV_DIRECTORY.getAbsolutePath());
+             } else if (!canWrite(DEFAULT_IGV_DIRECTORY)) {
+                 throw new DataLoadException("Cannot write to user directory", DEFAULT_IGV_DIRECTORY.getAbsolutePath());
+             }
+ 
+             System.out.println("IGV directory: " + DEFAULT_IGV_DIRECTORY);
+ 
+         }
+ 
+ 
+         return DEFAULT_IGV_DIRECTORY;
+     }
+ 
+     private static boolean canWrite(File directory) {
+         // There are bugs in Java window (targe fix is Java 7).  The only way to know for sure is to try to write something
+         if (IS_WINDOWS) {
+             File testFile = null;
+             try {
+                 testFile = new File(directory, "igv332415dsfjdsklt.testfile");
+                 if (testFile.exists()) {
+                     testFile.delete();
+                 }
+                 testFile.deleteOnExit();
+                 testFile.createNewFile();
+                 return testFile.exists();
+             } catch (IOException e) {
+                 return false;
+             } finally {
+                 if (testFile.exists()) {
+                     testFile.delete();
+                 }
+             }
+         } else {
+             return directory.canWrite();
+         }
+ 
+     }
+ 
+     public static File getGenomeCacheDirectory() {
+         if (GENOME_CACHE_DIRECTORY == null) {
+             GENOME_CACHE_DIRECTORY = new File(getIgvDirectory(), Globals.GENOME_CACHE_FOLDER_NAME);
+             if (!getGenomeCacheDirectory().exists()) {
+                 getGenomeCacheDirectory().mkdir();
+             }
+             if (!getGenomeCacheDirectory().canRead()) {
+                 throw new DataLoadException("Cannot read from user directory", getGenomeCacheDirectory().getAbsolutePath());
+             } else if (!getGenomeCacheDirectory().canWrite()) {
+                 throw new DataLoadException("Cannot write to user directory", getGenomeCacheDirectory().getAbsolutePath());
+             }
+         }
+         return GENOME_CACHE_DIRECTORY;
+     }
+ 
+     public static File getTmpDirectory() {
+         if (IGV_TEMP_DIRECTORY == null) {
+             String tmpDir = (System.getProperty("java.io.tmpdir"));
+             IGV_TEMP_DIRECTORY = new File(tmpDir);
+             if (!getTmpDirectory().exists()) {
+                 getTmpDirectory().mkdir();
+             }
+             if (!IGV_TEMP_DIRECTORY.canRead()) {
+                 throw new DataLoadException("Cannot read from user directory", getTmpDirectory().getAbsolutePath());
+             } else if (!IGV_TEMP_DIRECTORY.canWrite()) {
+                 throw new DataLoadException("Cannot write to user directory", getTmpDirectory().getAbsolutePath());
+             }
+ 
+         }
+         return IGV_TEMP_DIRECTORY;
++>>>>>>> upstream/1.5.56
      }
  
  
@@@ -250,14 -288,10 +486,21 @@@
       */
      final public static String NEW_SESSION_MESSAGE =
              "<html>Creating a new session will unload all current data. " + "<br>Are you sure you wish to continue?";
++<<<<<<< HEAD
 +    final public static String DEFAULT_SERVER_GENOME_ARCHIVE_LIST = "http://igv.broadinstitute.org/genomes/genomes.txt";
 +    final public static String CANNOT_ACCESS_SERVER_GENOME_LIST = "The Genome server is currently inaccessible.";
 +    final public static String INVALID_SERVER_GENOME_LIST_HEADER = "Genomes cannot be retrieved from the server. " + "The server-side genome list is invalid!";
 +    // Session Folder
 +    /**
 +     * Field description
 +     */
 +    final public static String SESSION_FOLDER = "/igv_sessions";
++=======
+     final public static String CANNOT_ACCESS_SERVER_GENOME_LIST = "The Genome server is currently inaccessible.";
+     final public static String INVALID_SERVER_GENOME_LIST_HEADER = "Genomes cannot be retrieved from the server. " + "The server-side genome list is invalid!";
+     // Session Folder
+ 
++>>>>>>> upstream/1.5.56
      /**
       * Field description
       */
@@@ -306,4 -340,5 +549,8 @@@
       * Field description
       */
      final static public String GENOME_LIST_SEPARATOR = "--SEPARATOR--";
++<<<<<<< HEAD
++=======
+ 
++>>>>>>> upstream/1.5.56
  }
diff --combined src/org/broad/igv/ui/action/FitDataToWindowMenuAction.java
index 821a4fc,538d5fb..b90723d
--- a/src/org/broad/igv/ui/action/FitDataToWindowMenuAction.java
+++ b/src/org/broad/igv/ui/action/FitDataToWindowMenuAction.java
@@@ -22,15 -22,15 +22,19 @@@
   */
  package org.broad.igv.ui.action;
  
- import com.jidesoft.utils.SwingWorker;
  import org.apache.log4j.Logger;
  import org.broad.igv.track.Track;
  import org.broad.igv.track.TrackGroup;
  import org.broad.igv.ui.IGVMainFrame;
  import org.broad.igv.ui.UIConstants;
 +import org.broad.igv.ui.WaitCursorManager;
  import org.broad.igv.ui.panel.DataPanel;
  import org.broad.igv.ui.panel.TrackPanelScrollPane;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.util.LongRunningTask;
+ import org.broad.igv.util.NamedRunnable;
++>>>>>>> upstream/1.5.56
  
  import java.awt.event.ActionEvent;
  import java.util.Collection;
@@@ -58,8 -58,22 +62,22 @@@ public class FitDataToWindowMenuAction 
       */
      public void actionPerformed(ActionEvent e) {
  
-         Worker worker = new Worker();
-         worker.execute();
+         NamedRunnable runnable = new NamedRunnable() {
+             public void run() {
+                 for (TrackPanelScrollPane sp : IGVMainFrame.getInstance().getTrackManager().getTrackPanelScrollPanes()) {
+                     fitTracksToPanel(sp.getDataPanel());
+                     sp.getDataPanel().doResize();
+                 }
+                 mainFrame.doRefresh();
+             }
+ 
+ 
+             public String getName() {
+                 return "Fit data to window";
+             }
+         };
+ 
+         LongRunningTask.submit(runnable);
      }
  
      /**
@@@ -126,40 -140,4 +144,43 @@@
          return success;
      }
  
++<<<<<<< HEAD
 +    /**
 +     * The worker class for this action.
 +     */
 +    class Worker<String, Void> extends SwingWorker {
 +
 +        boolean success;
 +        WaitCursorManager.CursorToken token;
 +
 +        @Override
 +        /**
 +         * This method is executed in a background thread (NOT the swing
 +         * thread).
 +         */
 +        protected Object doInBackground() throws Exception {
 +            // Process Data and Feature Tracks
 +            token = WaitCursorManager.showWaitCursor();
 +            success = false;
 +            for (TrackPanelScrollPane sp : IGVMainFrame.getInstance().getTrackManager().getTrackPanelScrollPanes()) {
 +                success = success || fitTracksToPanel(sp.getDataPanel());
 +            }
 +
 +            return success;
 +
 +        }
 +
 +        @Override
 +        /**
 +         * This method is executed in the swing thread when doInBackground 
 +         * completes.
 +         */
 +        protected void done() {
 +            WaitCursorManager.removeWaitCursor(token);
 +            mainFrame.updateTrackState();
 +
 +        }
 +    }
++=======
++>>>>>>> upstream/1.5.56
  }
diff --combined src/org/broad/igv/ui/action/LoadFromServerAction.java
index 645b134,bacbebd..850e3cf
--- a/src/org/broad/igv/ui/action/LoadFromServerAction.java
+++ b/src/org/broad/igv/ui/action/LoadFromServerAction.java
@@@ -76,46 -76,44 +76,87 @@@ public class LoadFromServerAction exten
          String genomeId = ViewContext.getInstance().getGenomeId();
          String genomeURL = urlString.replaceAll("\\$\\$", genomeId);
          try {
++<<<<<<< HEAD
 +
 +
 +            // Add genome parameter for users with hardcoded reference to registry servlet
 +            if (genomeURL.startsWith("http:") || genomeURL.startsWith("https:"))
 +                genomeURL += "?genome=" + genomeId;
 +
 +
 +            InputStream is = null;
 +            HttpURLConnection conn = null;
 +            LinkedHashSet<URL> urls = null;
 +            try {
 +                URL masterResourceFileURL = new URL(genomeURL);
 +                if (genomeURL.startsWith("ftp:")) {
 +                    MessageUtils.showMessage("FTP protocol not supported for data registry URL");
 +                    return;
 +                } else if (genomeURL.startsWith("http:") || genomeURL.startsWith("https:")) {
 +                    conn = IGVHttpUtils.openConnection(masterResourceFileURL);
 +                    conn.setReadTimeout(10000);
 +                    conn.setConnectTimeout(10000);
 +                    is = IGVHttpUtils.openHttpStream(masterResourceFileURL, conn);
 +                } else {
 +                    File file = new File(genomeURL.startsWith("file:") ? masterResourceFileURL.getFile() : genomeURL);
 +                    if(!file.exists()) {
 +                       MessageUtils.showMessage("ERROR: File does not exist: " + file.getAbsolutePath());
 +                    return;
 +                    }
 +                    is = new FileInputStream(file);
 +                }
 +
 +                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
 +                urls = getResourceUrls(bufferedReader);
 +            } catch (IOException e) {
 +                String msg = "";
 +                if (conn.getResponseCode() == 401) {
 +                    msg = "Authorization failure accessing resource: " + genomeURL;
 +                } else {
 +                    msg = "Error accessing dataset list: " + e.toString();
 +                }
 +                MessageUtils.showMessage(msg);
 +                log.error("Error accessing URL: " + genomeURL, e);
++=======
+ 
+ 
+             // Add genome parameter for users with hardcoded reference to registry servlet
+             if (genomeURL.startsWith("http:") || genomeURL.startsWith("https:"))
+                 genomeURL += "?genome=" + genomeId;
+ 
+ 
+             InputStream is = null;
+             HttpURLConnection conn = null;
+             LinkedHashSet<URL> urls = null;
+             try {
+                 URL masterResourceFileURL = new URL(genomeURL);
+                 if (genomeURL.startsWith("ftp:")) {
+                     MessageUtils.showMessage("FTP protocol not supported for data registry URL");
+                     return;
+                 } else if (genomeURL.startsWith("http:") || genomeURL.startsWith("https:")) {
+                     conn = IGVHttpUtils.openConnection(masterResourceFileURL);
+                     conn.setReadTimeout(10000);
+                     conn.setConnectTimeout(10000);
+                     is = IGVHttpUtils.openHttpStream(masterResourceFileURL, conn);
+                 } else {
+                     File file = new File(genomeURL.startsWith("file:") ? masterResourceFileURL.getFile() : genomeURL);
+                     if (!file.exists()) {
+                         MessageUtils.showMessage("ERROR: File does not exist: " + file.getAbsolutePath());
+                         return;
+                     }
+                     is = new FileInputStream(file);
+                 }
+ 
+                 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
+                 urls = getResourceUrls(bufferedReader);
+             } catch (IOException e) {
+ 
+                 if (conn.getResponseCode() == 401) {
+                     String msg = "Authorization failure accessing resource: " + genomeURL;
+                     MessageUtils.showMessage(msg);
+                     log.error("Error accessing URL: " + genomeURL, e);
+                 }
++>>>>>>> upstream/1.5.56
              }
              finally {
                  if (is != null) is.close();
@@@ -281,11 -279,16 +322,24 @@@
              if (selectedLocators != null) {
                  for (ResourceLocator locator : selectedLocators) {
  
++<<<<<<< HEAD
++                    // Don't reload data that is already loaded
++                    if (loadedResources.contains(locator)) {
++                        continue;
++                    }
++
++=======
+                     // skip locators with no data path
+                     if(locator.getPath() == null) {
+                         continue;
+                     }
+ 
                      // Don't reload data that is already loaded
                      if (loadedResources.contains(locator)) {
                          continue;
                      }
  
++>>>>>>> upstream/1.5.56
                      newLoadList.add(locator);
                  }
              }
diff --combined src/org/broad/igv/ui/action/LoadFromURLMenuAction.java
index c7d566d,116f58f..41d1926
--- a/src/org/broad/igv/ui/action/LoadFromURLMenuAction.java
+++ b/src/org/broad/igv/ui/action/LoadFromURLMenuAction.java
@@@ -56,16 -56,11 +56,24 @@@ public class LoadFromURLMenuAction exte
          if (e.getActionCommand().equalsIgnoreCase(LOAD_FROM_URL)) {
              String url = JOptionPane.showInputDialog(IGVMainFrame.getInstance(), "Enter Http URL ");
              if (url != null && url.trim().length() > 0) {
++<<<<<<< HEAD
 +                if(url.endsWith(".xml")) {
 +                    try {
 +                        mainFrame.doRestoreSession(new URL(url), null);
 +                    } catch (MalformedURLException e1) {
 +                        MessageUtils.showMessage("Error loading url: " + url + " (" + e1.toString() + ")");
 +                    }
 +                }
 +                else {
 +                ResourceLocator rl = new ResourceLocator(url.trim());
 +                mainFrame.loadTracks(Arrays.asList(rl));
++=======
+                 if (url.endsWith(".xml")) {
+                    loadSession(url);
+                 } else {
+                     ResourceLocator rl = new ResourceLocator(url.trim());
+                     mainFrame.loadTracks(Arrays.asList(rl));
++>>>>>>> upstream/1.5.56
  
                  }
              }
@@@ -78,5 -73,32 +86,32 @@@
              }
          }
      }
+ 
+     private void loadSession(String url) {
+         // If anything has been loaded warn the users.  Popping up the
+         // warning all the time will get annoying.
+         if (IGVMainFrame.getInstance().getTrackManager().getAllTracks(false).size() > 0) {
+             int status =
+                     JOptionPane.showConfirmDialog(
+                             mainFrame,
+                             UIConstants.OVERWRITE_SESSION_MESSAGE,
+                             null,
+                             JOptionPane.OK_CANCEL_OPTION,
+                             JOptionPane.PLAIN_MESSAGE,
+                             null);
+ 
+             if (status == JOptionPane.CANCEL_OPTION ||
+                     status == JOptionPane.CLOSED_OPTION) {
+                 return;
+             }
+         }
+ 
+         try {
+             mainFrame.doRestoreSession(new URL(url), null);
+         } catch (MalformedURLException e1) {
+             MessageUtils.showMessage("Error loading url: " + url + " (" + e1.toString() + ")");
+         }
+ 
+     }
  }
  
diff --combined src/org/broad/igv/ui/action/OpenSessionMenuAction.java
index 8e063f3,099af06..d6f407e
--- a/src/org/broad/igv/ui/action/OpenSessionMenuAction.java
+++ b/src/org/broad/igv/ui/action/OpenSessionMenuAction.java
@@@ -45,15 -45,16 +45,22 @@@ import java.io.File
  public class OpenSessionMenuAction extends MenuAction {
  
      private static Logger log = Logger.getLogger(OpenSessionMenuAction.class);
++<<<<<<< HEAD
 +    IGVMainFrame mainFrame;
 +
 +    File sessionFile = null;
++=======
+     private IGVMainFrame mainFrame;
+     private File sessionFile = null;
+     private boolean autoload = false;
++>>>>>>> upstream/1.5.56
  
      public OpenSessionMenuAction(String label, File sessionFile, IGVMainFrame mainFrame) {
          super(label);
          this.sessionFile = sessionFile;
          this.mainFrame = mainFrame;
          setToolTipText(UIConstants.RESTORE_SESSION_TOOLTIP);
+         autoload = true;
      }
  
      public OpenSessionMenuAction(String label, int mnemonic, IGVMainFrame mainFrame) {
@@@ -65,22 -66,25 +72,44 @@@
      @Override
      public void actionPerformed(ActionEvent e) {
  
++<<<<<<< HEAD
 +        FileChooserDialog dialog = new FileChooserDialog(mainFrame, true);
 +        dialog.setTitle("Open Session");
 +        dialog.setSelectedFile(null);
 +        dialog.setFileSelectionMode(JFileChooser.FILES_ONLY);
 +
 +        File lastSessionDirectory =
 +                PreferenceManager.getInstance().getLastSessionDirectory();
 +        dialog.setCurrentDirectory(lastSessionDirectory);
 +        dialog.setVisible(true);
 +
 +        if (dialog.isCanceled()) {
 +            return;
 +        }
 +        sessionFile = dialog.getSelectedFile();
 +        doRestoreSession();
 +
++=======
+         //dhmay adding if statement for restore of specific session specified in menu
+         if (sessionFile == null || autoload == false) {
+             FileChooserDialog dialog = new FileChooserDialog(mainFrame, true);
+             dialog.setTitle("Open Session");
+             dialog.setSelectedFile(null);
+             dialog.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ 
+             File lastSessionDirectory =
+                     PreferenceManager.getInstance().getLastSessionDirectory();
+             dialog.setCurrentDirectory(lastSessionDirectory);
+             dialog.setVisible(true);
+ 
+             if (dialog.isCanceled()) {
+                 return;
+             }
+             sessionFile = dialog.getSelectedFile();
+         }
+         doRestoreSession();
+ 
++>>>>>>> upstream/1.5.56
      }
  
      final public void doRestoreSession() {
diff --combined src/org/broad/igv/ui/action/RegionsBaseMenuAction.java
index 0e3034b,7f34f65..c10660c
--- a/src/org/broad/igv/ui/action/RegionsBaseMenuAction.java
+++ b/src/org/broad/igv/ui/action/RegionsBaseMenuAction.java
@@@ -61,7 -61,7 +61,11 @@@ public class RegionsBaseMenuAction exte
      public final void importExportRegionsOfInterest(Direction direction) {
          File exportRegionDirectory = PreferenceManager.getInstance().getLastExportedRegionDirectory();
          if (exportRegionDirectory == null) {
++<<<<<<< HEAD
 +            exportRegionDirectory = new File(UIConstants.getDefaultUserDirectory());
++=======
+             exportRegionDirectory = UIConstants.getUserDirectory();
++>>>>>>> upstream/1.5.56
          }
  
          FileChooser exportedRegionFileChooser = new FileChooser(exportRegionDirectory);
diff --combined src/org/broad/igv/ui/action/SearchCommand.java
index 65ace98,a1b33f3..6a7e545
--- a/src/org/broad/igv/ui/action/SearchCommand.java
+++ b/src/org/broad/igv/ui/action/SearchCommand.java
@@@ -29,6 -29,7 +29,10 @@@ import org.broad.igv.PreferenceManager
  import org.broad.igv.feature.Chromosome;
  import org.broad.igv.feature.Feature;
  import org.broad.igv.feature.FeatureDB;
++<<<<<<< HEAD
++=======
+ import org.broad.igv.feature.Genome;
++>>>>>>> upstream/1.5.56
  import org.broad.igv.session.ViewContext;
  import org.broad.igv.ui.IGVMainFrame;
  import org.broad.igv.ui.util.MessageUtils;
@@@ -50,44 -51,47 +54,81 @@@ public class SearchCommand implements C
      String searchString;
      ViewContext viewContext;
      boolean recordHistory = true;
++<<<<<<< HEAD
++=======
+     Genome genome;
++>>>>>>> upstream/1.5.56
  
      public SearchCommand(ViewContext viewContext, String searchString) {
          this.viewContext = viewContext;
          this.searchString = searchString.trim();
+         genome = viewContext.getGenome();
      }
  
      public SearchCommand(ViewContext viewContext, String searchString, boolean recordHistory) {
          this(viewContext, searchString);
          this.recordHistory = recordHistory;
      }
++<<<<<<< HEAD
 +
 +
 +    public void execute() {
 +
 +        if (log.isDebugEnabled()) {
 +            log.debug("Run search: " + searchString);
 +        }
 +
 +        boolean success = false;
 +
 +        // Space delimited?
 +        String[] tokens = searchString.split("\\s+");
 +        if (tokens.length == 3) {
 +            String chr = tokens[0];
 +            int start = Integer.parseInt(tokens[1]) - 1; // Convert to UCSC convention
 +            int end = Integer.parseInt(tokens[2]);
 +            viewContext.jumpTo(chr, start, end);
 +            success = true;
 +        }
 +
 +        // Feature search
 +
 +        else {
 +            Feature feature = FeatureDB.getFeature(searchString.toUpperCase().trim());
 +            if (feature != null) {
 +                int start = Math.max(0, feature.getStart());
 +                int end = feature.getEnd();
 +
++=======
+ 
+ 
+     public void execute() {
+ 
+         if (log.isDebugEnabled()) {
+             log.debug("Run search: " + searchString);
+         }
+ 
+         boolean success = false;
+ 
+         // Space delimited?
+         String[] tokens = searchString.split("\\s+");
+         if (tokens.length == 3) {
+             String chr = tokens[0];
+             String chrAlias = genome == null ? chr :  genome.getChromosomeAlias(chr);
+             int start = Integer.parseInt(tokens[1]) - 1; // Convert to UCSC convention
+             int end = Integer.parseInt(tokens[2]);
+             viewContext.jumpTo(chrAlias, start, end);
+             success = true;
+         }
+ 
+         // Feature search
+ 
+         else {
+             Feature feature = FeatureDB.getFeature(searchString.toUpperCase().trim());
+             if (feature != null) {
+                 int start = Math.max(0, feature.getStart());
+                 int end = feature.getEnd();
+ 
++>>>>>>> upstream/1.5.56
                  if (PreferenceManager.getInstance().getBooleanPreference(PreferenceManager.SEARCH_ZOOM, true)) {
                      viewContext.jumpTo(feature.getChr(), start, end);
                  } else {
@@@ -113,11 -117,12 +154,19 @@@
  
                      // The chromosome is that portion of the search string up to the colon.
                      chr = searchString.substring(0, colon);
++<<<<<<< HEAD
++=======
+                     String chrAlias = genome == null ? chr :  genome.getChromosomeAlias(chr);
++>>>>>>> upstream/1.5.56
                      String posString = searchString.substring(colon).replace(":", "");
                      startEnd = getStartEnd(posString);
  
                      if (startEnd != null) {
++<<<<<<< HEAD
 +                        viewContext.jumpTo(chr, startEnd[0], startEnd[1]);
++=======
+                         viewContext.jumpTo(chrAlias, startEnd[0], startEnd[1]);
++>>>>>>> upstream/1.5.56
  
                          if (log.isDebugEnabled()) {
                              log.debug("End search: " + searchString);
@@@ -144,9 -149,10 +193,16 @@@
                      } else {
  
                          // No dash, this is either a chromosome or an unkown search string
++<<<<<<< HEAD
 +                        Chromosome chromosome = viewContext.getGenome().getChromosome(searchString);
 +                        if (chromosome != null || searchString.startsWith(Globals.CHR_ALL)) {
 +                            viewContext.setChromosomeName(searchString, true);
++=======
+                         String chrAlias = genome == null ? searchString :  genome.getChromosomeAlias(searchString);
+                         Chromosome chromosome = viewContext.getGenome().getChromosome(chrAlias);
+                         if (chromosome != null || chrAlias.equals(Globals.CHR_ALL)) {
+                             viewContext.setChromosomeName(chrAlias, true);
++>>>>>>> upstream/1.5.56
                              IGVMainFrame.getInstance().repaintDataAndHeaderPanels();
                              IGVMainFrame.getInstance().repaintStatusAndZoomSlider();
                              
diff --combined src/org/broad/igv/util/FileUtils.java
index 6295fc5,6f800fa..05dd306
--- a/src/org/broad/igv/util/FileUtils.java
+++ b/src/org/broad/igv/util/FileUtils.java
@@@ -22,8 -22,12 +22,17 @@@ import org.apache.log4j.Logger
  import org.apache.log4j.PatternLayout;
  import org.apache.log4j.RollingFileAppender;
  import org.broad.igv.ui.UIConstants;
++<<<<<<< HEAD
 +
 +import java.io.*;
++=======
+ import org.broad.igv.ui.util.MessageUtils;
+ import org.broad.tribble.util.HttpUtils;
+ 
+ import java.io.*;
+ import java.net.MalformedURLException;
+ import java.net.URL;
++>>>>>>> upstream/1.5.56
  import java.util.HashMap;
  import java.util.Map;
  
@@@ -34,8 -38,25 +43,28 @@@ public class FileUtils 
      final private static String separator = System.getProperties().getProperty("file.separator");
      public static StringBuffer buffer = new StringBuffer();
      static private RollingFileAppender appender;
+     private static Logger log = Logger.getLogger(FileUtils.class);
  
  
+     public static boolean resourceExists(String path) {
+         try {
+             boolean remoteFile = isRemote(path);
+             return (!remoteFile && (new File(path).exists())) ||
+                     (remoteFile && HttpUtils.resourceAvailable(new URL(path)));
+         } catch (MalformedURLException e) {
+             log.error("Malformed URL: " + path, e);
+             return false;
+         }
+     }
+ 
+ 
++<<<<<<< HEAD
++=======
+     public static boolean isRemote(String path) {
+         return path.startsWith("http://") || path.startsWith("https://") || path.startsWith("ftp://");
+     }
++>>>>>>> upstream/1.5.56
+ 
      public static boolean canWriteTo(File file) {
          FileOutputStream fos = null;
          try {
@@@ -211,10 -232,6 +240,13 @@@
      }
  
  
++<<<<<<< HEAD
 +    public static void main(String [] args){
 +        fixEOL("/Volumes/igv/data/public/ismb/ismb_snp_answers.bed", "/Volumes/igv/data/public/ismb/snp_answers.bed");
 +    }
 +
++=======
++>>>>>>> upstream/1.5.56
      public static void fixEOL(String ifile, String ofile) {
          BufferedReader br = null;
          PrintWriter pw = null;
@@@ -274,7 -291,7 +306,11 @@@
  
          // Build the log file path
          StringBuffer logFilePath = new StringBuffer();
++<<<<<<< HEAD
 +        logFilePath.append(UIConstants.DEFAULT_IGV_DIRECTORY);
++=======
+         logFilePath.append(UIConstants.getIgvDirectory());
++>>>>>>> upstream/1.5.56
          logFilePath.append(separator);
          logFilePath.append("igv.log");
  
@@@ -304,7 -321,7 +340,7 @@@
  
          try {
              is = new FileInputStream(from);
-             int bytesCopied = createFileFromStream(new BufferedInputStream(is), to);
+             createFileFromStream(is, to);
  
          }
          finally {
@@@ -317,50 -334,55 +353,80 @@@
      /**
       * Create a file from an input stream.
       *
-      * @param is
+      * @param in
       * @param outputFile
       * @throws java.io.IOException
       */
-     public static int createFileFromStream(InputStream is, File outputFile) throws IOException {
+     public static void createFileFromStream(InputStream in, File outputFile) throws IOException {
  
          int totalSize = 0;
  
-         int chunkSize = 64000;
-         byte[] data = new byte[chunkSize];
- 
-         FileOutputStream fileOutputStream = null;
+         FileOutputStream out = null;
  
          try {
-             fileOutputStream = new FileOutputStream(outputFile);
-             int bytesRead = 0;
-             while ((bytesRead = is.read(data)) > 0) {
-                 totalSize += bytesRead;
-                 fileOutputStream.write(data, 0, bytesRead);
+             out = new FileOutputStream(outputFile);
+             byte[] buffer = new byte[64000];
+             int bytes_read;
+             while ((bytes_read = in.read(buffer)) != -1)
+                 out.write(buffer, 0, bytes_read);
+         }
+ 
+         catch (Exception e) {
+             outputFile.delete();
+             MessageUtils.showMessage("<html>Error downloading file: " + outputFile.getAbsoluteFile() +
+                     "<br/>" + e.toString());
+ 
+         }
+         finally {
+             if (out != null) {
+                 out.flush();
+                 out.close();
              }
-         } finally {
-             if (fileOutputStream != null) {
-                 fileOutputStream.close();
+         }
+     }
+ 
+ 
+ 
+     public static void replaceStrings(File inputFile, File outputFile, Map<String, String> replace) throws IOException {
+ 
+         BufferedReader reader = null;
+         PrintWriter writer = null;
+ 
+         try {
+             reader = new BufferedReader(new FileReader(inputFile));
+             writer = new PrintWriter(new BufferedWriter(new FileWriter(outputFile)));
+             String nextLine;
+             while ((nextLine = reader.readLine()) != null) {
+                 for (Map.Entry<String, String> entry : replace.entrySet()) {
+                     nextLine = nextLine.replace(entry.getKey(), entry.getValue());
+                 }
+                 writer.println(nextLine);
              }
++
++        }
++        finally {
++            reader.close();
++            writer.close();
++
 +        }
-         return totalSize;
 +    }
 +
 +
 +    public static void replaceStrings(File inputFile, File outputFile, Map<String, String> replace) throws IOException {
 +
 +        BufferedReader reader = null;
 +        PrintWriter writer = null;
 +
 +        try {
 +            reader = new BufferedReader(new FileReader(inputFile));
 +            writer = new PrintWriter(new BufferedWriter(new FileWriter(outputFile)));
 +            String nextLine;
 +            while ((nextLine = reader.readLine()) != null) {
 +                for (Map.Entry<String, String> entry : replace.entrySet()) {
 +                    nextLine = nextLine.replace(entry.getKey(), entry.getValue());
 +                }
 +                writer.println(nextLine);
 +            }
  
          }
          finally {
diff --combined src/org/broad/igv/util/LRUCache.java
index 8076684,82a511b..9e19bbc
--- a/src/org/broad/igv/util/LRUCache.java
+++ b/src/org/broad/igv/util/LRUCache.java
@@@ -1,89 -1,98 +1,163 @@@
  /*
++<<<<<<< HEAD
 + * Copyright (c) 2007-2010 by The Broad Institute, Inc. and the Massachusetts Institute of Technology.
 + * All Rights Reserved.
++=======
+  * Copyright (c) 2007-2011 by The Broad Institute, Inc. and the Massachusetts Institute of
+  * Technology.  All Rights Reserved.
++>>>>>>> upstream/1.5.56
   *
-  * This software is licensed under the terms of the GNU Lesser General Public License (LGPL), Version 2.1 which
-  * is available at http://www.opensource.org/licenses/lgpl-2.1.php.
+  * This software is licensed under the terms of the GNU Lesser General Public License (LGPL),
+  * Version 2.1 which is available at http://www.opensource.org/licenses/lgpl-2.1.php.
   *
-  * THE SOFTWARE IS PROVIDED "AS IS." THE BROAD AND MIT MAKE NO REPRESENTATIONS OR WARRANTIES OF
-  * ANY KIND CONCERNING THE SOFTWARE, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
-  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT
-  * OR OTHER DEFECTS, WHETHER OR NOT DISCOVERABLE.  IN NO EVENT SHALL THE BROAD OR MIT, OR THEIR
-  * RESPECTIVE TRUSTEES, DIRECTORS, OFFICERS, EMPLOYEES, AND AFFILIATES BE LIABLE FOR ANY DAMAGES OF
-  * ANY KIND, INCLUDING, WITHOUT LIMITATION, INCIDENTAL OR CONSEQUENTIAL DAMAGES, ECONOMIC
-  * DAMAGES OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF WHETHER THE BROAD OR MIT SHALL
-  * BE ADVISED, SHALL HAVE OTHER REASON TO KNOW, OR IN FACT SHALL KNOW OF THE POSSIBILITY OF THE
-  * FOREGOING.
+  * THE SOFTWARE IS PROVIDED "AS IS." THE BROAD AND MIT MAKE NO REPRESENTATIONS OR
+  * WARRANTES OF ANY KIND CONCERNING THE SOFTWARE, EXPRESS OR IMPLIED, INCLUDING,
+  * WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+  * PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, WHETHER
+  * OR NOT DISCOVERABLE.  IN NO EVENT SHALL THE BROAD OR MIT, OR THEIR RESPECTIVE
+  * TRUSTEES, DIRECTORS, OFFICERS, EMPLOYEES, AND AFFILIATES BE LIABLE FOR ANY DAMAGES
+  * OF ANY KIND, INCLUDING, WITHOUT LIMITATION, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
+  * ECONOMIC DAMAGES OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF WHETHER
+  * THE BROAD OR MIT SHALL BE ADVISED, SHALL HAVE OTHER REASON TO KNOW, OR IN FACT
+  * SHALL KNOW OF THE POSSIBILITY OF THE FOREGOING.
   */
  package org.broad.igv.util;
  
  import org.apache.log4j.Logger;
  
++<<<<<<< HEAD
++=======
+ import java.lang.ref.SoftReference;
++>>>>>>> upstream/1.5.56
  import java.lang.ref.WeakReference;
  import java.util.*;
  
  /**
   * @author jrobinso
   */
- public class LRUCache<K, V> extends LinkedHashMap<K, V> {
+ public class LRUCache<K, V> {
  
      Logger log = Logger.getLogger(LRUCache.class);
  
-     private int maxEntries = 100;
  
++<<<<<<< HEAD
 +    private static Set<WeakReference<LRUCache>> instances = new HashSet();
 +
 +
 +    public LRUCache(int maxEntries) {
 +        this.maxEntries = maxEntries;
 +        instances.add(new WeakReference(this));
 +    }
 +
 +    public static void clearCaches() {
 +        for (WeakReference<LRUCache> cache : instances) {
 +            LRUCache instance = cache.get();
 +            if (instance != null) {
 +                instance.clear();
 +            }
 +        }
 +        instances.clear();
 +    }
 +
 +    public static void removeAllOldestEntries() {
 +        for (WeakReference<LRUCache> cache : instances) {
 +            LRUCache instance = cache.get();
 +            if (instance != null) {
 +                instance.removeOldestEntries();
 +            }
 +        }
 +    }
 +
 +    @Override
 +    protected boolean removeEldestEntry(Map.Entry eldest) {
 +        if (size() > maxEntries) {
 +            if (log.isDebugEnabled()) {
 +                log.debug("Exceed cache capacity.");
 +            }
 +            return true;
 +        } else if (RuntimeUtils.getAvailableMemoryFraction() < 0.3) {
 +            log.info("Memory low.  Free cache entry");
 +            removeAllOldestEntries();
 +
 +            // Per the LinkedHashMap contract return false, to prevent further modifications
 +            return false;
 +        } else {
 +            return false;
++=======
+     private static Map<Object, LRUCache> instances = Collections.synchronizedMap(new WeakHashMap<Object, LRUCache>());
+ 
+     public static void clearCaches() {
+         for (LRUCache cache : instances.values()) {
+             if (cache != null) {
+                 cache.clear();
+             }
+         }
+     }
+ 
+ 
+     private final int maxEntries;
+ 
+     private SoftReference<Map<K, V>> mapReference;
+ 
+ 
+     public LRUCache(Object source, int max) {
+         instances.put(source, this);
+         this.maxEntries = max;
+         createMap();
+     }
+ 
+     private void createMap() {
+         mapReference = new SoftReference(Collections.synchronizedMap(
+                 new LinkedHashMap<K, V>() {
+                     @Override
+                     protected boolean removeEldestEntry(Map.Entry eldest) {
+                         return (size() > maxEntries);
+                     }
+                 }));
+     }
+ 
+     private Map<K, V> getMap() {
+         if (mapReference == null || mapReference.get() == null) {
+             createMap();
++>>>>>>> upstream/1.5.56
          }
+         return mapReference.get();
      }
  
+     public V put(K k, V v) {
+         return getMap().put(k, v);
+     }
+ 
++<<<<<<< HEAD
 +    private void removeOldestEntries() {
 +        // Remove oldest entries,  keeping the lower of the newest 5 or 1/2 of the entries.
 +        List<K> keys = new ArrayList(keySet());
 +        int midPoint = Math.min(5, keys.size() / 2);
 +        for (int i = midPoint; i < keys.size(); i++) {
 +            remove(keys.get(i));
 +        }
 +        System.gc();
 +    }
++=======
+     public V get(Object key) {
+         return getMap().get(key);
+     }
+ 
+     public boolean containsKey(Object o) {
+         return getMap().containsKey(o);
+     }
+ 
+     public boolean isEmpty() {
+         return getMap().isEmpty();    //To change body of overridden methods use File | Settings | File Templates.
+     }
+ 
+     public void clear() {
+         getMap().clear();
+     }
+ 
+ 
+ 
+ 
++>>>>>>> upstream/1.5.56
  }
  
diff --combined src/org/broad/igv/util/MacroSnapshotAction.java
index f0332fe,fef4cfd..257ece0
--- a/src/org/broad/igv/util/MacroSnapshotAction.java
+++ b/src/org/broad/igv/util/MacroSnapshotAction.java
@@@ -72,7 -72,7 +72,11 @@@ public class MacroSnapshotAction 
          IGVMainFrame mainFrame = IGVMainFrame.getInstance();
  
          if (filename == null) {
++<<<<<<< HEAD
 +            String locus = ViewContext.getInstance().getCurrentLocusString();
++=======
+             String locus = ViewContext.getInstance().getFormattedLocusString();
++>>>>>>> upstream/1.5.56
              filename = locus.replaceAll(":", "_").replace("-", "_") + ".png";
          }
  
diff --combined src/org/broad/igv/util/SeekableFileStream.java
index 49c1cd2,c6a9540..107786a
--- a/src/org/broad/igv/util/SeekableFileStream.java
+++ b/src/org/broad/igv/util/SeekableFileStream.java
@@@ -35,63 -35,86 +35,134 @@@ public class SeekableFileStream extend
      File file;
      FileInputStream fis;
  
++<<<<<<< HEAD
 +     SeekableFileStream(File file) throws FileNotFoundException {
++=======
+     SeekableFileStream(File file) throws FileNotFoundException {
++>>>>>>> upstream/1.5.56
          this.file = file;
          fis = new FileInputStream(file);
      }
  
      public void seek(long position) throws IOException {
+         if (fis == null) {
+             fis = new FileInputStream(file);
+         }
          fis.getChannel().position(position);
      }
  
      public long position() throws IOException {
++<<<<<<< HEAD
++=======
+         if (fis == null) {
+             fis = new FileInputStream(file);
+         }
++>>>>>>> upstream/1.5.56
          return fis.getChannel().position();
      }
  
      @Override
      public long skip(long n) throws IOException {
++<<<<<<< HEAD
++=======
+         if (fis == null) {
+             fis = new FileInputStream(file);
+         }
++>>>>>>> upstream/1.5.56
          return fis.skip(n);
      }
  
      @Override
      public int read(byte[] buffer, int offset, int length) throws IOException {
++<<<<<<< HEAD
++=======
+         if (fis == null) {
+             fis = new FileInputStream(file);
+         }
++>>>>>>> upstream/1.5.56
          return fis.read(buffer, offset, length);
      }
  
      @Override
      public int read() throws IOException {
++<<<<<<< HEAD
++=======
+         if (fis == null) {
+             fis = new FileInputStream(file);
+         }
++>>>>>>> upstream/1.5.56
          return fis.read();
      }
  
      @Override
      public int read(byte[] b) throws IOException {
++<<<<<<< HEAD
 +        return fis.read(b);    
 +    }
 +
 +    @Override
 +    public int available() throws IOException {
 +        return fis.available();
 +    }
 +
 +    @Override
 +    public void mark(int readlimit) {
 +        fis.mark(readlimit); 
 +    }
 +
 +    @Override
 +    public boolean markSupported() {
 +        return fis.markSupported();
 +    }
 +
 +    @Override
 +    public void reset() throws IOException {
 +        fis.reset();
 +    }
 +
 +    @Override
 +    public void close() throws IOException {
 +        fis.close();
 +
 +    }
 +
++=======
+         if (fis == null) {
+             fis = new FileInputStream(file);
+         }
+         return fis.read(b);
+     }
+ 
+     @Override
+     public int available() throws IOException {
+         if (fis == null) {
+             fis = new FileInputStream(file);
+         }
+         return fis.available();
+     }
+ 
+     @Override
+     public void mark(int readlimit) {
+         fis.mark(readlimit);
+     }
+ 
+     @Override
+     public boolean markSupported() {
+         return fis.markSupported();
+     }
+ 
+     @Override
+     public void reset() throws IOException {
+         fis.reset();
+     }
+ 
+     @Override
+     public void close() throws IOException {
+         if (fis != null) {
+             fis.close();
+             fis = null;
+         }
+     }
+ 
++>>>>>>> upstream/1.5.56
  }
diff --combined src/org/broad/tribble/readers/BasicFeatureReader.java
index 0a9ba99,4ad1de1..2b990c6
--- a/src/org/broad/tribble/readers/BasicFeatureReader.java
+++ b/src/org/broad/tribble/readers/BasicFeatureReader.java
@@@ -189,21 -189,17 +189,35 @@@ public class BasicFeatureReader<T exten
          }
  
          private T readNextRecord() throws IOException {
++<<<<<<< HEAD
 +
 +            currentRecord = null;
 +            String nextLine;
 +            while (currentRecord == null && reader != null && (nextLine = reader.readLine()) != null) {
 +
 +                Feature f = BasicFeatureReader.codec.decode(nextLine);
 +                if (f == null)
 +                    continue;
 +                else if (f.getStart() > end) {
 +                    break;
 +                } else if ((contained && f.getStart() >= start) ||
 +                        (!contained && f.getEnd() >= start)) {
 +                    // todo -- any way to avoid this cast?
 +                    currentRecord = (T) f;
 +                }
++=======
+             currentRecord = null;
+             String nextLine;
+             while (currentRecord == null && reader != null && (nextLine = reader.readLine()) != null) {
+                 Feature f = null;
+                 f = BasicFeatureReader.codec.decode(nextLine);
+                 if (f == null)
+                     continue;
+                 else if ((end > 0 && f.getStart() > end) || (chr != null && !chr.equals(f.getChr())))
+                     break;
+                 else if (f.getEnd() >= start)
+                     currentRecord = (T) f;
++>>>>>>> upstream/1.5.56
              }
              return currentRecord;
          }
diff --combined src/resources/about.properties
index a477534,1124c73..c571e31
--- a/src/resources/about.properties
+++ b/src/resources/about.properties
@@@ -16,7 -16,8 +16,15 @@@
  # FOREGOING.
  #
  
++<<<<<<< HEAD
 +version=1.5.21
 +build=5828
 +timestamp=09/15/2010 12:46 AM
- master-resource-url=@DEFAULT_MASTER_RESOURCE_URL
++master-resource-url=@DEFAULT_MASTER_RESOURCE_URL
++=======
+ version=1.5.56
+ build=6203
+ timestamp=03/10/2011 12:32 AM
+ master-resource-url=@DEFAULT_MASTER_RESOURCE_URL
 -master-genome-url=@DEFAULT_MASTER_GENOME_URL
++master-genome-url=@DEFAULT_MASTER_GENOME_URL
++>>>>>>> upstream/1.5.56

-- 
Integrative Genomics Viewer



More information about the debian-med-commit mailing list