diff --git a/uk/ac/sanger/artemis/components/database/DatabaseJPanel.java b/uk/ac/sanger/artemis/components/database/DatabaseJPanel.java
index 9e4ba111b7f968af7f9be26b5ec025a83ef11aff..170d4e0c4836a908378eff203c728efb8d05fba3 100644
--- a/uk/ac/sanger/artemis/components/database/DatabaseJPanel.java
+++ b/uk/ac/sanger/artemis/components/database/DatabaseJPanel.java
@@ -20,7 +20,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
- * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/database/DatabaseJPanel.java,v 1.18 2008-10-30 15:37:00 tjc Exp $
+ * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/database/DatabaseJPanel.java,v 1.19 2008-11-17 13:51:57 tjc Exp $
  */
 
 package uk.ac.sanger.artemis.components.database;
@@ -45,6 +45,7 @@ import javax.swing.BorderFactory;
 import javax.swing.border.Border;
 import javax.swing.tree.TreePath;
 
+import org.gmod.schema.organism.Organism;
 import org.gmod.schema.sequence.Feature;
 
 import java.awt.BorderLayout;
@@ -56,15 +57,8 @@ import java.awt.Toolkit;
 import java.awt.Cursor;
 import java.awt.FontMetrics;
 import java.io.*;
-import java.net.ConnectException;
-import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.List;
-import java.util.Vector;
 
 public class DatabaseJPanel extends JPanel
 {
@@ -140,11 +134,7 @@ public class DatabaseJPanel extends JPanel
       DatabaseTreeNode seq_node = 
         (DatabaseTreeNode)path.getLastPathComponent();
       String node_name = (String)seq_node.getUserObject();
-      String userName;
-      if(!doc.isSingleSchema())
-        userName = seq_node.getSchema();
-      else
-        userName = doc.getUserName();
+      String userName = doc.getUserName();
 
       String id = seq_node.getFeatureId(); 
       if(id != null)
@@ -241,6 +231,8 @@ public class DatabaseJPanel extends JPanel
         srcComponent.setCursor(cbusy);
         try
         {
+          while(DatabaseDocument.isCvThreadAlive())
+            Thread.sleep(5);
           openEntry(srcfeatureId, entry_source, srcComponent, status_line, stream_progress_listener,
               splitGFFEntry, splash_main, dbDocumentName, userName, null);
         }
@@ -260,6 +252,10 @@ public class DatabaseJPanel extends JPanel
           openEntry(srcfeatureId, entry_source, srcComponent, status_line, stream_progress_listener,
               splitGFFEntry, splash_main, dbDocumentName, userName, null);
         }
+        catch(InterruptedException e)
+        {
+          e.printStackTrace();
+        }
         srcComponent.setCursor(cdone);
         return null;
       }
@@ -369,115 +365,31 @@ public class DatabaseJPanel extends JPanel
       try
       {
         doc = entry_source.getDatabaseDocument();
-        entries = doc.getDatabaseEntries();
-        
         final DatabaseTreeNode top = new DatabaseTreeNode("");
-        createNodes(top, doc, entries);
+        
+        final List organisms = doc.getOrganismsContainingSrcFeatures();
+        for(int i=0; i<organisms.size(); i++)
+        {
+          Organism org = (Organism)organisms.get(i);
+          
+          String name = org.getCommonName();
+          if(name == null || name.equals(""))
+            name = org.getGenus() + "." + org.getSpecies();
+          DatabaseTreeNode orgNode = 
+            new DatabaseTreeNode(name, false, org, doc.getUserName(), doc);
+          top.add(orgNode); 
+        }
         return new DatabaseJTree(top);
       }
-      catch(ConnectException e)
-      {
-        entry_source.setLocation(true);
-      }
-      catch(SQLException e)
-      {
-        entry_source.setLocation(true);
-      }
-      catch(RuntimeException p)
+      catch(Exception e)
       {
-        entry_source.setLocation(true);
+        if(!entry_source.setLocation(true))
+          return null;
       }
     }
 
     return null;
   }
