diff --git a/uk/ac/sanger/artemis/circular/Block.java b/uk/ac/sanger/artemis/circular/Block.java
index 8a24bc6adbd521ae3d7510c9cd1831164855affa..5265b6670e41550ee76ece435195effae8c03048 100644
--- a/uk/ac/sanger/artemis/circular/Block.java
+++ b/uk/ac/sanger/artemis/circular/Block.java
@@ -610,7 +610,7 @@ public class Block implements Transferable
   * @param x    x position 
   * @param y    y position
   */
-  public void setBlockLocation(int x, int y, final TrackViewer viewer)
+  public void setBlockLocation(int x, int y, final TrackManager viewer)
   {
     if(current_dna.isCircular())
     {
diff --git a/uk/ac/sanger/artemis/circular/DNADraw.java b/uk/ac/sanger/artemis/circular/DNADraw.java
index 86be7aa9d55c3be7a8de86e9d91f531535c8ead6..ecd09010fc420a83d03f2e1679a12662d1a7b9ec 100644
--- a/uk/ac/sanger/artemis/circular/DNADraw.java
+++ b/uk/ac/sanger/artemis/circular/DNADraw.java
@@ -61,7 +61,11 @@ import java.awt.dnd.DropTargetDragEvent;
 import java.awt.dnd.DropTargetDropEvent;
 import java.awt.dnd.DropTargetEvent;
 import java.awt.dnd.DropTargetListener;
+import java.io.BufferedReader;
+import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 
 import javax.swing.JButton;
 import javax.swing.JCheckBoxMenuItem;
@@ -87,7 +91,6 @@ public class DNADraw extends ScrollPanel
                      implements Printable, DragGestureListener,
                      DragSourceListener, DropTargetListener
 {
-
   private static final long serialVersionUID = 1L;
   public static JScrollPane jsp;
   private DNADraw current_dna;
@@ -130,7 +133,7 @@ public class DNADraw extends ScrollPanel
   private Graph userGraph;
   protected static int Y_SHIFT = -35;
   protected static int THETA = -90;
-  private TrackViewer viewer;
+  private TrackManager trackManager;
   private AffineTransform original;
   
   // linear plot variables
@@ -197,7 +200,28 @@ public class DNADraw extends ScrollPanel
     this.addMouseListener(mouseListener);
   }
   
-
+  private String getVersion()
+  {
+    final ClassLoader cl = this.getClass().getClassLoader();
+    try
+    {
+      String line;
+      InputStream in = cl.getResourceAsStream("etc/versions");
+      BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+      while((line = reader.readLine()) != null)
+      {
+        if(line.startsWith("DNAPlot"))
+          return line.substring( "DNAPlot".length() ).trim();
+      }
+      reader.close();
+      in.close();
+    }
+    catch (Exception ex)
+    {
+    }
+    return null;
+  }
+  
   /**
    * Add list of features to a track
    * @param features
@@ -956,7 +980,7 @@ public class DNADraw extends ScrollPanel
    * @param g
    * @return
    */
-  private boolean containsGraph(Graph g)
+  protected boolean containsGraph(Graph g)
   {
     int ncomponents = getComponentCount();
     for(int i=0; i<ncomponents; i++)
@@ -1099,7 +1123,7 @@ public class DNADraw extends ScrollPanel
       public void actionPerformed(ActionEvent e)
       {
         Wizard.readEntry(DNADraw.this, getBases());
-        viewer.refresh();
+        trackManager.refresh();
         repaint();
       }
     });
@@ -1141,7 +1165,13 @@ public class DNADraw extends ScrollPanel
     fileMenu.add(printPreview);
     fileMenu.add(new JSeparator());
 
-
+    fileMenu.add(TrackManager.getExportTrackTemplateMenuItem(null, this));
+    
+    if(trackManager == null)
+      trackManager = new TrackManager(DNADraw.this);
+    fileMenu.add(trackManager.getImportTrackTemplateMenuItem(null));
+    fileMenu.add(new JSeparator());
+    
     final JMenuItem fileMenuExit;
     if(!close)
       fileMenuExit = new JMenuItem("Exit");
@@ -1199,7 +1229,11 @@ public class DNADraw extends ScrollPanel
     graph_menu.add(gc);
     
     final JCheckBoxMenuItem gcPlot = new JCheckBoxMenuItem("Draw");
-    gcPlot.setState(false);
+    
+    if(gcGraph == null)
+      gcPlot.setState(false);
+    else
+      gcPlot.setState(true);
     gcPlot.addItemListener(new ItemListener() 
     {
       public void itemStateChanged(ItemEvent event) 
@@ -1236,8 +1270,12 @@ public class DNADraw extends ScrollPanel
     JMenu gcSkew = new JMenu("GC Skew");
     graph_menu.add(gcSkew);
     
-    final JCheckBoxMenuItem gcSkewPlot = new JCheckBoxMenuItem("GC Skew plot");
-    gcSkewPlot.setState(false);
+    final JCheckBoxMenuItem gcSkewPlot = new JCheckBoxMenuItem("Draw");
+    if(gcSkewGraph == null)
+      gcSkewPlot.setState(false);
+    else
+      gcSkewPlot.setState(true);
+
     gcSkewPlot.addItemListener(new ItemListener() 
     {
       public void itemStateChanged(ItemEvent event) 
@@ -1277,8 +1315,11 @@ public class DNADraw extends ScrollPanel
     
     JMenu user = new JMenu("User");
     graph_menu.add(user);
-    final JCheckBoxMenuItem userPlot = new JCheckBoxMenuItem("User plot");
-    userPlot.setState(false);
+    final JCheckBoxMenuItem userPlot = new JCheckBoxMenuItem("Draw");
+    if(userGraph == null)
+      userPlot.setState(false);
+    else
+      userPlot.setState(true);
     userPlot.addItemListener(new ItemListener() 
     {
       public void itemStateChanged(ItemEvent event) 
@@ -1377,12 +1418,12 @@ public class DNADraw extends ScrollPanel
 
     if(getArtemisEntryGroup() != null)
     {
-      viewer = new TrackViewer(DNADraw.this);
+      trackManager = new TrackManager(DNADraw.this);
       tracksMenu.addActionListener(new ActionListener()
       {
         public void actionPerformed(ActionEvent e)
         {
-          viewer.setVisible(true);
+          trackManager.setVisible(true);
         }
       });
     }
@@ -1685,7 +1726,7 @@ public class DNADraw extends ScrollPanel
       {
         Point loc = e.getLocation();
         Block b   = (Block)t.getTransferData(Block.BLOCK);
-        b.setBlockLocation(loc.x,loc.y,viewer);
+        b.setBlockLocation(loc.x,loc.y,trackManager);
         DNADraw.this.repaint();
       }
       catch(Exception ufe){} 
@@ -1725,110 +1766,6 @@ public class DNADraw extends ScrollPanel
   {
     return block;
   }
-  
-  public static void main(String arg[])
-  {
-    final Wizard wiz = new Wizard(null);
-    final DNADraw dna = wiz.getDNADraw();
-     
-    /**
-    final DNADraw dna = new DNADraw();
-    final String seq =         
-    "taaaggtagaattggaaaaattggaaaaattggaaaaatcatgtgatcac"+
-    "tgtaaaacaactaacaaatgcaagaatgattatgataaaaataaatgtga"+
-    "aaagtgtaaaacgagatgtcaacaatatgataattttattcttaaatgga"+
-    "aaactctattcgatatacaatctaagaaatacaaagaattgtatgaacca"+
-    "atagatacaaaaaactctacttatgatcatgttgaaaattttgtacaaaa"+
-    "gttgaaaaaatataaaaatgaatgttctgttgaaagcgtttctgaatatc"+
-    "ttcatgaaacaagtaagtgtttgaattataaatttgatgaaaatgatggt"+
-    "tcttctaatatacgatcatatgcttttgaagaaacaccaaaaagttataa"+
-    "agaagcttgcagttgtacattaccttctaagaatccattggataattgtc"+
-    "ctaccgatcaaaacaaagatgtatgtaaggaattacaaacttttaccttc"+
-    "tgctcgaagaatgattatgataataatcttgataattggaacgcatacct"+
-    "tgttcttaatagttcagatgataataaaggtgtattgattcctccaagaa"+
-    "gaagacatttatgtacaagacctatcactgcatataattatagaaaaggt"+
-    "gataaagaaattttaaaaaaaaaacttcttacttctgctttcagtcaagg"+
-    "acaattgttaggtcaaaaatataaatcggaagaagagttgtgctttgagg"+
-    "caatgaaatatagttatgcagattattccgatataattaaaggaactgat"+
-    "atgatggacacttcattatctgaaaaaattaaaaaaatatttgaaacatc"+
-    "aaatcaagacactgaagattgtaaaacatggtgggaaaaaaatagaagtc"+
-    "atgtatggcacgctatgttatgtggatatatatcaaaaaacaaaaatgag"+
-    "aacattaacccaaaatggtgtaatgtacctactgaagatggaactgatca"+
-    "attcttaagatggttaattgaatgggcaatgcaagcatgtaaagaaaaga"+
-    "aacgtgtaagggattcattaaaaacaaaatgtcgttgttcaaacaaagat"+
-    "aattttaaagcgtcagaattattaagacaacctggatgtcagaatgatat"+
-    "tagaaaatatattagcttgaatatattgatacaaaattcaatggaaaatc"+
-    "taaatataaaatataaaaaattcaaagatcaatcttcaggtttagggttc"+
-    "agggtttagggttcagggtttagggtttagggttcagggttttaggttta"+
-    "gggttcagggtttagggttcagggtttagggtttagggttcagggtttta"+
-    "gggtttagggttcagggtttagggtttaggtttagggtttaggtttaggg"+
-    "ttcagggtttaggtttagggttcagggtttaggtttagggttcagggttt"+
-    "agggttcagggttcagggtttagggttccggtttagggttcagggttcag"+
-    "ggtttagggtttagggtttagggttcagggttcaggtttagggtttaggg"+
-    "ttcagggtttagggtttaggtttcagggtttagggtttagggtttagggt"+
-    "ttaggtttagggtttagggtttaggtttagggtttagggttcatggttta"+
-    "gggtttagggtttagggtttagggtttagggtttaggtttagggttgtgg"+
-    "tttagggtttagggtttagggttcagggtttagggtttagggttcagggt";
-    
-    Bases bases = new Bases(new uk.ac.sanger.artemis.io.RawStreamSequence(seq));
-    
-    dna.setBases( bases  );
-    int sequenceLength = bases.getLength();
-    
-    
-    // set sequence length and
-    Hashtable lineAttr = new Hashtable();
-    lineAttr.put("lsize",new Integer(1));
-    lineAttr.put("circular",new Boolean(true));
-    lineAttr.put("start",new Integer(0));
-    lineAttr.put("end",new Integer(sequenceLength));
-    dna.setLineAttributes(lineAttr);   
-    
-    // set ticks
-    int div;
-    if(sequenceLength < 1000)
-      div = 100;
-    else if(sequenceLength < 10000)
-      div = 1000;
-    else if(sequenceLength < 100000)
-      div = 10000;
-    else
-      div = 100000;
-    int tick = sequenceLength/div;
-    tick = tick*(div/10);
-    dna.setMinorTickInterval(tick);
-    dna.setTickInterval(tick);
-     
-    final List features = new Vector();
-    features.add(new Feature("a", 20, 250, 2));
-    features.add(new Feature("b", 300, 550, 2));
-
-    final Track track = new Track(0.9);
-    dna.setGeneticMarker(new Vector());
-    dna.addFeaturesToTrack(features, track, true);
-    
-    final Track track2 = new Track(0.8);
-    dna.addFeatureToTrack(new Feature("cc", 1400, 1555, 5), track2, true);
-    **/
-    
-    //
-    final JFrame f = new JFrame("DNA Viewer");
-
-    Dimension d = f.getToolkit().getScreenSize();
-    jsp = new JScrollPane(dna);
-    jsp.getViewport().setBackground(Color.white);
-    f.getContentPane().add(jsp);
-    f.setJMenuBar(dna.createMenuBar());
-    
-    //dna.add(new Graph(dna));
-    f.pack();
-    f.setLocation(((int)d.getWidth()-f.getWidth())/4,
-                  ((int)d.getHeight()-f.getHeight())/2);
-
-    
-    //dna.add(dna.new BlockPanel(dna));
-    f.setVisible(true);
-  }
 
 
   public int getBasesPerLine()
@@ -1901,6 +1838,83 @@ public class DNADraw extends ScrollPanel
   {
     this.borderHeight2 = borderHeight2;
   }
+
+  public TrackManager getTrackManager()
+  {
+    return trackManager;
+  }
+
+  public void setTrackManager(TrackManager trackManager)
+  {
+    this.trackManager = trackManager;
+  }
+
+  public Graph getGcGraph()
+  {
+    return gcGraph;
+  }
+
+  public void setGcGraph(Graph gcGraph)
+  {
+    this.gcGraph = gcGraph;
+  }
+
+  public Graph getGcSkewGraph()
+  {
+    return gcSkewGraph;
+  }
+
+  public void setGcSkewGraph(Graph gcSkewGraph)
+  {
+    this.gcSkewGraph = gcSkewGraph;
+  }
+
+  public Graph getUserGraph()
+  {
+    return userGraph;
+  }
+
+  public void setUserGraph(Graph userGraph)
+  {
+    this.userGraph = userGraph;
+  }
+  
+  public static void main(String arg[])
+  {
+    final Wizard wiz;
+    
+    if(arg.length > 0 && arg[0].equals("-t"))
+    {
+      final File fileTemplate = new File(arg[1]);
+      wiz = new Wizard(fileTemplate);
+    }
+    else
+      wiz = new Wizard((DNADraw)null);
+    final DNADraw dna = wiz.getDNADraw();
+    
+    //
+    final String version = dna.getVersion();
+    final JFrame f = new JFrame();
+    if(version == null)
+      f.setTitle("DNA Plot");
+    else
+      f.setTitle("DNA Plot :: "+version);
+      
+    Dimension d = f.getToolkit().getScreenSize();
+    jsp = new JScrollPane(dna);
+    jsp.getViewport().setBackground(Color.white);
+    f.getContentPane().add(jsp);
+    f.setJMenuBar(dna.createMenuBar());
+    
+    //dna.add(new Graph(dna));
+    f.pack();
+    f.setLocation(((int)d.getWidth()-f.getWidth())/4,
+                  ((int)d.getHeight()-f.getHeight())/2);
+
+    
+    //dna.add(dna.new BlockPanel(dna));
+    f.setVisible(true);
+  }
   
   /*class BlockPanel extends JPanel
   {
diff --git a/uk/ac/sanger/artemis/circular/Graph.java b/uk/ac/sanger/artemis/circular/Graph.java
index d82cd9066b551da8d1d9280ddc4508bdb6872880..156ad5677a402474f2eb70502a3c0bbeefee79d2 100644
--- a/uk/ac/sanger/artemis/circular/Graph.java
+++ b/uk/ac/sanger/artemis/circular/Graph.java
@@ -102,26 +102,7 @@ public abstract class Graph extends JPanel
     int nvalues = bases.getLength()/getBaseStepSize();
     
     if(value_array == null)
-    {
-      value_array = new float [nvalues];
-      gcAverage   = 0;
-      for(int i=0; i<nvalues; i++)
-      {
-        int start = (i*getBaseStepSize())+1;
-        int end = start+getWindowSize();
-        
-        if(end > bases.getLength())
-          end = bases.getLength();
-        
-        value_array[i] = calculateValue(start, end);
-        if(value_array[i] > maxValue)
-          maxValue = value_array[i];
-        if(value_array[i] < minValue)
-          minValue = value_array[i];
-        gcAverage += value_array[i];
-      }
-      gcAverage = gcAverage/nvalues;
-    }
+      calcGraphValues();
     
     int minPos = (int)((ddiameter/2.d)*getTrack());
     int maxPos = minPos + (int)((ddiameter/2.d)*getGraphHeight());
@@ -181,31 +162,10 @@ public abstract class Graph extends JPanel
     int borderHeight2 = getCurrentDna().getBorderHeight2();
     
     Bases bases = getBases();
-    
     int nvalues = bases.getLength()/getBaseStepSize();
     
     if(value_array == null)
-    {
-      value_array = new float [nvalues];
-      gcAverage   = 0;
-      for(int i=0; i<nvalues; i++)
-      {
-        int start = (i*getBaseStepSize())+1;
-        int end = start+getWindowSize();
-        
-        if(end > bases.getLength())
-          end = bases.getLength();
-        
-        value_array[i] = calculateValue(start, end);
-        if(value_array[i] > maxValue)
-          maxValue = value_array[i];
-        if(value_array[i] < minValue)
-          minValue = value_array[i];
-        gcAverage += value_array[i];
-      }
-      gcAverage = gcAverage/nvalues;
-    }
-    
+      calcGraphValues();
     
     int minPos = (int)(lineHeight*(1-getTrack()));
     int maxPos = minPos + (int)(lineHeight*getGraphHeight());
@@ -239,6 +199,30 @@ public abstract class Graph extends JPanel
     }
   }
 
+  protected void calcGraphValues()
+  {
+    Bases bases = getBases();
+    int nvalues = bases.getLength()/getBaseStepSize();
+    value_array = new float [nvalues];
+    gcAverage   = 0;
+    for(int i=0; i<nvalues; i++)
+    {
+      int start = (i*getBaseStepSize())+1;
+      int end = start+getWindowSize();
+      
+      if(end > bases.getLength())
+        end = bases.getLength();
+      
+      value_array[i] = calculateValue(start, end);
+      if(value_array[i] > maxValue)
+        maxValue = value_array[i];
+      if(value_array[i] < minValue)
+        minValue = value_array[i];
+      gcAverage += value_array[i];
+    }
+    gcAverage = gcAverage/nvalues;
+  }
+  
   protected int getWindowSize()
   {
     return windowSize;
@@ -514,6 +498,55 @@ public abstract class Graph extends JPanel
     repaint();
   }
   
+  /**
+   * Used to write out options to template file
+   * @return
+   */
+  protected String getOptionsStr()
+  {
+    return "height="+getGraphHeight()+" window_size="+getWindowSize()+
+           " base_step_size="+getBaseStepSize()+" track="+getTrack()+
+           " minus_colour="+getMinusColour().getRed()+":"+
+                            getMinusColour().getGreen()+":"+
+                            getMinusColour().getBlue()+
+           " plus_colour="+getPlusColour().getRed()+":"+
+                           getPlusColour().getGreen()+":"+
+                           getPlusColour().getBlue();
+  }
+  
+  /**
+   * Used when reading in a template file
+   * @param options
+   */
+  protected void setOptionsStr(final String options[])
+  {
+    for(int i=0; i<options.length; i++)
+    {
+      if(options[i].startsWith("height"))
+        setGraphHeight(Float.parseFloat(options[i+1]));
+      else if(options[i].startsWith("window_size"))
+        setWindowSize(Integer.parseInt(options[i+1]));
+      else if(options[i].startsWith("base_step_size"))
+        setBaseStepSize(Integer.parseInt(options[i+1]));
+      else if(options[i].startsWith("track"))
+        setTrack(Double.parseDouble(options[i+1]));
+      else if(options[i].startsWith("minus_colour"))
+      {
+        String col[] = options[i+1].split(":");
+        setMinusColour(new Color(Integer.parseInt(col[0]),
+                                 Integer.parseInt(col[1]),
+                                 Integer.parseInt(col[2])));
+      }
+      else if(options[i].startsWith("plus_colour"))
+      {
+        String col[] = options[i+1].split(":");
+        setPlusColour(new Color(Integer.parseInt(col[0]),
+                                 Integer.parseInt(col[1]),
+                                 Integer.parseInt(col[2])));
+      }
+    }
+  }
+  
   private void setColorButton(final JButton button,
                               final Color col,
                               final ActionListener okListener,
diff --git a/uk/ac/sanger/artemis/circular/Track.java b/uk/ac/sanger/artemis/circular/Track.java
index 4c0c2bf556460b55d51c1313b0523fb1a2deaee3..eda2666b36cefac9a53fd17b1636cfcb62e7e51c 100644
--- a/uk/ac/sanger/artemis/circular/Track.java
+++ b/uk/ac/sanger/artemis/circular/Track.java
@@ -21,6 +21,11 @@
 package uk.ac.sanger.artemis.circular;
 
 import java.awt.Color;
+import java.io.IOException;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 
 import uk.ac.sanger.artemis.Entry;
 import uk.ac.sanger.artemis.Feature;
@@ -28,6 +33,7 @@ import uk.ac.sanger.artemis.FeatureKeyPredicate;
 import uk.ac.sanger.artemis.FeatureKeyQualifierPredicate;
 import uk.ac.sanger.artemis.FeaturePredicate;
 import uk.ac.sanger.artemis.io.Key;
+import uk.ac.sanger.artemis.util.FileDocument;
 
 public class Track
 {
@@ -235,4 +241,126 @@ public class Track
   {
     this.colour = colour;
   }
+  
+  protected void setPropertiesFromTemplate(final String line)
+  {
+    final String properties[] = line.split("\t");
+
+    setPosition(Double.parseDouble(properties[0]));
+    setSize(Float.parseFloat(properties[1]));
+    setShowForward(Boolean.parseBoolean(properties[2]));
+    setShowReverse(Boolean.parseBoolean(properties[3]));
+    setNotQualifier(Boolean.parseBoolean(properties[4]));
+    setAny(Boolean.parseBoolean(properties[5]));
+    
+    if(properties[6].equals("null"))
+      setKeyStr(null);
+    else
+      setKeyStr(properties[6]);
+    if(properties[7].equals("null"))
+      setQualifier(null);
+    else
+      setQualifier(properties[7]);
+    if(properties[8].equals("null"))
+      setQualifierValue(null);
+    else
+      setQualifierValue(properties[8]);
+    if(properties[9].equals("null"))
+      setColour(null);
+    else
+    {
+      String colourRGB[] = properties[9].split(":");
+      Color colour = new Color(Integer.parseInt(colourRGB[0]),
+                               Integer.parseInt(colourRGB[1]),
+                               Integer.parseInt(colourRGB[2]));
+      setColour(colour);
+    }
+  }
+  
+  /**
+   * Write the track properties out
+   * @param writer
+   * @throws IOException
+   */
+  protected void write(final Writer writer) throws IOException
+  { 
+    writer.write(position+"\t"+
+                 size+"\t"+
+                 showForward+"\t"+
+                 showReverse+"\t"+
+                 isNotQualifier()+"\t"+
+                 any+"\t"+
+                 keyStr+"\t"+
+                 qualifier+"\t"+
+                 qualifierValue+"\t"+
+                 ( colour != null ? 
+                     colour.getRed()+":"+colour.getGreen()+":"+colour.getBlue() : null)+"\t"+
+                 ( entry != null ? entry.getName()+"\t"+entry.getRootDocument() : null )+
+                 "\n");
+  }
+  
+  /**
+   * Write a header line for the track properties
+   * @param writer
+   * @throws IOException
+   */
+  protected static void writeHeader(final Writer writer, final DNADraw dna) throws IOException
+  {
+    DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");      
+    writer.write("## DNA Plot :: track template (created: "+
+        dateFormat.format(new Date())+")\n");
+    writer.write("# line attributes: start="+dna.getStart()+
+                                     " end="+dna.getEnd()+" " +
+                                "line_size="+dna.getLineSize()+
+                                " circular="+dna.isCircular());
+                                
+    if(!dna.isCircular())
+      writer.write(" line_height="+dna.getLineHeight()+
+                   " bases_per_line="+dna.getBasesPerLine());
+    
+    writer.write("\n# tick marks: major="+dna.getTickInterval()+
+                              " minor="+dna.getMinorTickInterval()+"\n");
+    
+    // graphs
+    if(dna.getUserGraph() != null && dna.containsGraph(dna.getUserGraph()))
+    {
+      FileDocument doc = (FileDocument) ((UserGraph)dna.getUserGraph()).getDocument();
+      String fileName = doc.getFile().getAbsolutePath();
+      
+      writer.write("# User Graph: "+dna.getUserGraph().getOptionsStr()+
+                   " file_name="+fileName+"\n");
+    }
+    if(dna.getGcGraph() != null && dna.containsGraph(dna.getGcGraph()))
+      writer.write("# GC Graph: "+dna.getGcGraph().getOptionsStr()+"\n");
+    if(dna.getGcSkewGraph() != null && dna.containsGraph(dna.getGcSkewGraph()))
+      writer.write("# GC Skew Graph: "+dna.getGcSkewGraph().getOptionsStr()+"\n");
+    
+    writer.write(
+        "# Columns are:\n"+
+        "# POS  - track position\n"+
+        "# SIZE - track size\n"+
+        "# FWD  - show forward strand features\n"+
+        "# REV  - show reverse strand features\n"+
+        "# NOT  - use NOT\n"+
+        "# ANY  - show any features\n"+
+        "# KEY  - show features of this key\n"+
+        "# QUAL - show features with this qualifier\n"+
+        "# VAL  - show features with this qualifier value(s)\n"+
+        "# COL  - colour for this track e.g. 255:0:0 (R:G:B) or NULL\n"+
+        "# NAME - file entry name or null\n"+
+        "# DIR  - root directory for this file\n#\n");
+    writer.write(
+        "#POS\t"+
+        "SIZE\t"+
+        "FWD\t"+
+        "REV\t"+
+        "NOT \t"+
+        "ANY\t"+
+        "KEY\t"+
+        "QUAL\t"+
+        "VAL\t"+
+        "COL\t"+
+        "NAME\t"+
+        "DIR\n");
+  }
 }
\ No newline at end of file
diff --git a/uk/ac/sanger/artemis/circular/TrackViewer.java b/uk/ac/sanger/artemis/circular/TrackManager.java
similarity index 75%
rename from uk/ac/sanger/artemis/circular/TrackViewer.java
rename to uk/ac/sanger/artemis/circular/TrackManager.java
index 833f744b0fb8da4542001d1e2a54e74969ecc713..aec1accef32d8122e1feed990a08ff7ead3342d4 100644
--- a/uk/ac/sanger/artemis/circular/TrackViewer.java
+++ b/uk/ac/sanger/artemis/circular/TrackManager.java
@@ -29,13 +29,24 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
+import javax.swing.JFileChooser;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
@@ -51,11 +62,12 @@ import uk.ac.sanger.artemis.FeaturePredicateVector;
 import uk.ac.sanger.artemis.FeatureVector;
 import uk.ac.sanger.artemis.components.KeyChoice;
 import uk.ac.sanger.artemis.components.QualifierChoice;
+import uk.ac.sanger.artemis.components.StickyFileChooser;
 import uk.ac.sanger.artemis.io.Key;
 import uk.ac.sanger.artemis.io.Range;
 import uk.ac.sanger.artemis.io.RangeVector;
 
-class TrackViewer extends JFrame
+class TrackManager extends JFrame
 {
   private static final long serialVersionUID = 1L;
   private DNADraw dnaDraw;
@@ -70,21 +82,147 @@ class TrackViewer extends JFrame
   private TextFieldFloat trackSize[];
   private TextFieldFloat trackPosition[];
   
-  public TrackViewer(final DNADraw dnaDraw)
+  public TrackManager(final DNADraw dnaDraw)
   {
     super("Track Manager");
     this.dnaDraw = dnaDraw;
     setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
+    
+    createMenu();
     JScrollPane jsp = new JScrollPane(getPanelComponents());
     getContentPane().add(jsp); 
     pack();
   }
   
-  protected void refresh()
+  /**
+   * Create a menu for the track manager.
+   */
+  private void createMenu()
   {
-    getContentPane().removeAll();
-    getContentPane().add(getPanelComponents()); 
-    pack();
+    final JMenu menuFile = new JMenu("File");
+    final JMenuBar menuBar = new JMenuBar();
+    setJMenuBar(menuBar);
+    menuBar.add(menuFile);
+    menuFile.add(getExportTrackTemplateMenuItem(this, dnaDraw));
+    menuFile.add(getImportTrackTemplateMenuItem(this));
+    final JMenuItem closeMenu = new JMenuItem("Close");
+    closeMenu.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        TrackManager.this.setVisible(false);
+      }
+    });
+    menuFile.add(closeMenu);
+  }
+  
+  protected JMenuItem getImportTrackTemplateMenuItem(final JFrame f)
+  {
+    final JMenuItem readTemplate = new JMenuItem("Import Track Template...");
+    readTemplate.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent arg0)
+      {
+        StickyFileChooser fileDialog = new StickyFileChooser();
+        int status = fileDialog.showOpenDialog(f);
+        if(status == JFileChooser.CANCEL_OPTION)
+          return;
+
+        final File fileRead = fileDialog.getSelectedFile();
+        if(!fileRead.exists())
+        {
+          JOptionPane.showMessageDialog(f, 
+              fileRead.getName()+" not found.", 
+              "Problem Reading File", 
+              JOptionPane.WARNING_MESSAGE);
+          return;
+        }
+        
+        try
+        {
+          final FileReader reader = new FileReader(fileRead);
+          BufferedReader inputStream = new BufferedReader(reader);
+          String inLine = null;
+          
+          Track[] tracks = Wizard.getTracks();
+          int trackCount = 0;
+
+          while ((inLine = inputStream.readLine()) != null) 
+          {
+            if(inLine.startsWith("#") || inLine.trim().equals(""))
+              continue;
+            
+            if(trackCount >= tracks.length)
+            {
+              addTrack();
+              tracks = Wizard.getTracks();
+            }
+            tracks[trackCount].setPropertiesFromTemplate(inLine);
+            trackCount++;
+          }
+          inputStream.close();
+          reader.close();
+          refresh();
+        }
+        catch(FileNotFoundException e)
+        {
+          e.printStackTrace();
+        }
+        catch(IOException e)
+        {
+          e.printStackTrace();
+        }
+      }
+    });
+    return readTemplate;
+  }
+  
+  /**
+   * Menu Item with associated ActionListener for exporting the properties
+   * of this track.
+   * @param f
+   * @return
+   */
+  protected static JMenuItem getExportTrackTemplateMenuItem(final JFrame f,
+                                                            final DNADraw dnaDraw)
+  {
+    final JMenuItem saveTemplate = new JMenuItem("Export Track Template...");
+    saveTemplate.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent arg0)
+      {
+        StickyFileChooser fileDialog = new StickyFileChooser();
+        int status = fileDialog.showSaveDialog(f);
+        if(status == JFileChooser.CANCEL_OPTION)
+          return;
+        
+        final File fileWrite = fileDialog.getSelectedFile();
+        if(fileWrite.exists())
+        {
+          status = JOptionPane.showConfirmDialog(f, fileWrite.getName()+
+                      " exists. Overwrite?", 
+                      "Selected File Exists", 
+                      JOptionPane.OK_CANCEL_OPTION);
+          if(status == JFileChooser.CANCEL_OPTION)
+            return;
+        }
+        
+        final Track[] tracks = Wizard.getTracks();
+        try
+        {
+          final Writer writer = new FileWriter(fileWrite);
+          Track.writeHeader(writer, dnaDraw);
+          for(int i=0; i<tracks.length; i++)
+            tracks[i].write(writer);
+          writer.close();
+        }
+        catch(IOException e)
+        {
+          e.printStackTrace();
+        }
+      }
+    });
+    return saveTemplate;
   }
   
   private JPanel getPanelComponents()
@@ -344,9 +482,7 @@ class TrackViewer extends JFrame
           pack();
  
           setVisible(true);
-          update(Wizard.getTracks(), keyChoice, qualifierChoice, qualifierValue,
-              notQualifier, showForward, showReverse,
-              showAny, trackSize, trackPosition);
+          update(Wizard.getTracks());
         }
       });
       optionBox.add(deleteTrack, c);
@@ -362,9 +498,7 @@ class TrackViewer extends JFrame
     {
       public void actionPerformed(ActionEvent e)
       {
-         update(tracks, keyChoice, qualifierChoice, qualifierValue,
-                notQualifier, showForward, showReverse,
-                showAny, trackSize, trackPosition);
+         update(tracks);
       }
     });
     
@@ -378,36 +512,39 @@ class TrackViewer extends JFrame
     {
       public void actionPerformed(ActionEvent e)
       {
-        Entry entry;
-        if(Wizard.getTracks().length > 0)
-          entry = Wizard.getTracks()[0].getEntry();
-        else
-          entry = dnaDraw.getArtemisEntryGroup().elementAt(0);
-        
-        Wizard.addTrack( entry );
-        getContentPane().removeAll();
-        
-        JScrollPane jsp = new JScrollPane(getPanelComponents());
-        getContentPane().add(jsp); 
-        pack();
-
-        setVisible(true);
+        addTrack();
       }
     });
     
     return optionBox;
   }
   