-
-
-  /**
-   * Create the nodes of the organism JTree
-   * @param top       root node
-   * @param schema    <code>List</code>
-   * @param doc       DatabaseDocument
-   * @param organism  sequences collection
-   */
-  private void createNodes(DatabaseTreeNode top,
-                           DatabaseDocument doc,
-                           HashMap entries)
-  {
-    final Object v_organism[] = entries.keySet().toArray();
-    final int v_organism_size = v_organism.length;
-    Arrays.sort(v_organism, new Comparator()
-    {
-      public int compare(Object o1, Object o2)
-      {
-        return ((String)o1).compareToIgnoreCase( (String)o2 );
-      } 
-    });
-    
-    final Hashtable organismNodes = new Hashtable();
-    final List organism = new Vector();
-    
-    String seqFullName;
-    DatabaseTreeNode seq_node;
-    DatabaseTreeNode typ_node;
-
-    for(int i = 0; i < v_organism_size; i++)
-    {
-      seqFullName = (String) v_organism[i];
-      String seqNames[] = seqFullName.split("-");
-      
-      final String featureId = (String) entries.get(seqFullName);
-      final String schema = seqNames[0].trim();
-      String type = seqNames[1].trim();
-      String thisSeqName = seqNames[2].trim();
-      
-      if(!organismNodes.containsKey(schema))
-      {
-        organismNodes.put(schema, new DatabaseTreeNode(schema));
-        organism.add(schema);
-      }
-      
-      DatabaseTreeNode organismNode = (DatabaseTreeNode) organismNodes.get(schema);
-      typ_node = getChild(organismNode, type);
-      if(typ_node == null)
-      {
-        typ_node = new DatabaseTreeNode(type);
-        organismNode.add(typ_node);
-      }
-
-      seq_node = new DatabaseTreeNode(thisSeqName, featureId, schema,
-                            doc.getUserName(), doc.isSingleSchema());
-      typ_node.add(seq_node);
-    }
-    
-    // add organism nodes that have child nodes
-    Collections.sort(organism);   
-    for(int i=0; i<organism.size(); i++)
-    {
-      String name = (String) organism.get(i);
-      DatabaseTreeNode organismNode = (DatabaseTreeNode) organismNodes.get(name);
-      if(organismNode.getChildCount() > 0)
-        top.add(organismNode);
-    }
-  }
-  
-  /**
-   * Get a child of a parent node with a given name.
-   * @param parentNode
-   * @param childNodeName
-   * @return
-   */
-  private DatabaseTreeNode getChild(final DatabaseTreeNode parentNode,
-                                    final String childNodeName)
-  {
-    for(int j=0; j<parentNode.getChildCount(); j++)
-    {
-      DatabaseTreeNode node = (DatabaseTreeNode) parentNode.getChildAt(j);
-      if(((String)node.getUserObject()).equals(childNodeName))
-        return node;
-    }
-    return null;
-  }
   
   /**
    * An InputStreamProgressListener used to update the error label with the
diff --git a/uk/ac/sanger/artemis/components/database/DatabaseJTree.java b/uk/ac/sanger/artemis/components/database/DatabaseJTree.java
index 3a3361c1ae48176b013b9704e36119eee5eee66e..0592f1b26a558e1fadb20327814eca3a5f4e823f 100644
--- a/uk/ac/sanger/artemis/components/database/DatabaseJTree.java
+++ b/uk/ac/sanger/artemis/components/database/DatabaseJTree.java
@@ -25,6 +25,7 @@
 package uk.ac.sanger.artemis.components.database;
 
 
+import java.awt.Cursor;
 import java.awt.Point;
 import java.awt.datatransfer.Transferable;
 import java.awt.dnd.DnDConstants;
@@ -39,6 +40,9 @@ import java.awt.event.InputEvent;
 import java.awt.event.MouseEvent;
 
 import javax.swing.JTree;
+import javax.swing.event.TreeExpansionEvent;
+import javax.swing.event.TreeExpansionListener;
+import javax.swing.tree.DefaultTreeModel;
 import javax.swing.tree.TreePath;
 import javax.swing.tree.TreeSelectionModel;
 
@@ -72,7 +76,31 @@ public class DatabaseJTree extends JTree
       dragSource.createDefaultDragGestureRecognizer(
          this,                             // component where drag originates
          DnDConstants.ACTION_COPY_OR_MOVE, // actions
-         this);                            // drag gesture recognizer   
+         this);                            // drag gesture recognizer
+      
+      addTreeExpansionListener(new TreeExpansionListener() 
+      {
+        public void treeExpanded(TreeExpansionEvent e)
+        {
+          TreePath path = e.getPath();
+          if(path != null) 
+          {
+            setCursor(new Cursor(Cursor.WAIT_CURSOR));
+            DatabaseTreeNode node = (DatabaseTreeNode)path.getLastPathComponent();
+
+            if(!node.isExplored()) 
+            {
+              node.explore();
+              DefaultTreeModel model = (DefaultTreeModel)getModel();
+              model.nodeStructureChanged(node);
+            }
+            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+          }
+        }
+        public void treeCollapsed(TreeExpansionEvent e){}
+      });
+
+
     }
 
     private boolean isLeafSelection()
diff --git a/uk/ac/sanger/artemis/components/database/DatabaseTreeNode.java b/uk/ac/sanger/artemis/components/database/DatabaseTreeNode.java
index d18f18423a85a18e2d38203c92810ca8e788dcce..3f042dc355f6e0a1a61a6b4a02ffbf9d052abd82 100644
--- a/uk/ac/sanger/artemis/components/database/DatabaseTreeNode.java
+++ b/uk/ac/sanger/artemis/components/database/DatabaseTreeNode.java
@@ -29,8 +29,15 @@ import java.awt.datatransfer.DataFlavor;
 import java.awt.datatransfer.UnsupportedFlavorException;
 import javax.swing.tree.DefaultMutableTreeNode;
 
+import org.gmod.schema.organism.Organism;
+import org.gmod.schema.sequence.Feature;
+
+import uk.ac.sanger.artemis.util.DatabaseDocument;
+
 import java.io.Serializable;
 import java.io.IOException;
+import java.util.Hashtable;
+import java.util.List;
 
 /**
 *
@@ -40,7 +47,7 @@ import java.io.IOException;
 public class DatabaseTreeNode extends DefaultMutableTreeNode 
                  implements Transferable, Serializable
 {
-  
+  private static final long serialVersionUID = 1L;
   public static final DataFlavor DATABASETREENODE = 
           new DataFlavor(DatabaseTreeNode.class, "Work Package");
   public static final DataFlavor STRING_DATA_FLAVOUR = 
@@ -48,29 +55,106 @@ public class DatabaseTreeNode extends DefaultMutableTreeNode
   private static final DataFlavor flavors[] = 
          { DATABASETREENODE, DataFlavor.stringFlavor };
   
-  
   private String featureId;
-  private String schema;
+  private Organism organism;
+  private boolean isLeaf = false;
   private String userName;
-  private boolean singleSchema;
-    
+  private DatabaseDocument dbDoc;
+  private boolean explored = false;
+   
   public DatabaseTreeNode(final String name)
   { 
     super(name);
   }
+  
+  public DatabaseTreeNode(final String name, 
+                          final boolean isLeaf)
+  {
+    super(name);
+    this.isLeaf = isLeaf;
+  }
+    
+  /**
+   * Top node constructor
+   * @param name
+   * @param isLeaf
+   * @param organism
+   * @param userName
+   * @param dbDoc
+   */
+  public DatabaseTreeNode(final String name, 
+                          final boolean isLeaf,
+                          final Organism organism,
+                          final String userName,
+                          final DatabaseDocument dbDoc)
+  { 
+    super(name);
+    this.isLeaf   = isLeaf;
+    this.organism = organism;
+    this.userName = userName;
+    this.dbDoc    = dbDoc;
+  }
 