-  private void update(final Track[] tracks, 
-                      final KeyChoice keyChoice[], 
-                      final QualifierChoice qualifierChoice[],
-                      final JTextField qualifierValue[] ,
-                      final JCheckBox notQualifier[],
-                      final JCheckBox showForward[],
-                      final JCheckBox showReverse[],
-                      final JCheckBox showAny[],
-                      final TextFieldFloat trackSize[],
-                      final TextFieldFloat trackPosition[])
+  protected void refresh()
+  {
+    getContentPane().removeAll();
+    JScrollPane jsp = new JScrollPane(getPanelComponents());
+    getContentPane().add(jsp); 
+    pack();
+  }
+  
+  private void addTrack()
+  {
+    Entry entry;
+    if(Wizard.getTracks().length > 0)
+      entry = Wizard.getTracks()[0].getEntry();
+    else
+      entry = dnaDraw.getArtemisEntryGroup().elementAt(0);
+    
+    Wizard.addTrack( entry );
+    refresh();
+    setVisible(true);
+  }
+  
+  /**
+   * Update the tracks based on the Track Manager settings
+   * @param tracks
+   */
+  protected void update(final Track[] tracks)
   {      
     // update tracks
     for(int i=0; i<tracks.length; i++)
@@ -472,15 +609,21 @@ class TrackViewer extends JFrame
       }
       tracks[i].setShowForward(showForward[i].isSelected());
       tracks[i].setShowReverse(showReverse[i].isSelected());
+      tracks[i].setNotQualifier(!notQualifier[i].isSelected());
       tracks[i].setSize((float) trackSize[i].getValue());
       tracks[i].setPosition(trackPosition[i].getValue());
     }
     
     // update viewer
+    updateDNADraw(dnaDraw, tracks);
+  }
+  
+  
+  private static void updateDNADraw(final DNADraw dnaDraw, final Track[] tracks)
+  {
     dnaDraw.getBlock().removeAll(dnaDraw.getBlock());
     final FeatureVector features = dnaDraw.getArtemisEntryGroup().getAllFeatures();
     
-    
     for(int i=0; i<features.size(); i++)
     {   
       Feature f = features.elementAt(i);
diff --git a/uk/ac/sanger/artemis/circular/UserGraph.java b/uk/ac/sanger/artemis/circular/UserGraph.java
index 4b3346250aa8572f59f444839ac965d4c152a85f..fe6cd2fc9eca6ae9e5a824430d9be2d039834aca 100644
--- a/uk/ac/sanger/artemis/circular/UserGraph.java
+++ b/uk/ac/sanger/artemis/circular/UserGraph.java
@@ -55,12 +55,15 @@ public class UserGraph extends Graph
    *  The average calculated by readData ().
    **/
   private float average_value = 0;
+  
+  private Document document;
 
   
   public UserGraph(DNADraw currentDna, final Document document)
          throws IOException
   {
     super(currentDna);
+    this.document = document;
     
     final Reader document_reader = document.getReader();
     LinePushBackReader pushback_reader =
@@ -147,5 +150,10 @@ public class UserGraph extends Graph
     }
     average_value /= seqLength;
   }
+
+  public Document getDocument()
+  {
+    return document;
+  }
   
 }