+  /**
+   * Leaf constructor
+   * @param name
+   * @param organism
+   * @param featureId
+   * @param userName
+   */
   public DatabaseTreeNode(final String name,
+                          final Organism organism,
                           final String featureId,
-                          final String schema,
-                          final String userName,
-                          final boolean singleSchema)
+                          final String userName)
   { 
     super(name);
-    this.featureId    = featureId;
-    this.schema       = schema;
-    this.userName     = userName;
-    this.singleSchema = singleSchema;
+    this.organism  = organism;
+    this.featureId = featureId;
+    this.userName  = userName;
+  }
+  
+  /** @return   true if node is a directory */
+  public boolean getAllowsChildren() { return !isLeaf; }
+  /** @return         true if node is a file */
+  public boolean isLeaf() { return isLeaf; }
+  /** @return         true if node is a directory */
+  public boolean isDirectory() { return !isLeaf; }
+  /** @return         true if explored */
+  public boolean isExplored() { return explored; }
+
+  /**
+   * Explore the tree node if this is a node with child nodes.
+   */
+  public void explore()
+  {
+    if(isLeaf)
+      return;
+    
+    List sequenceList = dbDoc.getResidueFeatures(new Integer(getOrganism().getOrganismId()));
+    Hashtable sequenceNode = new Hashtable();
+    
+    for(int i=0;i<sequenceList.size(); i++)
+    {
+      Feature f = (Feature)sequenceList.get(i);
+      DatabaseTreeNode typeNode;
+      if(!sequenceNode.containsKey(f.getCvTerm().getName()))
+      {
+        typeNode = new DatabaseTreeNode(f.getCvTerm().getName(), false);
+        add(typeNode);
+        sequenceNode.put(f.getCvTerm().getName(), typeNode);
+      }
+      else
+        typeNode = (DatabaseTreeNode) sequenceNode.get(f.getCvTerm().getName());
+      
+      DatabaseTreeNode seqNode = new DatabaseTreeNode(
+          f.getUniqueName(), getOrganism(), Integer.toString(f.getFeatureId()), getUserName());
+      seqNode.isLeaf = true;
+      typeNode.add(seqNode);
+      typeNode.explored = true;
+    }
+    explored = true;
   }