\ No newline at end of file
diff --git a/uk/ac/sanger/artemis/circular/Wizard.java b/uk/ac/sanger/artemis/circular/Wizard.java
index 34cada978d1c283a5c682e6068e91dda02cf2fa7..495b81743d75622c00de3a0c5dcd129ec1b1c24d 100644
--- a/uk/ac/sanger/artemis/circular/Wizard.java
+++ b/uk/ac/sanger/artemis/circular/Wizard.java
@@ -24,14 +24,21 @@ package uk.ac.sanger.artemis.circular;
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Dimension;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
 import java.util.Vector;
 import java.util.Hashtable;
 
 import javax.swing.Box;
 import javax.swing.ButtonGroup;
+import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
+import javax.swing.JProgressBar;
 import javax.swing.JRadioButton;
 import javax.swing.JScrollPane;
 import javax.swing.JSeparator;
@@ -43,10 +50,17 @@ import uk.ac.sanger.artemis.Feature;
 import uk.ac.sanger.artemis.FeatureVector;
 import uk.ac.sanger.artemis.Options;
 import uk.ac.sanger.artemis.SimpleEntryGroup;
+import uk.ac.sanger.artemis.components.EntryFileDialog;
+import uk.ac.sanger.artemis.components.MessageDialog;
+import uk.ac.sanger.artemis.components.StickyFileChooser;
+import uk.ac.sanger.artemis.components.Utilities;
+import uk.ac.sanger.artemis.io.EntryInformation;
 import uk.ac.sanger.artemis.io.Range;
 import uk.ac.sanger.artemis.io.RangeVector;
 import uk.ac.sanger.artemis.sequence.Bases;
 import uk.ac.sanger.artemis.sequence.NoSequenceException;
+import uk.ac.sanger.artemis.util.Document;
+import uk.ac.sanger.artemis.util.DocumentFactory;
 import uk.ac.sanger.artemis.util.OutOfRangeException;
 
 
@@ -73,6 +87,18 @@ public class Wizard
                                      // option 2 - edit existing dna
     if(n == 0)
       dna = getDNADrawFromFile(dna_current);
+    else if(n == 3)
+    {
+      StickyFileChooser chooser = new StickyFileChooser();
+      chooser.showOpenDialog(null);
+
+      File fileTemplate = chooser.getSelectedFile();
+      if(!fileTemplate.exists())
+        JOptionPane.showMessageDialog(null, 
+            fileTemplate.getName()+" cannot be found!", 
+            "Missing File", JOptionPane.WARNING_MESSAGE);
+      loadTemplate(fileTemplate);
+    }
     else if(n == 1 || n == 2)
     {
       Vector block = new Vector();
@@ -165,8 +191,286 @@ public class Wizard
   
       s = la.getEnd();
       dna.setEnd(s);
+    }
+  }
+  
+  /**
+   * Open a DNA plot based on a template file
+   * @param template
+   */
+  public Wizard(final File template)
+  {
+    loadTemplate(template);
+  }
+  
+  /**
+   * Load from a template file
+   * @param template
+   */
+  private void loadTemplate(final File template)
+  {
+    final JFrame f = new JFrame();
+    f.setUndecorated(true);
+    JPanel panel = (JPanel) f.getContentPane();
+    JProgressBar progress = new JProgressBar(1,10);
+    progress.setStringPainted(true);
+    progress.setString("Reading from "+template.getName()+"   ");
+    progress.setValue(2);
+    progress.setPreferredSize(new Dimension(350, progress.getPreferredSize().height));
+    panel.add(progress, BorderLayout.CENTER);
+    f.pack();
+    Utilities.centreFrame(f);
+    f.setVisible(true);
+    
+    if(dna == null)
+      dna = new DNADraw();
+    Options.getOptions();
+    
+
+    try
+    {
+      final FileReader reader = new FileReader(template);
+      final BufferedReader inputStream = new BufferedReader(reader);
+      final EntryGroup entryGroup = new SimpleEntryGroup();
+      final Hashtable fileEntrys = new Hashtable();
+      Vector v_tracks = new Vector();
+      String inLine = null;
+      String lineAttrStr[]  = null;
+      String tickMarksStr[] = null;
+      String gcGraphStr[]      = null;
+      String gcSkewGraphStr[]  = null;
+      String userGraphStr[]    = null;
+      
+      String lineAttrStart    = "# line attributes:";
+      String tickMarksStart   = "# tick marks:";
+      String gcGraphStart     = "# GC Graph:";
+      String gcSkewGraphStart = "# GC Skew Graph:";
+      String userGraphStart   = "# User Graph:";
+      
+      while((inLine = inputStream.readLine()) != null)
+      {
+        if(inLine.startsWith("#") || inLine.trim().equals(""))
+        {
+          if(inLine.startsWith(lineAttrStart))
+            lineAttrStr = inLine.substring(lineAttrStart.length()).trim().split("[=\\s]");
+          else if(inLine.startsWith(tickMarksStart))
+            tickMarksStr = inLine.substring(tickMarksStart.length()).trim().split("[=\\s]");
+          else if(inLine.startsWith(gcGraphStart))
+            gcGraphStr = inLine.substring(gcGraphStart.length()).trim().split("[=\\s]");
+          else if(inLine.startsWith(gcSkewGraphStart))
+            gcSkewGraphStr = inLine.substring(gcSkewGraphStart.length()).trim().split("[=\\s]");
+          else if(inLine.startsWith(userGraphStart))
+            userGraphStr = inLine.substring(userGraphStart.length()).trim().split("[=\\s]");
+          continue;
+        }
+
+        String properties[] = inLine.split("\t");
+        String fileName = properties[11] + File.separator + properties[10];
+        Entry entry;
+        if(!fileEntrys.containsKey(fileName))
+        {
+          progress.setString("Reading "+properties[10]);
+          progress.setValue(4);
+          entry = getEntry(fileName, entryGroup);
+          if(entry == null)
+            continue;
+          fileEntrys.put(fileName, entry);
+        }
+        else
+        {
+          entry = (Entry)fileEntrys.get(fileName);
+        }
+        
+        Track track = new Track(.9,entry);
+        track.setPropertiesFromTemplate(inLine);
+        v_tracks.add(track);
+      }
+      inputStream.close();
+      reader.close();
+      
+      progress.setString("Read template "+template.getName());
+      progress.setValue(7);
+      Track[] newTracks = new Track[v_tracks.size()];
+      for(int i=0; i<v_tracks.size(); i++)
+        newTracks[i] = (Track) v_tracks.get(i);
+      
+      Wizard.tracks = newTracks;
+
+      dna.setArtemisEntryGroup(entryGroup);
+
+      int sequenceLength = entryGroup.getSequenceEntry().getBases().getLength();
+      
+      Hashtable lineAttr = new Hashtable();
+      lineAttr.put("lsize", new Integer(1));
+      lineAttr.put("circular", new Boolean(true));
+      lineAttr.put("start", new Integer(0));
+      lineAttr.put("end", new Integer(sequenceLength));
+      if(lineAttrStr != null)
+      {
+        for(int i=0; i<lineAttrStr.length; i++)
+        {
+          if(lineAttrStr[i].startsWith("line_size"))
+            lineAttr.put("lsize", new Integer(lineAttrStr[i+1]));
+          else if(lineAttrStr[i].startsWith("circular"))
+            lineAttr.put("circular", new Boolean(lineAttrStr[i+1]));
+          else if(lineAttrStr[i].startsWith("line_height"))
+            dna.setLineHeight(Float.parseFloat(lineAttrStr[i+1]));
+          else if(lineAttrStr[i].startsWith("bases_per_line"))
+            dna.setBasesPerLine(Integer.parseInt(lineAttrStr[i+1]));
+        }
+      }
+      dna.setLineAttributes(lineAttr);
+
+      final int div;
+      if(sequenceLength < 1000)
+        div = 100;
+      else if(sequenceLength < 10000)
+        div = 1000;
+      else if(sequenceLength < 100000)
+        div = 10000;
+      else
+        div = 100000;
+      int tick = sequenceLength / div;
+      tick = tick * (div / 10);
+      int tick2 = tick / 2;
+      tick = tick2 * 2;
+      
+      if(tickMarksStr != null)
+      {
+        for(int i=0; i<tickMarksStr.length; i++)
+        {
+          if(tickMarksStr[i].startsWith("major"))
+            tick = Integer.parseInt(tickMarksStr[i+1]);
+          else if(tickMarksStr[i].startsWith("minor"))
+            tick2 = Integer.parseInt(tickMarksStr[i+1]);
+        }
+      }
+
+      dna.setGeneticMarker(new Vector());
+      dna.setRestrictionEnzyme(new Vector());
+      dna.setMinorTickInterval(tick2);
+      dna.setTickInterval(tick);
+      
+      TrackManager trackManager = dna.getTrackManager();
+      if(trackManager == null)
+      {
+        trackManager = new TrackManager(dna);
+        dna.setTrackManager(trackManager);
+      }
+      trackManager.update(tracks);
+      loadGraphs(gcGraphStr, gcSkewGraphStr, userGraphStr, dna, progress);
+    }
+    catch(FileNotFoundException e)
+    {
+      e.printStackTrace();
+    }
+    catch(IOException e)
+    {
+      e.printStackTrace();
+    }
+    catch(NoSequenceException e)
+    {
+      e.printStackTrace();
+    }
+    f.dispose();
+  }
+  
+  /**
+   * 
+   * @param gcGraphStr
+   * @param gcSkewGraphStr
+   * @param userGraphStr
+   * @param dna
+   */
+  private void loadGraphs(final String gcGraphStr[], 
+                          final String gcSkewGraphStr[], 
+                          final String userGraphStr[],
+                          final DNADraw dna,
+                          final JProgressBar progress)
+  {
+    if(gcGraphStr != null)
+    {
+      if(progress != null)
+        progress.setString("Calculating GC graph points");
+      GCGraph gcGraph = new GCGraph(dna);
+      gcGraph.setOptionsStr(gcGraphStr);
+      dna.setGcGraph(gcGraph);
+      gcGraph.calcGraphValues();
+      dna.add(gcGraph);
+    }
+    if(gcSkewGraphStr != null)
+    {
+      if(progress != null)
+        progress.setString("Calculating GC Skew graph points");
+      GCSkewGraph gcSkewGraph = new GCSkewGraph(dna);
+      gcSkewGraph.setOptionsStr(gcSkewGraphStr);
+      dna.setGcSkewGraph(gcSkewGraph);
+      gcSkewGraph.calcGraphValues();
+      dna.add(gcSkewGraph);
+    }
+    if(userGraphStr != null)
+    {
+      String fileName = null;
+      for(int i=0;i<userGraphStr.length; i++)
+      {
+        if(userGraphStr[i].startsWith("file_name"))
+          fileName = userGraphStr[i+1];
+      }
+      final uk.ac.sanger.artemis.util.Document document =
+        new uk.ac.sanger.artemis.util.FileDocument(new File(fileName));
+      try
+      {
+        if(progress != null)
+          progress.setString("Calculating user graph points");
+        UserGraph userGraph = new UserGraph(dna, document);
+        userGraph.setOptionsStr(userGraphStr);
+        dna.setUserGraph(userGraph);
+        userGraph.calcGraphValues();
+        dna.add(userGraph);
+      }
+      catch(IOException e)
+      {
+        e.printStackTrace();
+        return;
+      }
+    }
+  }
+  
+  private Entry getEntry(final String entryFileName, final EntryGroup entryGroup) 
+                   throws NoSequenceException
+  {
+    final Document entry_document = DocumentFactory.makeDocument(entryFileName);
+    final EntryInformation artemis_entry_information =
+      Options.getArtemisEntryInformation();
+    
+    final uk.ac.sanger.artemis.io.Entry new_embl_entry =
+      EntryFileDialog.getEntryFromFile(null, entry_document,
+                                       artemis_entry_information,
+                                       false);
+
+    if(new_embl_entry == null)  // the read failed
+      return null;
 
+    Entry entry = null;
+    try
+    {
+      Bases bases = null;
+      if(entryGroup.getSequenceEntry() != null)
+        bases = entryGroup.getSequenceEntry().getBases();
+      if(bases == null)
+        entry = new Entry(new_embl_entry);
+      else
+        entry = new Entry(bases,new_embl_entry);
+      
+      entryGroup.add(entry);
+    } 
+    catch(OutOfRangeException e) 
+    {
+      new MessageDialog(null, "read failed: one of the features in " +
+          entryFileName + " has an out of range " +
+                        "location: " + e.getMessage());
     }
+    return entry;
   }
 
   /**
@@ -377,10 +681,8 @@ public class Wizard
 
     JRadioButton[] radioButtons;
 
-    if(dna_current !=  null)
-      radioButtons = new JRadioButton[3];
-    else
-      radioButtons = new JRadioButton[2];
+    radioButtons = new JRadioButton[3];
+
     final ButtonGroup group = new ButtonGroup();
     radioButtons[0] = new JRadioButton("Read in sequence file");
     group.add(radioButtons[0]);
@@ -390,14 +692,20 @@ public class Wizard
     bdown.add(radioButtons[0]);
     bdown.add(radioButtons[1]);
 
+    radioButtons[0].setSelected(true);
     if(dna_current !=  null)
     {
       radioButtons[2] = new JRadioButton("Edit current dna display");
       group.add(radioButtons[2]);
       radioButtons[2].setSelected(true);
-      bdown.add(radioButtons[2]);
     }
-
+    else
+    {
+      radioButtons[2] = new JRadioButton("Read template file");
+      group.add(radioButtons[2]);  
+    }
+    bdown.add(radioButtons[2]);
+    
     JPanel pane = new JPanel(new BorderLayout());
     pane.add(bdown);
     JOptionPane.showMessageDialog(null, 
@@ -408,8 +716,10 @@ public class Wizard
       return 0;
     else if(radioButtons[1].isSelected())
       return 1;
-    else if(radioButtons[2].isSelected())
+    else if(radioButtons[2].isSelected() && dna_current !=  null)
       return 2;
+    else if(radioButtons[2].isSelected())
+      return 3;
      
     return 1;
   }