+  
     
 // Transferable
   public DataFlavor[] getTransferDataFlavors()
@@ -90,10 +174,15 @@ public class DatabaseTreeNode extends DefaultMutableTreeNode
   {
     if(d.equals(DATABASETREENODE))
       return new DatabaseTreeNode((String)getUserObject(), 
-                                  getFeatureId(), getSchema(),
-                                  getUserName(), isSingleSchema());
+                                  organism,
+                                  getFeatureId(), getUserName());
     else if(d.equals(DataFlavor.stringFlavor))
-      return getSchema()+":featureId="+getFeatureId();
+    {
+      String name = getOrganism().getCommonName();
+      if(name == null || name.equals(""))
+        name = getOrganism().getGenus() + "." + getOrganism().getSpecies();
+      return name+":featureId="+getFeatureId();
+    }
     else throw new UnsupportedFlavorException(d);
   }
 
@@ -103,15 +192,6 @@ public class DatabaseTreeNode extends DefaultMutableTreeNode
     return featureId;
   }
 
-  public String getSchema()
-  {
-    return schema;
-  }
-  
-  public boolean isSingleSchema()
-  {
-    return singleSchema;
-  }
   
 //Serializable
   private void writeObject(java.io.ObjectOutputStream out) throws IOException
@@ -125,11 +205,14 @@ public class DatabaseTreeNode extends DefaultMutableTreeNode
     in.defaultReadObject();
   }
 
+  public Organism getOrganism()
+  {
+    return organism;
+  }
+
   public String getUserName()
   {
     return userName;
   }
 
-
-
 }