[med-svn] [dazzle] 12/14: New upstream version 1.0.1r3643

Andreas Tille tille at debian.org
Tue Dec 5 13:28:42 UTC 2017


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository dazzle.

commit 79dee8469f78956d49ce5957a13125753bd818f3
Author: Andreas Tille <tille at debian.org>
Date:   Tue Dec 5 14:26:59 2017 +0100

    New upstream version 1.0.1r3643
---
 build.xml                                          |  219 +++
 dazzle-webapp/WEB-INF/web.xml                      |   25 +
 dazzle-webapp/das.xsl                              |  914 ++++++++++
 dazzle-webapp/das_welcome.html                     |    6 +
 dazzle-webapp/dazzlecfg.xml                        |   56 +
 dazzle-webapp/example.up                           |  158 ++
 dazzle-webapp/fickett-tss.gff                      |   44 +
 dazzle-webapp/sources.xml                          |   26 +
 dazzle-webapp/test.embl                            | 1774 ++++++++++++++++++++
 dazzle-webapp/test.style                           |   17 +
 dazzle-webapp/tss.style                            |   17 +
 dazzle-webapp/welcome.html                         |    6 +
 debian/README.Debian                               |   23 -
 debian/changelog                                   |   12 -
 debian/compat                                      |    1 -
 debian/control                                     |   27 -
 debian/copyright                                   |   29 -
 debian/dirs                                        |    2 -
 debian/docs                                        |    1 -
 debian/rules                                       |   66 -
 debian/source/format                               |    1 -
 debian/watch                                       |    3 -
 docs/background.png                                |  Bin 0 -> 19517 bytes
 docs/deploy.html                                   |  312 ++++
 docs/docs.css                                      |   25 +
 manifest/dazzle.txt                                |    4 +
 .../org.biojava.servlets.dazzle.DazzleHandler      |   10 +
 resources/css/content.css                          |  475 ++++++
 resources/css/dazzle.css                           |  286 ++++
 resources/css/printer-styles.css                   |   18 +
 resources/css/screen-styles.css                    |   36 +
 resources/org/biodas/das1/dasdna.dtd               |    8 +
 resources/org/biodas/das1/dasdsn.dtd               |    8 +
 resources/org/biodas/das1/dasep.dtd                |   11 +
 resources/org/biodas/das1/dasgff.dtd               |   35 +
 resources/org/biodas/das1/dasres.dtd               |   11 +
 resources/org/biodas/das1/dassequence.dtd          |    7 +
 resources/org/biodas/das1/dasstyle.dtd             |   32 +
 resources/org/biodas/das1/dastypes.dtd             |   14 +
 src/META-INF/MANIFEST.MF                           |    3 +
 .../servlets/dazzle/AbstractDazzleHandler.java     |   53 +
 .../biojava/servlets/dazzle/AlignmentHandler.java  |  279 +++
 .../servlets/dazzle/DASQueryStringTranslator.java  |  121 ++
 src/org/biojava/servlets/dazzle/DASStatus.java     |   68 +
 .../biojava/servlets/dazzle/DazzleException.java   |   83 +
 src/org/biojava/servlets/dazzle/DazzleHandler.java |   48 +
 .../biojava/servlets/dazzle/DazzleResponse.java    |  109 ++
 src/org/biojava/servlets/dazzle/DazzleServlet.java |  720 ++++++++
 src/org/biojava/servlets/dazzle/DazzleTools.java   |  181 ++
 .../servlets/dazzle/EntryPointsHandler.java        |   98 ++
 .../biojava/servlets/dazzle/FeaturesHandler.java   |  902 ++++++++++
 .../servlets/dazzle/GFFFeaturesHandler.java        |  408 +++++
 .../servlets/dazzle/HydraGFFFeaturesHandler.java   |  352 ++++
 .../servlets/dazzle/InteractionHandler.java        |  318 ++++
 src/org/biojava/servlets/dazzle/LinkHandler.java   |   79 +
 .../biojava/servlets/dazzle/SangerProxyFilter.java |  116 ++
 src/org/biojava/servlets/dazzle/Segment.java       |  106 ++
 .../biojava/servlets/dazzle/SequenceHandler.java   |  244 +++
 .../biojava/servlets/dazzle/StructureHandler.java  |  403 +++++
 .../biojava/servlets/dazzle/StylesheetHandler.java |   75 +
 .../datasource/AbstractBiojavaFeatureSource.java   |  362 ++++
 .../dazzle/datasource/AbstractDataSource.java      |  366 ++++
 .../datasource/AbstractDazzleDataSource.java       |  136 ++
 .../datasource/AbstractGFFFeatureSource.java       |  273 +++
 .../dazzle/datasource/AlignmentSource.java         |   82 +
 .../servlets/dazzle/datasource/AlignmentTools.java |  126 ++
 .../dazzle/datasource/BasicDazzleInstallation.java |  321 ++++
 .../dazzle/datasource/BioSQLDataSource.java        |  225 +++
 .../dazzle/datasource/BiojavaFeatureSource.java    |  213 +++
 .../servlets/dazzle/datasource/DASGFFGroup.java    |   87 +
 .../dazzle/datasource/DataSourceException.java     |   44 +
 .../dazzle/datasource/DazzleDataSource.java        |  290 ++++
 .../dazzle/datasource/DazzleInstallation.java      |   47 +
 .../dazzle/datasource/DazzleReferenceSource.java   |   83 +
 .../servlets/dazzle/datasource/EmblDataSource.java |  163 ++
 .../dazzle/datasource/FastaDataSource.java         |  116 ++
 .../dazzle/datasource/GFFAnnotationSource.java     |  351 ++++
 .../servlets/dazzle/datasource/GFFFeature.java     |  138 ++
 .../dazzle/datasource/GFFFeatureSource.java        |   34 +
 .../dazzle/datasource/HydraGFFFeatureSource.java   |   58 +
 .../datasource/InteractionReferenceSource.java     |   42 +
 .../servlets/dazzle/datasource/LdasDataSource.java |  572 +++++++
 .../dazzle/datasource/PhobiusExampleSource.java    |  181 ++
 .../dazzle/datasource/ProxyDataSource.java         |  205 +++
 .../dazzle/datasource/ProxyReferenceSource.java    |  168 ++
 .../dazzle/datasource/SIFReferenceSource.java      |  480 ++++++
 .../dazzle/datasource/StructureSource.java         |  216 +++
 .../dazzle/datasource/TilingFeatureSource.java     |   27 +
 .../dazzle/datasource/TypeMetadataSource.java      |   19 +
 .../dazzle/datasource/UniProtDataSource.java       |  167 ++
 .../dazzle/datasource/db/GFFFeatureCache.java      |   34 +
 .../dazzle/datasource/db/MysqlFeatureCache.java    |  358 ++++
 92 files changed, 15304 insertions(+), 165 deletions(-)

diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..ddbf81b
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,219 @@
+<?xml version="1.0"?>
+
+<!--
+
+  Ant build file for the entire biojava tree
+
+  see:
+  <a href="http://ant.apache.org/">Ant Project Homepage</a>
+
+  targets:
+
+    compile
+    compile-tests     compiles JUnit tests
+    compile-demos     compiles the demo files
+    compile-apps      compiles the application files
+    package-biojava   builds the biojava.jar file (default)
+    package-demos     builds the demos.jar file
+    package-apps      builds the jar.apps file
+    runtests          runs all tests (requires Ant 1.6.0 or later)
+    runtests-fork     runs all tests in separate virtual machines
+    javadocs-biojava  builds biojava API documentation
+    javadocs-taglets  builds taglets API documentation
+    javadocs-grammars builds grammars API documentation
+    javadocs-demos    builds demos API documentation
+    javadocs-all      builds API documentation for all the above
+    docbook           builds DocBook documentation
+    clean             cleans up the build & dist directories
+    
+  The 'runtests' target can be restricted to portions of the tree, e.g.:
+  
+       ant -Dtest.subtree=org/biojava/bio/symbol runtests
+       ant -Dtest.subtree=org/biojava/bio/seq/** runtests
+
+  author:  Michael Heuer, 
+           Keith James (JUnit support, DocBook support)
+           Greg Cox (fixed documentation)
+           Thomas Down (clean up, remove source-copying steps
+  version: $Id: build.xml,v 1.77 2004/01/27 21:31:50 thomasd Exp $
+
+  portions Copyright (c) 1999-2000 The Apache Software Foundation.
+
+-->
+
+<project name="dazzle" default="package-main" basedir=".">
+
+  <!-- Checks environment and setup variables -->
+  <target name="init" description="Checks environment and setup variables">
+    <tstamp />
+    <property name="version" value="live" />
+
+    <property name="build.compiler" value="modern" />
+
+    <property name="classpath" value="jars/biojava.jar:jars/bytecode.jar:jars/servlet-api-2.3.jar:jars/dasmi-model.jar" />
+
+    <property name="readme"         value="./README" />
+    <property name="license"        value="./LICENSE" />
+    <property name="src.dir"        value="./src" />
+    <property name="tests.dir"      value="./tests" />
+    <property name="demos.dir"      value="./demos" />
+    <property name="apps.dir"       value="./apps" />
+    <property name="docs.dir"       value="./docs" />
+    <property name="doc.css.file"   value="biojava-doc.css" />
+    <property name="reports.dir"    value="./reports" />
+    <property name="manifest.dir"   value="./manifest" />
+    <property name="resources.dir"  value="./resources" />
+    <property name="taglets.dir"    value="./taglets" />
+    <property name="webapp.dir"     value="./dazzle-webapp" />
+    <property name="thirdparty.dir" value="./thirdparty" />
+
+    <!-- Main build directory -->
+    <property name="build.dir" value="./ant-build" />
+    <property name="build.classes.dir" value="${build.dir}/classes" />
+
+    <!-- Javac properties -->
+    <property name="javac.depend" value="false" />
+    <property name="javac.debug" value="true" />
+    <property name="javac.deprecation" value="false" />
+    <property name="javac.source" value="1.5" />
+
+    <!-- Javadoc properties -->
+    <property name="build.dest.docs" value="${build.dir}/docs" />
+    <property name="build.dest.doccheck" value="${build.dir}/docs/check" />
+    <property name="packages" value="org.*" />
+
+    <!-- Subdirectories for main source and classes -->
+    <property name="name.main" value="dazzle" />
+    <property name="Name.main" value="Dazzle" />
+    <property name="build.dest.main" value="${build.classes.dir}/${name.main}" />
+    <property name="build.docs.main" value="${build.dest.docs}/${name.main}" />
+    <property name="jar.main" value="${build.dir}/${name.main}.jar" />
+    <property name="manifest.file.main" value="${manifest.dir}/${name.main}.txt" />
+    <!-- Subdirectory for libraries used during build -->
+    <property name="build.lib" value="${build.dir}/lib" />
+    
+    <!-- Echo information -->
+    <echo message="Building ${name.main}-${version}" />
+  </target>
+
+
+  <!--
+    Prepare each part of the project.
+
+    Each preparation creates working directories and copies files over.
+  -->
+
+  <!-- Prepares the basic stuff -->
+  <target name="prepare" depends="init" description="creates basic directories">
+    <!-- Creates directories -->
+    <mkdir dir="${build.dir}" />
+    <mkdir dir="${build.lib}" />
+
+    <!-- Copies jars -->
+    <copy todir="${build.dir}">
+      <fileset dir=".">
+        <include name="*.jar" />
+      </fileset>
+    </copy>
+
+  </target>
+  
+  <!-- Prepares the biojava source code -->
+  <target name="prepare-main" depends="prepare"
+  description="Prepares biojava source files">
+    <!-- Creates directories -->
+    <mkdir dir="${build.dest.main}" />
+    <mkdir dir="${build.docs.main}" />
+  </target>
+
+  <!-- Prepares the javadocs -->
+  <target name="prepare-javadocs" depends="prepare" description="Prepares the javadocs">
+
+    <!-- Creates directories -->
+    <mkdir dir="${build.dest.docs}" />
+  </target>
+
+
+  <!-- Compiles the source directory -->
+  <target name="compile-main" depends="prepare-main"
+  description="Compiles the source directory">
+    <javac
+      destdir="${build.dest.main}"
+      depend="${javac.depend}"
+      deprecation="${javac.deprecation}"
+      debug="${javac.debug}"
+      srcdir="${src.dir}">
+      <classpath>
+        <pathelement path="${classpath}" />
+      </classpath>
+      
+      <filename name="org/biojava/**/*.java" />
+    </javac>
+  </target>
+
+  <!--
+    Creates the .jar files containing each distributable component.
+
+    This probably just jars up the .class files and any resources as well as
+    a manifest for each distributable component.
+  -->
+
+  <!-- Creates the biojava package (tests are left in the parallel tree) -->
+  
+  <!-- this ought to depend on compile-grammars at well, but until conditional
+        sablecc works, that's a Bad Idea -->
+  
+  <target name="package-main" depends="compile-main"
+  description="create main class jar file">
+    <jar
+      jarfile="${jar.main}"
+      manifest="${manifest.file.main}"
+    >
+      <fileset dir="${build.dest.main}" />
+      <fileset dir="${resources.dir}" />
+    </jar>
+  </target>
+
+
+ <target name="dazzle-war" depends="init,prepare,prepare-main,compile-main,package-main">
+      <war 	destfile="dazzle.war" 
+      		webxml="${webapp.dir}/WEB-INF/web.xml" 		
+         	manifest="${manifest.file.main}" 	
+	>
+	<lib     dir="${build.dir}"/>
+	<lib     dir="${thirdparty.dir}"/>
+	<classes dir="${build.classes.dir}"/>
+	<fileset dir="${webapp.dir}"/>	   
+      </war>
+  </target>
+
+  
+
+  <!-- Creates the API documentation -->
+  <target name="javadocs-main" depends="prepare-main"
+  description="Creates the API documentation">
+    <javadoc
+      packagenames="${packages}"
+      sourcepath="${src.dir}"
+      classpath="${classpath}"
+      destdir="${build.docs.main}"
+      author="true"
+      version="true"
+      use="true"
+      source="1.4"
+      windowtitle="${Name.main} API"
+      doctitle="${Name.main}"
+      maxmemory="96m">
+       <link href="http://java.sun.com/j2se/1.4.2/docs/api/" offline="false"/>
+    </javadoc>
+  </target>
+
+
+  <!-- Cleans everything -->
+  <target name="clean" depends="init"
+  description="Cleans everything">
+    <delete file="dazzle.war"/>
+    <delete dir="${build.dir}" />
+
+  </target>
+</project>
diff --git a/dazzle-webapp/WEB-INF/web.xml b/dazzle-webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..3562538
--- /dev/null
+++ b/dazzle-webapp/WEB-INF/web.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE web-app 
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" 
+    "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
+
+<web-app>
+
+    <display-name>Dazzle server test installation</display-name>
+    <description>
+        This is a simple server for the Distributed Annotation
+        System.  See http://biodas.org/
+    </description>
+
+    <servlet>
+      <servlet-name>DazzleServerMain</servlet-name>
+      <servlet-class>org.biojava.servlets.dazzle.DazzleServlet</servlet-class>
+    </servlet>
+
+    <servlet-mapping>
+      <servlet-name>DazzleServerMain</servlet-name>
+      <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
diff --git a/dazzle-webapp/das.xsl b/dazzle-webapp/das.xsl
new file mode 100644
index 0000000..661c396
--- /dev/null
+++ b/dazzle-webapp/das.xsl
@@ -0,0 +1,914 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+<xsl:output method="html" indent="yes"/>
+
+<xsl:template match="/">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+<xsl:call-template name="css_and_js" />
+<xsl:apply-templates select="*" mode="hack" />
+<xsl:if test="0">
+<xsl:if test="not(DASDNA) and not(DASSEQUENCE)">
+  <xsl:call-template name="table_sort_js" />
+</xsl:if>
+</xsl:if>
+  <title><xsl:apply-templates select="*" mode="title" /></title>
+  </head>
+  <body>
+
+<div id="masthead">
+  <h1><a href="/"><img src="/img/e-bang.gif" style="width: 46px; height: 40px; vertical-align:bottom; border:0px; padding-bottom:2px" alt="" title="Home" /></a><a href="http://www.derkholm.net/thomas/dazzle/" class="home serif">Dazzle server</a>
+  <xsl:apply-templates select="*" mode="masthead" />
+  </h1>
+</div>
+
+<xsl:call-template name="release_and_links" />
+<div id="page">
+<div class="sptop"> </div>
+<xsl:apply-templates select="*" />
+<xsl:call-template name="disclaimer"        />
+</div>
+  </body>
+</html>
+</xsl:template>
+
+<xsl:template name="hack_js">
+  <script type="text/javascript">//<![CDATA[
+  function fix_species( ) {
+    var URL      = document.location.href;
+    var testRe   = new RegExp('^(https?://[^/]+)(/?.*/das/)([^/]*)/([^?]+)');
+    var T        = URL.match(testRe);
+    var DAS_BIT  = '';
+    var DAS_URL  = '';
+    var base_URL = '';
+    var DSN      = '';
+    var action   = '';
+    var species  = 'DAS';
+    var species_name;
+    var asm      = '';
+    var type     = '';
+    if( T ) {
+      base_URL = T[1];
+      DAS_bit  = T[2];
+      DAS_URL  = T[1]+T[2];    
+      DSN      = T[3];
+      action   = T[4];
+      T = DSN.match(/^([^.]+)\.(.*)\.([^.]+)$/);
+      species  = T[1];
+      asm      = T[2];
+      type     = T[3];
+    }
+    var species_name = species.replace(/_/,' ');
+    var Els          = document.getElementsByTagName('i');
+    for(i=0;i<Els.length;i++) {
+      var T = Els[i];
+      T.innerHTML = species_name;
+    }
+    var T = document.getElementsByTagName('title');
+    var Q = T[0].innerHTML;
+    Q = Q.replace(/DAS/,species_name);
+    T[0].innerHTML = Q;
+    var T = document.getElementById('masthead_species');
+    T.setAttribute('href',base_URL+'/'+species+'/');
+  }
+  addLoadEvent( fix_species );
+//]]>
+  </script>
+</xsl:template>
+
+<xsl:template name="table_sort_js">
+  <script type="text/javascript" src="/js/tablesorter.js"></script>
+  <script type="text/javascript">//<![CDATA[
+  function sort_table() {
+    var TableSorter1 = new TSorter;
+    TableSorter1.init('das');
+  }
+  addLoadEvent( sort_table );
+//]]>
+  </script>
+</xsl:template>
+<xsl:template name="css_and_js">
+  <script type="text/javascript">//<![CDATA[
+function addLoadEvent(func) {
+  var oldonload = window.onload;
+  if( typeof window.onload != 'function' ) { window.onload = func; } else { window.onload = function() { oldonload(); func(); } }
+}
+//]]>
+  </script>
+  <style type="text/css" media="all">
+    @import url(css/dazzle.css);
+    @import url(css/content.css);
+div.das { text-align: center }
+table.das { border-collapse: collapse; border: 1px solid #ccc; width: 98%; margin: 0px auto; text-align: left }
+table.das tr    { background:#fff; vertical-align: top }
+table.das tr th { border:1px solid #ccc; background: #ccc; text-align: center }
+table.das tr td { border:1px solid #ccc; }
+table.das tr td.e { background-color: #fdd }
+table.das tr td.c { text-align: center }
+table.das tr td.l { text-align: left  }
+table.das tr td.r { text-align: right }
+table.das tr td ul     { margin: 0px; padding: 0px }
+#page div.das table.das tr td ul li  { margin: 0px; list-style-type: none; list-style-image: none; }
+#page div.das table.das tr dt ul li span.nb, #page table.das tr td ul li a { white-space: nowrap; font-weight: bold; text-decoration: none }
+table.das tr.alt_bg td { background-color:#eee }
+table.das tr.ref_bg td { background-color:#fed }
+  </style>
+  <style type="text/css" media="print">
+    @import url(css/printer-styles.css);
+  </style>
+  <style type="text/css" media="screen">
+    @import url(css/screen-styles.css);
+  </style>
+  <style type="text/css" media="all">
+body { background-image: none }
+  </style>
+</xsl:template>
+
+<xsl:template name="release_and_links">
+<div id="release-t">                </div>
+<div id="release"><div>Please see <i>page source</i> for the actual XML document. </div></div>
+<div id="help"><strong>
+  <a href="/">HOME</a> ·
+  <a href="/sources">DAS SOURCES</a> ·
+  <a href="javascript:void(window.open('/help_index.jsp','help','width=700,height=550,resizable,scrollbars'))" class="blue-button">HELP</a>
+</strong></div>
+</xsl:template>
+
+<xsl:template name="disclaimer">
+<p class="center">
+  © 2007 <a href="http://www.sanger.ac.uk/" class="nowrap">Sanger Institute</a>
+  </p>
+</xsl:template>
+
+<!-- support functions to split up the name... -->
+<xsl:template name="first_bit">
+  <xsl:param name="string" />
+  <xsl:value-of select="substring-before($string,'.')" />
+</xsl:template>
+
+<xsl:template name="species_name">
+  <xsl:param name="string" />
+  <xsl:value-of select="translate( substring-before($string,'.'),'_',' ')" />
+</xsl:template>
+
+<xsl:template name="middle_bit">
+  <xsl:param name="string" />
+  <xsl:call-template name="mb">
+    <xsl:with-param name="string" select="substring-after($string,'.')" />
+    <xsl:with-param name="sep" />
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="mb">
+  <xsl:param name="string" />
+  <xsl:param name="sep" />
+  <xsl:if test="contains($string,'.')">
+    <xsl:value-of select="$sep" />
+    <xsl:value-of select="substring-before($string,'.')" />
+    <xsl:call-template name="mb">
+      <xsl:with-param name="string" select="substring-after($string,'.')" />
+      <xsl:with-param name="sep">.</xsl:with-param>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="ucfirst">
+  <xsl:param name="string"/>
+  <xsl:param name="strLen" select="string-length($string)"/>
+  <xsl:variable name="restString" select="substring($string,2,$strLen)"/>
+  <xsl:variable name="translate" select="translate(substring($string,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ' )" />
+  <xsl:value-of select="concat($translate,$restString)"/>
+</xsl:template>
+
+<xsl:template name="last_bit">
+  <xsl:param name="string" />
+  <xsl:choose>
+    <xsl:when test="contains($string,'.')">
+      <xsl:call-template name="last_bit">
+        <xsl:with-param name="string" select="substring-after($string,'.')" />
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="$string" />
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+<!-- DSN templates -->
+<xsl:template match="DASDSN" mode="title">
+  Dazzle DAS DSN
+</xsl:template>
+
+<xsl:template match="DASDSN" mode="hack"></xsl:template>
+
+<xsl:template match="DASDSN" mode="masthead">
+  <a class="section"> DAS</a><span class="viewname serif">DSN</span>
+</xsl:template>
+
+<xsl:template match="DASDSN">
+<h3 class="boxed">DAS sources available</h3>
+<div class="das"><table id="das" class="das"><thead>
+  <tr>
+    <th>#</th>
+    <th>ID</th>
+    <th>Species<br />Assembly</th>
+    <th>Map Master<br />Notes</th>
+    <th>Actions</th>
+  </tr>
+</thead><tbody>
+  <xsl:apply-templates select="DSN"><xsl:sort select="@id" /></xsl:apply-templates>
+</tbody></table></div>
+</xsl:template>
+
+<xsl:template match="DSN">
+    <xsl:variable name="species"><xsl:call-template name="first_bit">
+      <xsl:with-param name="string" select="SOURCE/@id" />
+    </xsl:call-template></xsl:variable>
+    <xsl:variable name="asm"><xsl:call-template name="middle_bit">
+      <xsl:with-param name="string" select="SOURCE/@id" />
+    </xsl:call-template></xsl:variable>
+    <xsl:variable name="type"><xsl:call-template name="last_bit">
+      <xsl:with-param name="string" select="SOURCE/@id" />
+    </xsl:call-template></xsl:variable>
+  <xsl:element name="tr">
+    <xsl:if test="position() mod 2 = 1"><xsl:attribute name="class">alt_bg</xsl:attribute></xsl:if>
+    <td class="r"><xsl:value-of select="position()"/></td>
+    <td class="l"><xsl:value-of select="SOURCE/@id"/></td>
+    <td class="c"><xsl:value-of select="$species" /><br /><xsl:value-of select="$asm" /></td>
+    <td class="l"><xsl:value-of select="MAPMASTER"/><br /><xsl:value-of select="DESCRIPTION" /></td>
+    <xsl:choose>
+      <xsl:when test="$type='reference'">
+    <td class="c"><xsl:element name="a"><xsl:attribute name="href" >/das/<xsl:value-of select="SOURCE/@id" />/entry_points</xsl:attribute>Entry points</xsl:element></td>
+      </xsl:when>
+      <xsl:otherwise>
+    <td class="l"><ul>
+      <li><xsl:element name="a"><xsl:attribute name="href" ><xsl:value-of select="SOURCE/@id" />/entry_points</xsl:attribute>entry_points</xsl:element></li>
+    
+    </ul></td>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:element>
+</xsl:template>
+
+<!-- SOURCES templates -->
+
+<xsl:template match="SOURCES" mode="title">
+  DAS Registry listing of sources
+</xsl:template>
+<xsl:template match="SOURCES" mode="masthead">
+  <a class="section"> DAS</a><span class="viewname serif">Sources</span>
+</xsl:template>
+
+<xsl:template match="SOURCES">
+<h3 class="boxed">DAS sources available</h3>
+<div class="das"><table id="das" class="das"><thead>
+  <tr>
+    <th>#<!--<xsl:value-of select="." />--></th>
+    <th>URI</th>
+    <th>Title</th>
+    <th>Description</th>
+    <th>Species</th>
+    <th>Coordinate System</th>
+    <th>Maintainer</th>
+    <th>Taxon ID</th>
+    <th>Test range</th>
+    <th>Capabilities</th>
+
+  </tr>
+</thead><tbody>
+    <xsl:apply-templates select="SOURCE">
+      <xsl:sort select="substring-before(@title,'.')" />
+      <xsl:sort select="@uri" />
+    </xsl:apply-templates>
+</tbody></table></div>
+</xsl:template>
+
+<xsl:template match="SOURCE">
+  <xsl:variable name="species"        select="substring-before(@title,'.')" />
+  <xsl:variable name="species_name"   select="translate($species,'_',' ')" />
+  
+  <xsl:variable name="type">
+    <xsl:call-template name="last_bit">
+      <xsl:with-param name="string"  select="@title" />
+    </xsl:call-template>
+  </xsl:variable>
+
+  <xsl:element name="tr">
+    <xsl:choose>
+      <xsl:when test="$type='reference'">
+        <xsl:attribute name="class">ref_bg</xsl:attribute>
+      </xsl:when>
+      <xsl:when test="position() mod 2 = 1">
+        <xsl:attribute name="class">alt_bg</xsl:attribute>
+      </xsl:when>
+    </xsl:choose>
+    <td class="r"><xsl:value-of select="position()"/></td>
+    <td class="l"><xsl:element name="a"><xsl:attribute name="href">http://www.dasregistry.org/showdetails.jsp?auto_id=<xsl:value-of select="@uri" /></xsl:attribute><xsl:value-of select="@uri" /></xsl:element></td>
+    <td class="l"><xsl:element name="a"><xsl:attribute name="href">http://www.dasregistry.org/showdetails.jsp?auto_id=<xsl:value-of select="@uri" /></xsl:attribute><xsl:value-of select="@title" /></xsl:element></td>
+    <td class="l"><xsl:value-of select="@description" /></td>
+    <td class="c"><i><xsl:value-of select="$species_name" /></i></td>
+    <td class="c"><xsl:element name="a"><xsl:attribute name="href"><xsl:value-of select="VERSION/COORDINATES/@uri" /></xsl:attribute><xsl:value-of select="VERSION/COORDINATES" /></xsl:element></td>
+    <td class="l"><xsl:element name="a"><xsl:attribute name="href">mailto:<xsl:value-of select="MAINTAINER/@email" /></xsl:attribute><xsl:value-of select="MAINTAINER/@email" /></xsl:element></td>
+    <td class="c"><xsl:element name="a"><xsl:attribute name="href">http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?id=<xsl:value-of select="VERSION/COORDINATES/@taxid" /></xsl:attribute><xsl:value-of select="VERSION/COORDINATES/@taxid" /></xsl:element></td>
+    <td class="l"><xsl:value-of select="VERSION/COORDINATES/@test_range" /></td>
+    <td class="l"><ul>
+    <xsl:apply-templates select="VERSION/CAPABILITY" />
+    </ul></td>
+
+  </xsl:element>
+</xsl:template>
+
+<xsl:template match="VERSION/CAPABILITY">
+  <xsl:variable name="protocol" select="substring-before(@type,':')" />
+  <xsl:variable name="function" select="substring-after( @type,':')" />
+
+      <li>
+  <xsl:choose>
+    <xsl:when test="($function='entry_points') or ($function='stylesheet')">
+      <xsl:element name="a">
+        <xsl:attribute name="href"><xsl:value-of select="@query_uri" /></xsl:attribute>
+        <xsl:value-of select="@type" />
+      </xsl:element>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:element name="a">
+        <xsl:attribute name="href"><xsl:value-of select="@query_uri" />?segment=<xsl:value-of select="../COORDINATES/@test_range" /></xsl:attribute>
+        <xsl:value-of select="@type" />
+      </xsl:element>
+    </xsl:otherwise>
+  </xsl:choose>
+      </li>
+</xsl:template>
+
+<!-- ENTRY_POINTS templates -->
+
+<xsl:template match="DASEP" mode="hack"><xsl:call-template name="hack_js" /></xsl:template>
+
+<xsl:template match="DASEP" mode="title">
+  Dazzle DAS EntryPoints
+</xsl:template>
+
+<xsl:template match="DASEP" mode="masthead">
+  <a class="section" id="masthead_species"><i>DAS</i></a>
+  <span class="viewname serif"> Entry Points</span>
+</xsl:template>
+
+<xsl:template match="DASEP">
+  <xsl:apply-templates select="ENTRY_POINTS" />
+</xsl:template>
+
+<xsl:template match="ENTRY_POINTS">
+  <xsl:variable name="species"><xsl:call-template name="first_bit">
+    <xsl:with-param name="string" select="substring-after( @href, '/das/' )" />
+  </xsl:call-template></xsl:variable>
+<h3 class="boxed">Entry points for <i>_</i></h3>
+<div class="das"><table id="das" class="das"><thead>
+  <tr>
+    <th>#</th>
+    <th>Name</th>
+    <th>Type</th>
+    <th>Start</th>
+    <th>End</th>
+    <th>Orientation</th>
+    <th>-</th>
+  </tr>
+</thead><tbody>
+  <xsl:apply-templates select="SEGMENT" mode="ep">
+    <xsl:with-param name="species" select="$species" />
+    <xsl:sort select="@stop" data-type="number" order="descending"/>
+  </xsl:apply-templates>
+</tbody></table></div>
+</xsl:template>
+
+<xsl:template match="SEGMENT" mode="ep">
+  <xsl:param name="species" />
+  <xsl:variable name="base" select="substring-before( @href, 'entrypoints' )" />
+  <xsl:element name="tr">
+    <xsl:if test="position() mod 2 = 1"><xsl:attribute name="class">alt_bg</xsl:attribute></xsl:if>
+    <td class="r"><xsl:value-of select="position()"   /></td>
+    <td class="l"><xsl:value-of select="@id"          /></td>
+    <td class="l"><xsl:value-of select="@type"        /></td>
+    <td class="r"><xsl:value-of select="@start"       /></td>
+    <td class="r"><xsl:value-of select="@stop"        /></td>
+    <td class="c"><xsl:value-of select="@orientation" /></td>
+    <td class="c"><xsl:choose>
+      <xsl:when test="@subparts">
+        <xsl:element name="a">
+          <xsl:attribute name="href">
+            <xsl:value-of select="$base" />features?segment=<xsl:value-of select="@id" />:<xsl:value-of select="@start" />,<xsl:value-of select="@stop" />
+          </xsl:attribute>
+          Elements
+        </xsl:element>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:element name="a">
+          <xsl:attribute name="href">
+            <xsl:value-of select="$base" />features?segment=<xsl:value-of select="@id" />:<xsl:value-of select="@start" />,<xsl:value-of select="@stop" />
+          </xsl:attribute>
+          XXX
+        </xsl:element>
+      </xsl:otherwise>
+    </xsl:choose></td>
+    </xsl:element>
+  </xsl:template>
+
+<!-- DNA/SEQUENCE templates -->
+
+<xsl:template match="DASSEQUENCE" mode="hack"><xsl:call-template name="hack_js" /></xsl:template>
+<xsl:template match="DASDNA"      mode="hack"><xsl:call-template name="hack_js" /></xsl:template>
+<xsl:template match="DASSEQUENCE" mode="title">Dazzle Sequence</xsl:template>
+<xsl:template match="DASDNA"      mode="title">Dazzle DNA Sequence</xsl:template>
+
+<xsl:template match="DASSEQUENCE" mode="masthead">
+  <a class="section" id="masthead_species"><i>DAS</i></a>
+  <span class="viewname serif"> Sequence</span>
+</xsl:template>
+
+<xsl:template match="DASDNA" mode="masthead">
+  <a class="section" id="masthead_species"><i>DAS</i></a>
+  <span class="viewname serif"> Sequence</span>
+</xsl:template>
+
+<xsl:template match="DASSEQUENCE">
+  <xsl:apply-templates select="SEQUENCE" mode="seq" />
+</xsl:template>
+<xsl:template match="DASDNA">
+  <xsl:apply-templates select="SEQUENCE" mode="dna" />
+</xsl:template>
+
+<xsl:template match="SEQUENCE" mode="dna">
+<h3 class="boxed"><i>_</i> segment: <xsl:value-of select="@id" />:<xsl:value-of select="@start" />-<xsl:value-of select="@stop" /></h3>
+<pre>
+  <xsl:call-template name="seq">
+    <xsl:with-param name="dna"><xsl:value-of select="translate(normalize-space(DNA),' ','')" /></xsl:with-param>
+    <xsl:with-param name="pos"><xsl:value-of select="@start" /></xsl:with-param>
+  </xsl:call-template>
+</pre>
+</xsl:template>
+
+<xsl:template match="SEQUENCE" mode="seq">
+<h3 class="boxed">Segment: <xsl:value-of select="@id" />:<xsl:value-of select="@start" />-<xsl:value-of select="@stop" /></h3>
+<pre>
+  <xsl:call-template name="seq">
+    <xsl:with-param name="dna"><xsl:value-of select="translate(normalize-space(.),' ','')" /></xsl:with-param>
+    <xsl:with-param name="pos"><xsl:value-of select="@start" /></xsl:with-param>
+  </xsl:call-template>
+</pre>
+</xsl:template>
+
+<xsl:template name="seq">
+  <xsl:param name="dna" />
+  <xsl:param name="pos" />
+  <xsl:choose>
+    <xsl:when test="string-length($dna) > 6000000">
+      <xsl:call-template name="seq">
+        <xsl:with-param name="dna" select="substring($dna,1,6000000)" />
+        <xsl:with-param name="pos" select="$pos" />
+      </xsl:call-template>
+      <xsl:call-template name="seq">
+        <xsl:with-param name="dna" select="substring($dna,6000001)" />
+        <xsl:with-param name="pos" select="$pos + 6000000" />
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="string-length($dna) > 6000">
+      <xsl:call-template name="seq">
+        <xsl:with-param name="dna" select="substring($dna,1,6000)" />
+        <xsl:with-param name="pos" select="$pos" />
+      </xsl:call-template>
+      <xsl:call-template name="seq">
+        <xsl:with-param name="dna" select="substring($dna,6001)" />
+        <xsl:with-param name="pos" select="$pos + 6000" />
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="string-length($dna) > 60">
+      <xsl:call-template name="seq">
+        <xsl:with-param name="dna" select="substring($dna,1,60)" />
+        <xsl:with-param name="pos" select="$pos" />
+      </xsl:call-template>
+      <xsl:call-template name="seq">
+        <xsl:with-param name="dna" select="substring($dna,61)" />
+        <xsl:with-param name="pos" select="$pos + 60" />
+      </xsl:call-template>
+    </xsl:when>
+    <xsl:when test="$dna != ''">
+      <xsl:variable name="rpos"      select="$pos + string-length($dna) -1" />
+      <xsl:value-of select="concat( substring(concat('          ',$pos),string-length(string($pos))), ' ')" />
+      <xsl:value-of select="substring(concat( $dna,'                                                                                                    '),1,60)" />
+      <xsl:value-of select="substring(concat('           ',$rpos),string-length(string($rpos)))" />
+    <br />
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+<!-- GFF templates -->
+
+<xsl:template match="DASTYPES" mode="hack"></xsl:template>
+<xsl:template match="DASTYPES" mode="title">
+  Dazzle <xsl:call-template name="species_name">
+    <xsl:with-param name="string" select="substring-after( GFF/@href, '/das/' )" />
+  </xsl:call-template> <xsl:call-template name="last_bit">
+    <xsl:with-param name="string" select="substring-before( GFF/@href, '/types?' )" />
+  </xsl:call-template> Feature types
+</xsl:template>
+
+<xsl:template match="DASTYPES" mode="masthead">
+  <xsl:variable name="species"><xsl:call-template name="first_bit">
+    <xsl:with-param name="string" select="substring-after( GFF/@href, '/das/' )" />
+  </xsl:call-template></xsl:variable>
+  <xsl:variable name="type"><xsl:call-template name="last_bit">
+    <xsl:with-param name="string" select="substring-before( GFF/@href, '/types?' )" />
+  </xsl:call-template></xsl:variable>
+  <xsl:element name="a">
+    <xsl:attribute name="class">section</xsl:attribute>
+    <xsl:attribute name="href" >/<xsl:value-of select="$species" />/</xsl:attribute>
+    <i><xsl:value-of select="translate($species,'_',' ')" /></i>
+  </xsl:element>
+  <span class="viewname serif"> <xsl:call-template name="ucfirst"><xsl:with-param name="string" select="$type" /></xsl:call-template> feature types</span>
+</xsl:template>
+
+<xsl:template match="DASTYPES">
+  <xsl:apply-templates select="GFF" mode="type"/>
+</xsl:template>
+
+<xsl:template match="DASGFF" mode="hack"></xsl:template>
+<xsl:template match="DASGFF" mode="title">
+  Dazzle <xsl:call-template name="species_name">
+    <xsl:with-param name="string" select="substring-after( GFF/@href, '/das/' )" />
+  </xsl:call-template> <xsl:call-template name="last_bit">
+    <xsl:with-param name="string" select="substring-before( GFF/@href, '/features?' )" />
+  </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="DASGFF" mode="masthead">
+  <xsl:variable name="species"><xsl:call-template name="first_bit">
+    <xsl:with-param name="string" select="substring-after( GFF/@href, '/das/' )" />
+  </xsl:call-template></xsl:variable>
+  <xsl:variable name="type"><xsl:call-template name="last_bit">
+    <xsl:with-param name="string" select="substring-before( GFF/@href, '/features?' )" />
+  </xsl:call-template></xsl:variable>
+  <xsl:element name="a">
+    <xsl:attribute name="class">section</xsl:attribute>
+    <xsl:attribute name="href" >/<xsl:value-of select="$species" />/</xsl:attribute>
+    <i><xsl:value-of select="translate($species,'_',' ')" /></i>
+  </xsl:element>
+  <span class="viewname serif"> <xsl:call-template name="ucfirst"><xsl:with-param name="string" select="$type" /></xsl:call-template> features</span>
+</xsl:template>
+
+<xsl:template match="DASGFF">
+  <xsl:apply-templates select="GFF" />
+</xsl:template>
+
+<xsl:template match="GFF" mode="type">
+  <xsl:variable name="species"><xsl:call-template name="first_bit">
+    <xsl:with-param name="string" select="substring-after( @href, '/das/' )" />
+  </xsl:call-template></xsl:variable>
+  <xsl:variable name="type"><xsl:call-template name="last_bit">
+    <xsl:with-param name="string" select="substring-before(substring-after( @href, '/das/' ),'/')" />
+  </xsl:call-template></xsl:variable>
+
+<h3 class="boxed">Das types from: <xsl:value-of select="@href"/></h3>
+<div class="das"><table id="das" class="das">
+  <xsl:apply-templates select="SEGMENT|ERRORSEGMENT|UNKNOWNSEGMENT" mode="type">
+    <xsl:with-param name="species" select="$species" />
+    <xsl:with-param name="type" select="$type" />
+    <xsl:sort select="@id" />
+  </xsl:apply-templates>
+</table></div>
+</xsl:template>
+
+<xsl:template match="GFF">
+  <xsl:variable name="species"><xsl:call-template name="first_bit">
+    <xsl:with-param name="string" select="substring-after( @href, '/das/' )" />
+  </xsl:call-template></xsl:variable>
+  <xsl:variable name="type"><xsl:call-template name="last_bit">
+    <xsl:with-param name="string" select="substring-before(substring-after( @href, '/das/' ),'/')" />
+  </xsl:call-template></xsl:variable>
+
+<h3 class="boxed">Das Features from: <xsl:value-of select="@href"/></h3>
+<div class="das"><table id="das" class="das">
+  <xsl:apply-templates select="SEGMENT|ERRORSEGMENT|UNKNOWNSEGMENT" mode="gff">
+    <xsl:with-param name="species" select="$species" />
+    <xsl:with-param name="type" select="$type" />
+    <xsl:sort select="@id" />
+  </xsl:apply-templates>
+</table></div>
+</xsl:template>
+
+<xsl:template match="UNKNOWNSEGMENT" mode="type">
+  <xsl:param name="species" />
+  <xsl:param name="type" />
+  <tbody class="head">
+  <tr>
+    <th colspan="5">Segment: <xsl:value-of select="@id" />:<xsl:value-of select="@start" />-<xsl:value-of select="@stop" /></th>
+  </tr>
+  <tr>
+    <td colspan="5" class="c e">Unknown segment</td>
+  </tr>
+  </tbody>
+</xsl:template>
+
+<xsl:template match="ERRORSEGMENT" mode="type">
+  <xsl:param name="species" />
+  <xsl:param name="type" />
+  <tbody class="head">
+  <tr>
+    <th colspan="5">Segment: <xsl:value-of select="@id" />:<xsl:value-of select="@start" />-<xsl:value-of select="@stop" /></th>
+  </tr>
+  <tr>
+    <td colspan="5" class="e c">Error in selected segment (region chosen outside range of <xsl:value-of select="@id" />)</td>
+  </tr>
+  </tbody>
+</xsl:template>
+
+<xsl:template match="SEGMENT" mode="type">
+  <xsl:param name="species" />
+  <xsl:param name="type" />
+  <tbody class="head">
+  <xsl:if test="@id">
+  <tr>
+    <th colspan="6">Segment: <xsl:value-of select="@id" />:<xsl:value-of select="@start" />-<xsl:value-of select="@stop" />
+    []
+    </th>
+  </tr>
+  </xsl:if>
+  <xsl:choose>
+    <xsl:when test="TYPE">
+    <tr>
+    <th>#</th>
+    <th>Category</th>
+    <th>Type</th>
+    <th>Method</th>
+    <th>Count</th>
+  </tr>
+    </xsl:when>
+    <xsl:otherwise>
+  <tr><td colspan="11" class="c">No features on this segment</td></tr>
+    </xsl:otherwise>
+  </xsl:choose>
+  </tbody>
+  <tbody>
+  <xsl:apply-templates select="TYPE" mode="gff">
+    <xsl:sort select="@category" />
+    <xsl:sort select="@id" />
+    <xsl:with-param name="species" select="$species" />
+    <xsl:with-param name="type" select="$type" />
+  </xsl:apply-templates>
+  </tbody>
+</xsl:template>
+
+<xsl:template match="UNKNOWNSEGMENT" mode="gff">
+  <xsl:param name="species" />
+  <xsl:param name="type" />
+  <tbody class="head">
+  <tr>
+    <th colspan="11">Segment: <xsl:value-of select="@id" />:<xsl:value-of select="@start" />-<xsl:value-of select="@stop" /></th>
+  </tr>
+  <tr>
+    <td colspan="11" class="c e">Unknown segment</td>
+  </tr>
+  </tbody>
+</xsl:template>
+
+<xsl:template match="ERRORSEGMENT" mode="gff">
+  <xsl:param name="species" />
+  <xsl:param name="type" />
+  <tbody class="head">
+  <tr>
+    <th colspan="11">Segment: <xsl:value-of select="@id" />:<xsl:value-of select="@start" />-<xsl:value-of select="@stop" /></th>
+  </tr>
+  <tr>
+    <td colspan="11" class="e c">Error in selected segment (region chosen outside range of <xsl:value-of select="@id" />)</td>
+  </tr>
+  </tbody>
+</xsl:template>
+
+<xsl:template match="SEGMENT" mode="gff">
+  <xsl:param name="species" />
+  <xsl:param name="type" />
+  <tbody class="head">
+  <tr>
+    <th colspan="11">Segment: <xsl:value-of select="@id" />:<xsl:value-of select="@start" />-<xsl:value-of select="@stop" />
+    []
+    </th>
+  </tr>
+  <xsl:choose>
+    <xsl:when test="FEATURE">
+  <tr>
+    <th>#</th>
+    <th>Label<br />(Grouping)</th>
+    <th>Type<br />Category</th>
+    <th>Method</th>
+    <th>Start</th>
+    <th>End</th>
+    <th>Orientation</th>
+    <th>Score</th>
+    <th>Target</th>
+    <th>Links</th>
+    <th>Notes</th>
+  </tr>
+    </xsl:when>
+    <xsl:otherwise>
+  <tr><td colspan="11" class="c">No features on this segment</td></tr>
+    </xsl:otherwise>
+  </xsl:choose>
+  </tbody>
+  <tbody>
+  <xsl:apply-templates select="FEATURE">
+    <xsl:sort select="TYPE/@id" />
+    <xsl:sort select="START" data-type="number" />
+    <xsl:with-param name="species" select="$species" />
+    <xsl:with-param name="type" select="$type" />
+  </xsl:apply-templates>
+  </tbody>
+</xsl:template>
+
+<xsl:template match="TYPE" mode="gff">
+  <xsl:param name="species" />
+  <xsl:param name="type" />
+  <xsl:variable name="base_URL" select="substring-before(../../@href,'/features?')" />
+  <xsl:element name="tr">
+  <xsl:if test="position() mod 2 = 1"><xsl:attribute name="style">background-color: #f0f0f0</xsl:attribute></xsl:if>
+    <td class="r"><xsl:value-of select="position()" /></td>
+    <td class="c"><xsl:value-of select="@category" /></td>
+    <td class="c"><xsl:value-of select="@id" /></td>
+    <td class="c"><xsl:value-of select="@method" /></td>
+    <td class="r"><xsl:value-of select="." /></td>
+  </xsl:element>
+</xsl:template>
+
+<xsl:template match="GROUP" mode="gff">
+  <xsl:param name="base_URL" />
+  <li><xsl:element name="a">
+    <xsl:attribute name="href">
+      <xsl:value-of select="$base_URL" />/features?group_id=<xsl:value-of select="@id" />
+    </xsl:attribute><xsl:choose>
+    <xsl:when test="@label">
+      <xsl:value-of select="@label" />
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="@id" />
+    </xsl:otherwise>
+    </xsl:choose>
+  </xsl:element></li>
+</xsl:template>
+
+<xsl:template match="FEATURE">
+  <xsl:param name="species" />
+  <xsl:param name="type" />
+  <xsl:variable name="base_URL" select="substring-before(../../@href,'/features?')" />
+  <xsl:element name="tr">
+  <xsl:if test="position() mod 2 = 1"><xsl:attribute name="style">background-color: #f0f0f0</xsl:attribute></xsl:if>
+    <td class="r"><xsl:value-of select="position()" /></td>
+    <td class="l"><ul>
+      <li><xsl:element name="a">
+        <xsl:attribute name="href">
+          <xsl:value-of select="$base_URL" />/features?feature_id=<xsl:value-of select="@id" />
+        </xsl:attribute><xsl:choose>
+        <xsl:when test="@label">
+          <xsl:value-of select="@label" />
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="@id" />
+        </xsl:otherwise>
+        </xsl:choose>
+      </xsl:element></li>
+      <xsl:apply-templates select="GROUP" mode="gff">
+        <xsl:with-param name="base_URL" select="$base_URL" />
+        <xsl:sort select="@id" />
+      </xsl:apply-templates>
+    </ul></td>
+    <td class="c"><xsl:value-of select="TYPE"       /><br /><xsl:value-of select="TYPE/@category" /></td>
+    <td class="c"><xsl:value-of select="METHOD"     /></td>
+    <td class="r"><xsl:value-of select="START"      /></td>
+    <td class="r"><xsl:value-of select="END"        /></td>
+    <td class="c"><xsl:value-of select="ORIENTATION"/></td>
+    <td class="c"><xsl:value-of select="SCORE"      /></td>
+    <td class="c"><xsl:choose>
+      <xsl:when test="TARGET">
+        <xsl:value-of select="TARGET/@id" /><br />
+        <xsl:value-of select="TARGET/@start" />-<xsl:value-of select="TARGET/@stop" />
+      </xsl:when>
+      <xsl:otherwise>
+        -
+      </xsl:otherwise>
+    </xsl:choose></td>
+    <td class="l"><ul>
+    <xsl:if test="TYPE/@reference='yes'">
+      <xsl:if test="TYPE/@subparts='yes'">
+        <li><xsl:element name="a">
+        <xsl:attribute name="href"><xsl:value-of select="$base_URL" />/features?segment=<xsl:value-of select="@id" /></xsl:attribute>
+          <em>DAS</em> Assembly
+        </xsl:element></li>
+      </xsl:if>
+      <li><xsl:element name="a">
+        <xsl:attribute name="href"><xsl:value-of select="$base_URL" />/dna?segment=<xsl:value-of select="@id" /></xsl:attribute>
+          <em>DAS</em> Sequence
+      </xsl:element></li>
+    </xsl:if>
+      <li></li>
+    <xsl:apply-templates select="LINK"/>
+    <xsl:apply-templates select="GROUP/LINK"/>
+    </ul></td>
+    <td class="l">
+      <xsl:if test="(NOTE) or (GROUP/NOTE)"><ul>
+        <xsl:apply-templates select="NOTE"/>
+        <xsl:apply-templates select="GROUP/NOTE"/>
+      </ul></xsl:if></td>
+  </xsl:element>
+</xsl:template>
+
+<xsl:template match="LINK">
+  <xsl:choose>
+    <xsl:when test="(@href) and (@href!='')">
+      <li><xsl:element name="a">
+        <xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute>
+        <xsl:value-of select="."/>
+      </xsl:element></li>
+    </xsl:when>
+    <xsl:otherwise>
+      <li><span class="nb"><xsl:value-of select="." /></span></li>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="NOTE">
+      <li><small><xsl:value-of select="."/></small></li>
+</xsl:template>
+
+<!-- LAST BUT NOT LEAST STYLESHEETS -->
+
+<xsl:template match="DASSTYLE" mode="title">
+  Dazzle DAS StyleSheet
+</xsl:template>
+
+<xsl:template match="DASSTYLE" mode="masthead">
+  <xsl:element name="a">
+    <xsl:attribute name="class">section</xsl:attribute>
+    DAS
+  </xsl:element>
+  <span class="viewname serif"> StyleSheet</span>
+</xsl:template>
+
+<xsl:template match="DASSTYLE">
+  <xsl:apply-templates select="STYLESHEET" />
+</xsl:template>
+
+<xsl:template match="STYLESHEET">
+<h3 class="boxed">Feature styles...</h3>
+<div class="das"><table id="das" class="das">
+<tr>
+  <th>#</th>
+  <th>Category</th>
+  <th>Type</th>
+  <th>Glyph</th>
+</tr>
+  <xsl:apply-templates select="CATEGORY/TYPE" mode="ss">
+    <xsl:sort select="../@id" />
+    <xsl:sort select="@id" />
+  </xsl:apply-templates>
+</table></div>
+</xsl:template>
+<xsl:template match="CATEGORY/TYPE" mode="ss">
+  <xsl:variable name="alt" select="position() mod 2 = 1" />
+  <xsl:element name="tr">
+    <xsl:if test="$alt"><xsl:attribute name="class">alt_bg</xsl:attribute></xsl:if>
+    <xsl:element name="td">
+      <xsl:attribute name="class">r</xsl:attribute>
+      <xsl:attribute name="rowspan"><xsl:value-of select="count(GLYPH/*)" /></xsl:attribute>
+      <xsl:value-of select="position()" />
+    </xsl:element>
+    <xsl:element name="td">
+      <xsl:attribute name="class">c</xsl:attribute>
+      <xsl:attribute name="rowspan"><xsl:value-of select="count(GLYPH/*)" /></xsl:attribute>
+      <xsl:value-of select="../@id" />
+    </xsl:element>
+    <xsl:element name="td">
+      <xsl:attribute name="class">c</xsl:attribute>
+      <xsl:attribute name="rowspan"><xsl:value-of select="count(GLYPH/*)" /></xsl:attribute>
+      <xsl:value-of select="@id" />
+    </xsl:element>
+    <xsl:apply-templates select="GLYPH[position()=1]/*[position()=1]" mode="ss" />
+  </xsl:element>
+  <xsl:apply-templates select="GLYPH[position()=1]/*[position()!=1]" mode="ss-tr"><xsl:with-param name="alt" select="$alt" /></xsl:apply-templates>
+  <xsl:apply-templates select="GLYPH[position()!=1]/*" mode="ss-tr"><xsl:with-param name="alt" select="$alt" /></xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="GLYPH/*" mode="ss-tr">
+  <xsl:param name="alt" />
+  <xsl:element name="tr"><xsl:if test="$alt"><xsl:attribute name="class">alt_bg</xsl:attribute></xsl:if>
+  <xsl:apply-templates select="." mode="ss"/>
+  </xsl:element>
+</xsl:template>
+
+<xsl:template match="GLYPH/*" mode="ss">
+  <td class="l"><strong><xsl:value-of select="name(.)" />: </strong> <xsl:apply-templates select="." mode="ss-attr" />
+  </td>
+</xsl:template>
+<xsl:template match="*" mode="ss-attr">
+  <xsl:for-each select="*">
+    <xsl:sort select="name(.)" />
+    <xsl:value-of select="name(.)" /> = <xsl:value-of select="." />;
+  </xsl:for-each>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/dazzle-webapp/das_welcome.html b/dazzle-webapp/das_welcome.html
new file mode 100644
index 0000000..9f21f24
--- /dev/null
+++ b/dazzle-webapp/das_welcome.html
@@ -0,0 +1,6 @@
+<p>
+Dazzle was developed at the <a href="http://www.sanger.ac.uk/">Sanger
+Institute</a> by <a href="mailto:td2 at sanger.ac.uk">Thomas Down</a>.  For
+more information, visit the <a href="http://www.derkholm.net/thomas/dazzle/">Dazzle
+home page</a> or contact the author.
+</p>
diff --git a/dazzle-webapp/dazzlecfg.xml b/dazzle-webapp/dazzlecfg.xml
new file mode 100644
index 0000000..986bb7d
--- /dev/null
+++ b/dazzle-webapp/dazzlecfg.xml
@@ -0,0 +1,56 @@
+<!--
+ 
+  Example configuration file for the Dazzle servlet.
+
+  Please check all paths and URIs before deploying this on
+  your own server.
+
+  Information of configuring and deploying Dazzle can
+  be found at:
+
+      http://www.biojava.org/dazzle/
+
+  Alternatively, questions can be mailed to:
+
+      Thomas Down <td2 at sanger.ac.uk>
+
+  -->
+
+<dazzle xmlns="http://www.biojava.org/2000/dazzle">
+  <!-- Test reference server -->
+
+  <datasource id="test" jclass="org.biojava.servlets.dazzle.datasource.EmblDataSource">
+    <string name="name" value="Test seqs" />
+    <string name="description" value="Test set for promoter-finding software" />
+    <string name="version" value="default" />
+    <string name="fileName" value="/test.embl" />
+
+    <string name="stylesheet" value="test.style" />
+  </datasource>
+
+  <!-- Test annotation server.  Note that the mapMaster property must
+       be changed to match your reference server -->
+
+  <datasource id="tss" jclass="org.biojava.servlets.dazzle.datasource.GFFAnnotationSource">
+    <string name="name" value="TSS" />
+    <string name="description" value="Transcription start sites" />
+    <string name="version" value="default" />
+    <string name="fileName" value="/fickett-tss.gff" />
+    <boolean name="dotVersions" value="true" />
+    <string name="mapMaster" value="http://localhost:8080/das/test/" />
+
+    <string name="stylesheet" value="tss.style" />
+  </datasource>
+  
+  
+   <!-- Another test reference and annotation server. 
+   		It reads all info from an example uniprot file.
+   
+    -->
+  <datasource id="uniprot_snps" jclass="org.biojava.servlets.dazzle.datasource.UniProtDataSource">
+    <string name="name" value="uniprot_snps" />
+    <string name="description" value="some snps on a uniprot sequence" />
+    <string name="version" value="default" />
+    <string name="fileName" value="/example.up" />
+  </datasource>
+</dazzle>
diff --git a/dazzle-webapp/example.up b/dazzle-webapp/example.up
new file mode 100644
index 0000000..be1676c
--- /dev/null
+++ b/dazzle-webapp/example.up
@@ -0,0 +1,158 @@
+ID   EGR1_MOUSE              Reviewed;         533 AA.
+AC   P08046; Q61777;
+DT   01-AUG-1988, integrated into UniProtKB/Swiss-Prot.
+DT   01-NOV-1990, sequence version 2.
+DT   20-MAR-2007, entry version 78.
+DE   Early growth response protein 1 (EGR-1) (Krox-24 protein)
+DE   (Transcription factor Zif268) (Nerve growth factor-induced protein A)
+DE   (NGFI-A).
+GN   Name=Egr1; Synonyms=Egr-1, Krox-24;
+OS   Mus musculus (Mouse).
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Euteleostomi;
+OC   Mammalia; Eutheria; Euarchontoglires; Glires; Rodentia; Sciurognathi;
+OC   Muroidea; Muridae; Murinae; Mus.
+OX   NCBI_TaxID=10090;
+RN   [1]
+RP   NUCLEOTIDE SEQUENCE [MRNA].
+RX   MEDLINE=88165055; PubMed=3127059; DOI=10.1016/0092-8674(88)90485-0;
+RA   Sukhatme V.P., Cao X., Chang L.C., Tsai-Morris C.-H., Stamenkovich D.,
+RA   Ferreira P.C.P., Cohen D.R., Edwards S.A., Shows T.B., Curran T.,
+RA   le Beau M.M., Adamson E.D.;
+RT   "A zinc finger-encoding gene coregulated with c-fos during growth and
+RT   differentiation, and after cellular depolarization.";
+RL   Cell 53:37-43(1988).
+RN   [2]
+RP   NUCLEOTIDE SEQUENCE [MRNA].
+RX   MEDLINE=89042085; PubMed=3141919;
+RA   Christy B.A., Lau L.F., Nathans D.;
+RT   "A gene activated in mouse 3T3 cells by serum growth factors encodes a
+RT   protein with 'zinc finger' sequences.";
+RL   Proc. Natl. Acad. Sci. U.S.A. 85:7857-7861(1988).
+RN   [3]
+RP   NUCLEOTIDE SEQUENCE [GENOMIC DNA].
+RX   MEDLINE=90060781; PubMed=2511075; DOI=10.1016/0378-1119(89)90296-5;
+RA   Janssen-Timmen U., Lemaire P., Mattei M.-G., Revelant O., Charnay P.;
+RT   "Structure, chromosome mapping and regulation of the mouse zinc-finger
+RT   gene Krox-24; evidence for a common regulatory pathway for immediate-
+RT   early serum-response genes.";
+RL   Gene 80:325-336(1989).
+RN   [4]
+RP   NUCLEOTIDE SEQUENCE [MRNA] OF 50-533.
+RX   MEDLINE=88263014; PubMed=3133658;
+RA   Lemaire P., Revelant O., Bravo R., Charnay P.;
+RT   "Two mouse genes encoding potential transcription factors with
+RT   identical DNA-binding domains are activated by growth factors in
+RT   cultured cells.";
+RL   Proc. Natl. Acad. Sci. U.S.A. 85:4691-4695(1988).
+RN   [5]
+RP   MUTAGENESIS OF ZINC FINGERS.
+RX   MEDLINE=92156104; PubMed=1740423;
+RA   Wilson T.E., Day M.L., Pexton T., Padgett K.A., Johnston M.,
+RA   Milbrandt J.;
+RT   "In vivo mutational analysis of the NGFI-A zinc fingers.";
+RL   J. Biol. Chem. 267:3718-3724(1992).
+RN   [6]
+RP   X-RAY CRYSTALLOGRAPHY (2.1 ANGSTROMS) OF 333-421.
+RX   MEDLINE=91227904; PubMed=2028256;
+RA   Pavletich N.P., Pabo C.O.;
+RT   "Zinc finger-DNA recognition: crystal structure of a Zif268-DNA
+RT   complex at 2.1 A.";
+RL   Science 252:809-817(1991).
+RN   [7]
+RP   X-RAY CRYSTALLOGRAPHY (2.1 ANGSTROMS) OF 333-421 WITH VARIATIONS.
+RX   MEDLINE=98230744; PubMed=9562555; DOI=10.1016/S0969-2126(98)00047-1;
+RA   Elrod-Erickson M., Benson T.E., Pabo C.O.;
+RT   "High-resolution structures of variant Zif268-DNA complexes:
+RT   implications for understanding zinc finger-DNA recognition.";
+RL   Structure 6:451-464(1998).
+CC   -!- FUNCTION: Transcriptional regulator. Recognizes and binds to the
+CC       DNA sequence 5'-CGCCCCCGC-3'(EGR-site). Activates the
+CC       transcription of target genes whose products are required for
+CC       mitogenesis and differentiation.
+CC   -!- SUBCELLULAR LOCATION: Nucleus.
+CC   -!- INDUCTION: By growth factors.
+CC   -!- SIMILARITY: Belongs to the EGR C2H2-type zinc-finger protein
+CC       family.
+CC   -!- SIMILARITY: Contains 3 C2H2-type zinc fingers.
+CC   -----------------------------------------------------------------------
+CC   Copyrighted by the UniProt Consortium, see http://www.uniprot.org/terms
+CC   Distributed under the Creative Commons Attribution-NoDerivs License
+CC   -----------------------------------------------------------------------
+DR   EMBL; M20157; AAA37544.1; -; mRNA.
+DR   EMBL; M22326; AAA40416.1; -; mRNA.
+DR   EMBL; M28845; AAB00468.1; -; Genomic_DNA.
+DR   EMBL; M28844; AAB00468.1; JOINED; Genomic_DNA.
+DR   EMBL; M19643; AAA39382.1; -; mRNA.
+DR   PIR; JS0304; JS0304.
+DR   UniGene; Mm.181959; -.
+DR   PDB; 1A1F; X-ray; A=333-421.
+DR   PDB; 1A1G; X-ray; A=333-421.
+DR   PDB; 1A1H; X-ray; A=333-421.
+DR   PDB; 1A1I; X-ray; A=333-421.
+DR   PDB; 1A1J; X-ray; A=333-421.
+DR   PDB; 1A1K; X-ray; A=333-421.
+DR   PDB; 1A1L; X-ray; A=333-421.
+DR   PDB; 1AAY; X-ray; A=333-421.
+DR   PDB; 1F2I; X-ray; G/H/I/J/K/L=334-389.
+DR   PDB; 1G2D; X-ray; C/F=333-421.
+DR   PDB; 1G2F; X-ray; C/F=333-421.
+DR   PDB; 1JK1; X-ray; A=333-421.
+DR   PDB; 1JK2; X-ray; A=333-421.
+DR   PDB; 1LLM; X-ray; C/D=-.
+DR   PDB; 1P47; X-ray; A/B=333-419.
+DR   PDB; 1ZAA; X-ray; C=332-418.
+DR   TRANSFAC; T00244; -.
+DR   TRANSFAC; T00455; -.
+DR   Ensembl; ENSMUSG00000038418; Mus musculus.
+DR   KEGG; mmu:13653; -.
+DR   MGI; MGI:95295; Egr1.
+DR   LinkHub; P08046; -.
+DR   ArrayExpress; P08046; -.
+DR   GermOnline; ENSMUSG00000038418; Mus musculus.
+DR   GO; GO:0005634; C:nucleus; IMP:MGI.
+DR   GO; GO:0003700; F:transcription factor activity; IMP:MGI.
+DR   GO; GO:0006355; P:regulation of transcription, DNA-dependent; IMP:MGI.
+DR   GO; GO:0030217; P:T cell differentiation; IMP:MGI.
+DR   InterPro; IPR007087; Znf_C2H2.
+DR   Pfam; PF00096; zf-C2H2; 3.
+DR   ProDom; PD000003; Znf_C2H2; 2.
+DR   SMART; SM00355; ZnF_C2H2; 3.
+DR   PROSITE; PS00028; ZINC_FINGER_C2H2_1; 3.
+DR   PROSITE; PS50157; ZINC_FINGER_C2H2_2; 3.
+KW   3D-structure; Activator; DNA-binding; Metal-binding; Nuclear protein;
+KW   Repeat; Transcription; Transcription regulation; Zinc; Zinc-finger.
+FT   A_SNPS      366    366       Score: 13
+FT   A_SNPS      367    367       Score: 32
+FT   A_SNPS      368    368       Score: 18
+FT   A_SNPS      369    369       Score: 39
+FT   A_SNPS      370    370       Score: 23
+FT   A_SNPS      371    371       Score: 12
+FT   A_SNPS      372    372       Score: 21
+FT   A_SNPS      373    373       Score: 22
+FT   A_SNPS      374    374       Score: 19
+FT   A_SNPS      375    375       Score: 12
+FT   A_SNPS      376    376       Score: 32
+FT   A_SNPS      377    377       Score: 28
+FT   A_SNPS      378    378       Score: 21
+FT   A_SNPS      379    379       Score: 20
+FT   A_SNPS      380    380       Score: 21
+FT   A_SNPS      381    381       Score: 12
+FT   A_SNPS      382    382       Score: 30
+FT   A_SNPS      383    383       Score: 24
+FT   A_SNPS      384    384       Score: 9
+FT   A_SNPS      385    385       Score: 38
+FT   A_SNPS      386    386       Score: 21
+FT   A_SNPS      387    387       Score: 26
+FT   A_SNPS      388    388       Score: 7
+SQ   SEQUENCE   533 AA;  56590 MW;  36E3935767CEAA0F CRC64;
+     MAAAKAEMQL MSPLQISDPF GSFPHSPTMD NYPKLEEMML LSNGAPQFLG AAGTPEGSGG
+     NSSSSTSSGG GGGGGSNSGS SAFNPQGEPS EQPYEHLTTE SFSDIALNNE KAMVETSYPS
+     QTTRLPPITY TGRFSLEPAP NSGNTLWPEP LFSLVSGLVS MTNPPTSSSS APSPAASSSS
+     SASQSPPLSC AVPSNDSSPI YSAAPTFPTP NTDIFPEPQS QAFPGSAGTA LQYPPPAYPA
+     TKGGFQVPMI PDYLFPQQQG DLSLGTPDQK PFQGLENRTQ QPSLTPLSTI KAFATQSGSQ
+     DLKALNTTYQ SQLIKPSRMR KYPNRPSKTP PHERPYACPV ESCDRRFSRS DELTRHIRIH
+     TGQKPFQCRI CMRNFSRSDH LTTHIRTHTG EKPFACDICG RKFARSDERK RHTKIHLRQK
+     DKKADKSVVA SPAASSLSSY PSPVATSYPS PATTSFPSPV PTSYSSPGSS TYPSPAHSGF
+     PSPSVATTFA SVPPAFPTQV SSFPSAGVSS SFSTSTGLSD MTATFSPRTI EIC
+//
+
diff --git a/dazzle-webapp/fickett-tss.gff b/dazzle-webapp/fickett-tss.gff
new file mode 100644
index 0000000..1f5e5e4
--- /dev/null
+++ b/dazzle-webapp/fickett-tss.gff
@@ -0,0 +1,44 @@
+##gff-version 2
+##date 2000-09-13
+##sequence-region U29912.1 1 565
+##sequence-region U30245.1 1 1093
+##sequence-region U75286.1 1 1984
+##sequence-region U54701.1 1 5663
+##sequence-region Y10100.1 1 1066
+##sequence-region X94563.1 1 2692
+##sequence-region X75410.1 1 926
+##sequence-region L47615.1 1 3221
+##sequence-region AF107208.1 1 2313
+##sequence-region U49855.1 1 682
+##sequence-region U80601.1 1 632
+##sequence-region U24240.1 1 1728
+##sequence-region D86218.1 1 2191
+##sequence-region U52432.1 1 1604
+##sequence-region AF223952.1 1 7502
+##sequence-region Z49978.1 1 1352
+##sequence-region U10577.1 1 831
+##sequence-region U69634.1 1 1515
+L47615.1	hand_built	TSS	2097	2097	.	+	0
+L47615.1	hand_built	TSS	2108	2108	.	+	0
+U54701.1	hand_built	TSS	935	935	.	+	0
+U54701.1	hand_built	TSS	2002	2002	.	+	0
+AF107208.1	hand_built	TSS	1483	1554	.	+	0
+AF107208.1	hand_built	TSS	1756	1783	.	+	0
+U10577.1	hand_built	TSS	1169	1171	.	+	0
+U30245.1	hand_built	TSS	850	951	.	+	0
+U69634.1	hand_built	TSS	1450	1450	.	+	0
+U29912.1	hand_built	TSS	143	166	.	+	0
+Y10100.1	hand_built	TSS	1018	1033	.	+	0
+D86218.1	hand_built	TSS	1793	1812	.	+	0
+U75286.1	hand_built	TSS	1416	1480	.	+	0
+U52432.1	hand_built	TSS	1521	1523	.	+	0
+U80601.1	hand_built	TSS	317	400	.	+	0
+X94563.1	hand_built	TSS	1163	1200	.	+	0
+Z49978.1	hand_built	TSS	855	855	.	+	0
+Z49978.1	hand_built	TSS	1020	1020	.	+	0
+Z49978.1	hand_built	TSS	1150	1150	.	+	0
+U49855.1	hand_built	TSS	28	51	.	+	0
+X75410.1	hand_built	TSS	815	836	.	+	0
+U24240.1	hand_built	TSS	1480	1480	.	+	0
+AF223952.1	hand_built	TSS	1805	1820	.	+	0
+AF223952.1	hand_built	TSS	5528	5543	.	+	0
diff --git a/dazzle-webapp/sources.xml b/dazzle-webapp/sources.xml
new file mode 100644
index 0000000..ca32e88
--- /dev/null
+++ b/dazzle-webapp/sources.xml
@@ -0,0 +1,26 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<?xml-stylesheet type="text/xsl" href="das.xsl"?>
+<SOURCES>
+  <SOURCE 	uri="MyFirstDasSource" 
+  		title="The title of the DAS source" 
+		doc_href="http://www.myhomepage.org" 
+		description="Test set for promoter-finding software">
+  <MAINTAINER	email="you at myhomepage.org" />
+
+  <VERSION 	uri="latest" created="2007-12-25">
+
+   <COORDINATES uri="http://www.dasregistry.org/dasregistry/coordsys/CS_DS6" 
+   		source="Protein Sequence" 
+		authority="UniProt" 
+		test_range="P00280"/>   
+
+   <CAPABILITY type="das1:sequence" query_uri="http://www.ebi.ac.uk/das-srv/uniprot/das/aristotle/sequence" />
+   <CAPABILITY type="das1:features" query_uri="http://www.ebi.ac.uk/das-srv/uniprot/das/aristotle/features" />
+   <CAPABILITY type="das1:entry_points" query_uri="http://www.ebi.ac.uk/das-srv/uniprot/das/aristotle/entry_points" />
+
+   <CAPABILITY type="das1:stylesheet" query_uri="http://www.ebi.ac.uk/das-srv/uniprot/das/aristotle/stylesheet" />
+      
+   <PROP name="label" value="BioSapiens" />     
+  </VERSION>
+  </SOURCE>
+</SOURCES>
diff --git a/dazzle-webapp/test.embl b/dazzle-webapp/test.embl
new file mode 100644
index 0000000..b1052cc
--- /dev/null
+++ b/dazzle-webapp/test.embl
@@ -0,0 +1,1774 @@
+ID   AF107208   standard; DNA; ROD; 2313 BP.
+XX
+AC   AF107208;
+XX
+SV   AF107208.1
+XX
+DT   30-JUL-1999 (Rel. 60, Created)
+DT   30-JUL-1999 (Rel. 60, Last updated, Version 1)
+XX
+DE   Rattus norvegicus A2a adenosine receptor gene, partial cds.
+XX
+KW   .
+XX
+OS   Rattus norvegicus (Norway rat)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Rodentia; Sciurognathi; Muridae; Murinae;
+OC   Rattus.
+XX
+RN   [1]
+RP   1-2313
+RX   MEDLINE; 96213913.
+RA   Chu Y.Y., Tu K.H., Lee Y.C., Kuo Z.J., Lai H.L., Chern Y.;
+RT   "Characterization of the rat A2a adenosine receptor gene";
+RL   DNA Cell Biol. 15(4):329-337(1996).
+XX
+RN   [2]
+RP   1-2313
+RA   Chu Y.-Y., Tu K.-H., Lee Y.C., Kuo Z.-J., Lai H.-L., Chern Y.;
+RT   ;
+RL   Submitted (17-NOV-1998) to the EMBL/GenBank/DDBJ databases.
+RL   Neuroscience, Institute of Biomedical Sciences, Academia Sinica, Taipei
+RL   11529, Taiwan
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..2313
+FT                   /db_xref="taxon:10116"
+FT                   /organism="Rattus norvegicus"
+FT                   /strain="Sprague-Dawley"
+FT   misc_feature    1..1997
+FT                   /note="contains promoter and 5'UTR"
+FT   mRNA            <1998..>2313
+FT                   /product="A2a adenosine receptor"
+FT   CDS             1998..>2313
+FT                   /codon_start=1
+FT                   /note="G protein-coupled receptor"
+FT                   /product="A2a adenosine receptor"
+FT                   /protein_id="AAD45869.1"
+FT                   /translation="MGSSVYITVELAIAVLAILGNVLVCWAVWINSNLQNVTNFFVVSL
+FT                   AAADIAVGVLAIPFAITISTGFCAACHGCLFFACFVLVLTQSSIFSLLAIAIDRYIAIR
+FT                   I"
+XX
+SQ   Sequence 2313 BP; 493 A; 576 C; 683 G; 561 T; 0 other;
+     gatccagccg ttctgcttgg aacatgcgtt acaaacagct agtgggcagg cagcttgtgc        60
+     agaaccggga ctcgcaagga cttagccatc ggtcggtgtc tctgtctgac cttaggagca       120
+     gcggcatgga ttaggaacag caatcctgtc agtttctgca gactttgttt tctccttcca       180
+     aaccttcagt atcggcctca tcaatgacaa aatataagct gcatctgtgt ccactctctc       240
+     tctagactga agccctggca acgtcacagg agcaaccttg aggttcattt cttttagccc       300
+     ctattttgcc tctcggccaa cctcaggtgg agaagaccct tctcccaagg cctccagttc       360
+     cactcctcct tcctctcctt gaggggagaa ggaaaaggaa agatttgtct ccatgtaggg       420
+     gtctgaaagt cagcctgcag cattttgttc ccagcaggca cacccgtggt accatagagg       480
+     tcaagcactg aagaaggtgg actaggggtg gaggtgagga tcctttagct cttgcttggg       540
+     gagtaagagg ctattgggac agtcctgctt acattaaggt tttgcaagct cagctggggc       600
+     ccactatgga gagaccaaga cttccacttt ctaggggtct cagttattcc tgtgaactga       660
+     cattgtgact ctggggtagc ctttccaaat ctgtggataa gtgctgaaat gagcccttgg       720
+     tatctggggc ccaaaggtgt tgtagtctgt gtggagaaac tgaggcctgg gaaagaaaag       780
+     gattcttgcc cacggtcctc cacggcagtc cttactgagt acctgctttt cttgagcagc       840
+     attccctaga gcattctaga gcagcctcag ctacgacctg tggggagagg ggaggtgtgg       900
+     gaggaaagtg gaggcggatc cctcagggaa gcaatcacag cgcctgctct gcctggctgt       960
+     gcagctgtta gtgggagctc tctccgagca gcgggtttgg cttggaccct gctcttgctg      1020
+     cctgtgaggg taagaatggt tacttgccac ttgcggccat aactggagga taggaccaga      1080
+     aggctcccag atctttccag aaaggaactc tggggagtgt ctgaggtgac cttaggggca      1140
+     ggggtgtccc ttggatgggg atggtagtcc tctgaaggga tggagcaaaa tgagttggtc      1200
+     ttggagactg gctcagtgtg agaaggctgg tggaatgggg aaagcccagt ggggaaagaa      1260
+     ccttccttga gggagggtct tgtgggactg gggacccgga ggactggcca ggcagctaca      1320
+     gaaagtttga aaaactactc aaggggagcc aacatagaca tcaacttgcc ttgacttcaa      1380
+     cttgcaccca tagattaaat caaaaacaac aagatcttca gccactagtc caagctggga      1440
+     gggtgggtat ctgtaatacc ccgggtgaga aagatgcatg gggacaggtc agtgagaaat      1500
+     cctagttctg tttgtattct ctcctgtgtc tgccctgaag agactggaga aggaactatc      1560
+     tccctgagaa gggttgggta aagatcttgg taagacttct ttggaaccag tcagctcttg      1620
+     gggcctgtgt cccgacagac cgactgtcac agattgggca agatgggagt cattctcagg      1680
+     tggatgtctg gcccacgcct gactctgaag tggacagggt ggttcagctc ttcactgaga      1740
+     ctctctcttt ccaggtatct cagaaccctg aagccgagag gagccaggcc agatcccctg      1800
+     gagaagtcat gattttggga gatgcagagt cgtctgtgag aacgtcttcg gggagctctc      1860
+     tctgggaacg ctcgtggctc ttgtgaggaa agggctgcgg ggcttgggtg ggtggacggc      1920
+     tgggctgcag ctatggaccg agagctggcc caggcctgca tccctgctga gcctgcccaa      1980
+     gtgtggctgc tcccaccatg ggctcctcgg tgtacatcac ggtggagctg gccatcgctg      2040
+     tgctggccat cctgggcaac gtgctcgtgt gctgggccgt gtggatcaac agtaacctgc      2100
+     agaacgtcac caacttcttt gtggtatcgc tggcggcggc tgacattgca gtgggtgtgc      2160
+     tcgccatccc cttcgctatc accatcagca ccggcttctg cgccgcctgc cacggctgcc      2220
+     tcttcttcgc ctgttttgtc ctggtcctca cgcagagttc catctttagc ctcttggcta      2280
+     tcgccatcga ccgctacatc gccatccgaa ttc                                   2313
+//
+ID   RRD218     standard; DNA; ROD; 2191 BP.
+XX
+AC   D86218;
+XX
+SV   D86218.1
+XX
+DT   27-FEB-1997 (Rel. 51, Created)
+DT   27-FEB-1997 (Rel. 51, Last updated, Version 1)
+XX
+DE   Rat PP1alpha gene, 5'-flanking region.
+XX
+KW   PP1 alpha.
+XX
+OS   Rattus rattus (black rat)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Rodentia; Sciurognathi; Muridae; Murinae;
+OC   Rattus.
+XX
+RN   [1]
+RP   1-2191
+RA   Nomoto K.;
+RT   ;
+RL   Submitted (24-JUN-1996) to the EMBL/GenBank/DDBJ databases.
+RL   Ken Nomoto, Institute of Immunological Science, Hokkaido University,
+RL   Section of Biochemistry; Kita-15, Nishi-7, Kita-ku, Sapporo, Hokkaido 060,
+RL   Japan (E-mail:kenny at imm.hokudai.ac.jp, Tel:+81-11-706-5536,
+RL   Fax:+81-11-707-6839)
+XX
+RN   [2]
+RP   1-2191
+RA   Nomoto K., Shibata N., Kitamura K., Mizuno Y., Kikuchi K.;
+RT   "Molecular cloning and analysis of the 5'-flanking region of the rat PP1
+RT   alpha gene";
+RL   Unpublished.
+XX
+RN   [3]
+RA   Nomoto K., Shibata N., Kitamura K., Mizuno Y., Kikuchi K.;
+RT   "Molecular cloning and analysis of the 5'-flanking region of the rat PP1
+RT   alpha gene";
+RL   Biochim. Biophys. Acta 1309:221-225(1996).
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..2191
+FT                   /db_xref="taxon:10117"
+FT                   /organism="Rattus rattus"
+FT   misc_feature    1..2191
+FT                   /note="5'-flanking region"
+FT                   /gene="PP1 alpha"
+XX
+SQ   Sequence 2191 BP; 492 A; 616 C; 625 G; 458 T; 0 other;
+     gaattcccat ctggagttct tgggccagag atgaaaaggg aaaagatgtt cagtttgaag        60
+     agaaagtgca gaccctcggg ggataataga gatgtaaaag accttccctc caccaccctt       120
+     cttaccttaa tcccacatgg aacctgagga gtgacactgg aatgtcacag ctgagttctg       180
+     ggctggtgtc tacagcaaga ccctagaggc caggcctgat tccacaactc agtcctcagc       240
+     ctctgtcccc tacccatgcc tcacttaccc cagctcagct agttgccccc aatgaagcca       300
+     tatcggtcag cctgacgata tgggctggac ccactgatct ctgagtcgga ccctagagag       360
+     ctagaatcat cctgtagttc tggacggtag caacaagtcc tctcccaggg cctgggccat       420
+     tctgcctaga cccagtgtca cagctgcaag acatatagag agccagtgtg aacagccaga       480
+     ctgaggctgg ggttccagga accagtcctc agtcacgggg gagtcaggta gtccctgagg       540
+     taccacaaag accaagtctc tgtgtagaga cccaccccag gcctggcccc tagcccagct       600
+     cacctccttg ctgcacctca cctcctcctc tcacttcctc ctcagtctca gcttcagcag       660
+     cctattgggg gcccctccct ggtgggggga ctcccccctt cctctatgag gttcttcctg       720
+     cttgccttag tgcctgagcc acggactcct ccatcacgga tggaggtgtg aagagtcccg       780
+     acttgcccaa gttgaagatg acaggccact atcggttttg aggttacttg cgtgtaaaac       840
+     caactcatgg ttccagtaat aattatgctt taatgtcgtc ccaccactcc aacccactgt       900
+     cctgggtttt cttttttgag agtgaaaggg tacagtctgg gaacaagggt ctcacgtagc       960
+     ccaggcagga gatgaactca ctatgtagtt gagcatgacc ctgaacttct gatcctcctg      1020
+     tgtctagact cctgagtgct ggaatttcag gcactggaat tacaggttta tgatacattg      1080
+     ggttctttaa cgtgttactg tttaaaaata atacctttcc ccccttttct ttctttactt      1140
+     tccttccaga gccggagata aaacctcagg ccttgcacat gctagacaag tccaagcatt      1200
+     ctacaaagga cttacaacag gaaggagata aaatagtatt acatcactta acgaaaaaaa      1260
+     aaacctgacg tagcaggcac caaggcaacc tggaccaaaa cattgcttcg agttcagtag      1320
+     caggtgttca tgggtctggc cataaagacc gaggtgaatg tgaggctctg gaggtttgga      1380
+     gctcactctc agtgtcattg agccttagtt cctttttctg cacttcgagg aattacttta      1440
+     cagtgtttga gaagtcagcg attaacatgc tcacaccaca atcccacgca gggctggggt      1500
+     gggaagagac ttggaaagag aaaaacaatt tctacagtac ttccggttct aactcatcag      1560
+     aacgcagcag ggcgattcct cctgggtgga gccgacccaa ctccgcccta caaaccccgc      1620
+     cctccacccc tgccaggcct cgcccggccg cccgaggccc tccccggctg cagtgcttcc      1680
+     ggtccagggg aggcgctaga gagcagggaa ctacggacgc ggcagggcgg ggcggccggc      1740
+     cgaagaggcg gggcggcggg ccgagggcgg gctggggagg gcggaaggag agccaggccg      1800
+     gaaggaggct gcaagagggc gggaggcagg agagggcccg gagctggtgg gccggagcgg      1860
+     cggcgccgcc atgtccgaca gcgagaagct caacctggat tccatcatcg ggcgcctgct      1920
+     ggaaggtggg taggggtagg gaaggtgcgc gcgcgccgag cctgggccca tcgccgtccg      1980
+     gaagtagagc gcgggcgggc ccgccgctct cgggggctag cgtcgcttgg gcggggacag      2040
+     gccgtgaggt tctatggcca cggcagccct ccctactccc tgcgcctagg ctttggagcg      2100
+     cgctccgagg ccggggacgc ttgagtggcc gagactcagg gtgagactcc tgcgaagcta      2160
+     gctgggaagg ggttctgagg cgaggaacct t                                     2191
+//
+ID   MMFLI1G    standard; DNA; ROD; 3221 BP.
+XX
+AC   L47615;
+XX
+SV   L47615.1
+XX
+DT   04-OCT-1995 (Rel. 45, Created)
+DT   04-MAR-2000 (Rel. 63, Last updated, Version 3)
+XX
+DE   Mus musculus DNA-binding protein (Fli-1) gene, 5' end of cds.
+XX
+KW   DNA-binding protein.
+XX
+OS   Mus musculus (house mouse)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Rodentia; Sciurognathi; Muridae; Murinae;
+OC   Mus.
+XX
+RN   [1]
+RP   1-3221
+RX   MEDLINE; 91087339.
+RA   Bergeron D., Poliquin L., Kozak C.A., Rassart E.;
+RT   "Identification of a common viral integration region in Cas-Br-E murine
+RT   leukemia virus-induced non-T-, non-B-cell lymphomas";
+RL   J. Virol. 65(1):7-15(1991).
+XX
+RN   [2]
+RP   1-3221
+RA   Barbeau B., Bergeron D., Beaulieu M., Nadjem Z., Rassart E.;
+RT   "Identification of the human and mouse Fli-1 promoters";
+RL   Unpublished.
+XX
+DR   MGD; MGI:95554; Fli1.
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..3221
+FT                   /db_xref="taxon:10090"
+FT                   /organism="Mus musculus"
+FT                   /strain="C57BL"
+FT   TATA_signal     2043..2049
+FT                   /note="putative"
+FT   exon            2078..2482
+FT                   /gene="Fli-1"
+FT   protein_bind    2187..2202
+FT                   /evidence=EXPERIMENTAL
+FT                   /note="the evidence will be provided in a coming paper.
+FT                   Barbeau et al."
+FT                   /gene="Fli-1"
+FT                   /bound_moiety="GATA-1"
+FT                   /function="DNA binding protein"
+FT   protein_bind    2204..2211
+FT                   /evidence=EXPERIMENTAL
+FT                   /note="the evidence will be provided in a coming paper.
+FT                   Barbeau et al."
+FT                   /gene="Fli-1"
+FT                   /bound_moiety="Spi-1/PU-1"
+FT                   /function="DNA binding protein"
+FT   GC_signal       2371..2383
+FT                   /gene="Fli-1"
+FT   GC_signal       2438..2444
+FT                   /gene="Fli-1"
+FT   CDS             2465..>2482
+FT                   /citation=[2]
+FT                   /codon_start=1
+FT                   /db_xref="MGD:MGI:95554"
+FT                   /gene="Fli-1"
+FT                   /product="DNA-binding protein"
+FT                   /protein_id="AAA77653.1"
+FT                   /translation="MDGTIK"
+FT   intron          2483..>3221
+FT                   /gene="Fli-1"
+FT   protein_bind    2553..2559
+FT                   /evidence=EXPERIMENTAL
+FT                   /note="the DNA binding factor is present in all cell types
+FT                   but we did not identified it. The data will be published in
+FT                   a coming paper. Barbeau et al."
+FT                   /gene="Fli-1"
+FT                   /bound_moiety="ubiquitous protein"
+FT                   /function="DNA binding protein"
+XX
+SQ   Sequence 3221 BP; 690 A; 818 C; 1019 G; 694 T; 0 other;
+     gaattcttgt tgagaaggaa ttgggctcaa tgaagttcgg ggatattcca agtgaattat        60
+     tccagtgagt gttattcagc aatggacgtg actgtcgttt gccagatcag cagaagccga       120
+     aaggaaaacc tggtgattgt ctgccaccac ttggcccttg gggcagggcg gggcggggcg       180
+     gggggcgtgg tgattaaatg tggattggta ttttgtggct ttgtaagtcc cagtgctgga       240
+     aggagacctc tgtgggggag acgtcaaata ctttggacag aaagagggtc ccagtatagc       300
+     ttgggcgacc tctgaaagta gttatcattt gatgttgggt gaaaggaaaa tttggggttt       360
+     gaaaggatgt aattgattct tctttccctt taacctcttt cctctctgga aagcatgtgg       420
+     aaacgctgaa gggaagagca agagggcggg cagccggccg caggcaggaa agggttaagc       480
+     ctgatttctt ttaattgaac ctcagaaccc tggtggccca ggtaaacggg gggggaccct       540
+     gaccccgcta gcggtaacca gatgtggcgg tcccagggga gccccggagc agacccctgg       600
+     attgagaagc agacaggagg agggggagtg gcccggcccc caccccacgc ccccacagta       660
+     accgagtctc caatgctggc aggctgcacc gccactccag gtctggtcag gttcagcccg       720
+     tgtctgtatt cgaaccccaa attggaggcg aattgatgag actaatttgg gaagaggggg       780
+     gaagggggag gaggagggag cgagcgagcg caattgctcc tgaagaaata aagaattaat       840
+     aagtcacctt cttgccggcc gtggacaccc tcttgatttt tttttccttt ccaatttatt       900
+     cggatctgct ctggaatttt tcccctcttt tcccgggagg actcttaaat aatagtgaga       960
+     aagtccacag cgtggtctga agagcgtgga aaaaggtaac ctgttttcaa agtctgggag      1020
+     tcaggccgcc agcgccgata ccccagagaa ggcttaacaa gagagctcct gggtcagcag      1080
+     gggaggcgcg ggggatagca gaaagaaccg agccggtaaa gcgggccacg ccgctggttg      1140
+     ggaatgacag tccctagctt ggacccttag actgcccgtt ctcatccaag gtggggtctc      1200
+     tgctgagccg cggctcgccc tcctgggtcc tgctgcgtag tgtggagggc aagctcgccc      1260
+     tggtgtcagt tccttggggg ctccgatggt attgaagaac ttgggccgtc gggtcctgat      1320
+     aggtgagaga atttaactca aaaagcctag gttgtggctg gtctacctcc ttagcgggct      1380
+     gtggagcccg gagtcgaggc gggccaaagc atgggcatct ctctgctaac aaagcttgag      1440
+     gtattgagcc cttgacaggt caggtccgcg ggacccagaa ttcgctttga gcctatccgg      1500
+     agaccagcgc ttagatgcaa aaactctctt cggctcctct ctttctttct ttctttcttt      1560
+     ctttctttct ttctttcttt ctttctttct ttctttcttc cttccttcct tccttccttc      1620
+     cttccttcct tccttccttc cttccttttt aaaaatagta ggtttgcctt gatctgcatc      1680
+     cgaatctccc ctggcggtca gcatcgccag gttatcccct gttctaacaa actcttccgc      1740
+     cgtcttcctc ccatccccaa aaaagtttga ctccggctgg aaaaagcatt aatgaatgta      1800
+     tctgtgggaa gaaacggaaa gtgaatgagt caggagggcc accttcggcc aaaggcccaa      1860
+     gggaaggaaa gaggccagag cgtttggctt tggatttggg gggaagtgat gggggagttg      1920
+     cagactcagg aatcagggag cggatactgg gcgtggaccc cgtcattgtt cctggccagt      1980
+     cttatctccc aggagcaagt atcctgtgtg cgcagtgcat gaatgtaact gggcatcccg      2040
+     cgtatattta tatagcgagt gatgcgaaaa gcagggcgag gagaggacga gggggtgtgg      2100
+     gggagggaag acaagagaga gcagagagtg gagagggcga gatgagagag agagagagag      2160
+     agagagagag agagagagag agagagagag agagagagat aggacttcct ccccgatcgc      2220
+     aaagtgaagt cacttcccaa aattagctga aaaaaagttt catccggtta actgtctctt      2280
+     tttcgatccg ctacaacaac aaacgtgcac aggggagcga gggcagggcg ctcgcagggg      2340
+     gcactcagag agggcccagg gcgccaaaga ggccgcgccg ggctaatctg aaggggctac      2400
+     gaggtcaggc tgtaaccggg tcaatgtgtg gaatattggg gggctcggct gcagacttgg      2460
+     ccaaatggac gggactatta aggtaagcgg ctgggcagtg ggcgcgggga gagtgccgac      2520
+     cggggcggcg ggagggctgg gcgccggggt cccggaagac gtggccgctc tcccttcctt      2580
+     ccgcgccccg gcttcgcgcg gtctcctccg ggtggcgagt cccccattcc gaggaggccg      2640
+     gccagccttc ccgcccaggg cgatctaccc ctcactcctt gcgccactgt ggaatcccgc      2700
+     aggctcccac tgtgccgccc gaaggctgcg agacccggca gctgaaacct ggggacccgg      2760
+     ggcgcggaga gagtctcggg cgggagatcg ccgggtcggt tcccacccgg cacccagacg      2820
+     acctggcccc ggcgccaggc actagtctgg cggccagctt cctcacgcca gaggccgaga      2880
+     tctgcgcggg caggagcagc ttcgcctctg gctggggtcc cccgaccctc cgagcgagtt      2940
+     ggaggagtag ttgcgggagg gcaaggggtg caagggaggg tgtctgagga tccaggaggt      3000
+     gtcctctcag taagaattaa actccttcaa cagctgtccc cctgcggtgg ctggttcagt      3060
+     ctatggcttc agtctatggc ctggggttgc gattgcaccc ccacccccac ccgccacccg      3120
+     cgccggccca gcttgggtct aggttgcaaa gtgcagacca gcagacctgt gagtctgggt      3180
+     tccctgtcac gcttcagaaa ggccgagtgc tccctccgaa a                          3221
+//
+ID   GG10577    standard; RNA; VRT; 831 BP.
+XX
+AC   U10577;
+XX
+SV   U10577.1
+XX
+DT   11-DEC-1994 (Rel. 42, Created)
+DT   04-MAR-2000 (Rel. 63, Last updated, Version 5)
+XX
+DE   Gallus gallus bone sialoprotein II mRNA, complete cds.
+XX
+KW   .
+XX
+OS   Gallus gallus (chicken)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Archosauria; Aves; Neognathae; Galliformes; Phasianidae;
+OC   Phasianinae; Gallus.
+XX
+RN   [1]
+RP   1-831
+RX   MEDLINE; 91076896.
+RA   Gotoh Y., Pierschbacher M.D., Grzesiak J.J., Gerstenfeld L., Glimcher M.J.;
+RT   "Comparison of two phosphoproteins in chicken bone and their similarities
+RT   to the mammalian bone proteins, osteopontin and bone sialoprotein II";
+RL   Biochem. Biophys. Res. Commun. 173(1):471-479(1990).
+XX
+RN   [2]
+RP   1-831
+RX   MEDLINE; 95335314.
+RA   Yang R., Gotoh Y., Moore M.A., Rafidi K., Gerstenfeld L.C.;
+RT   "Characterization of an avian bone sialoprotein (BSP) cDNA: comparisons to
+RT   mammalian BSP and identification of conserved structural domains";
+RL   J. Bone Miner. Res. 10(4):632-640(1995).
+XX
+RN   [3]
+RP   1-831
+RA   Yang R.;
+RT   ;
+RL   Submitted (13-JUN-1994) to the EMBL/GenBank/DDBJ databases.
+RL   Renji Yang, Orthopedic Surgery, Children's Hospital, Harvard Medical
+RL   School, 300 Longwood Avenue, Boston, MA 02115, USA
+XX
+DR   SPTREMBL; P79780; P79780.
+XX
+CC   On Dec 8, 1994 this sequence version replaced gi:595405.
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..831
+FT                   /db_xref="taxon:9031"
+FT                   /organism="Gallus gallus"
+FT                   /strain="White leghorn"
+FT                   /sub_species="domesticus"
+FT                   /clone="mmpp3, lgpp9 and cBSP5"
+FT                   /tissue_type="bone"
+FT                   /dev_stage="17 day embryo"
+FT   sig_peptide     1..48
+FT   CDS             1..831
+FT                   /codon_start=1
+FT                   /db_xref="SPTREMBL:P79780"
+FT                   /evidence=EXPERIMENTAL
+FT                   /note="BSP"
+FT                   /function="bone matrix protein, calcification and cell
+FT                   adhesion"
+FT                   /product="bone sialoprotein II"
+FT                   /protein_id="AAB38374.1"
+FT                   /translation="MRTALLLACLLATASAFSVRSWLRRARAGDSEENAVLKSRHRYYL
+FT                   YRYAYPPLHRYKGSDSSEEEGDGSEEEEEGGAPSHAGTQAAGEGLTLGDVGPGGDAASA
+FT                   HQDCKGGQKGTRGDSGDEDSDEEEEEEEEEEEEEEVEEQDVSVNGTSTNTTAHTPHGNN
+FT                   TVAAEEEEDDDEEEEEEEEEEEEAEATTAAATTAQDEVTTLGDEQRSEVTTAGEQWEYE
+FT                   VTVGARGDEGPTESSYGDQEEPARGDSYRAYEDEYGYYKGHGYDMYGQDYYYNQ"
+FT   mat_peptide     49..828
+FT                   /evidence=EXPERIMENTAL
+FT                   /product="bone sialoprotein II"
+XX
+SQ   Sequence 831 BP; 204 A; 197 C; 324 G; 106 T; 0 other;
+     atgaggacgg cgctgctgct tgcctgcctg ctggccactg cctccgcctt ctcggtgagg        60
+     agctggctgc gcagagcccg ggcaggcgac tcggaggaga atgcggtgct gaagagccgg       120
+     caccggtact acctgtaccg ctacgcctac ccgccgctgc atcgctacaa gggcagtgac       180
+     tcctcggagg aagaggggga cggctcagag gaggaggagg aagggggggc accgtcccat       240
+     gcaggtactc aggcagcagg cgaggggctg accctcgggg atgtggggcc gggaggtgac       300
+     gctgcgtctg cccatcagga ctgcaaaggg ggccagaagg gcacacgggg tgactcgggc       360
+     gatgaggaca gtgatgagga agaggaggaa gaggaggagg aggaggagga agaagaggta       420
+     gaggagcagg atgtcagtgt caatgggacc agcaccaaca ccacagcaca cacaccccat       480
+     gggaacaaca ccgtggcagc tgaggaggag gaggatgatg atgaggagga ggaagaggaa       540
+     gaagaggagg aggaggaagc tgaagccacc accgctgctg ccaccactgc gcaggatgag       600
+     gtgaccacgt tgggcgatga gcagcgctct gaggtcacta cagctgggga gcagtgggag       660
+     tacgaggtga cagtgggagc ccgcggggat gaaggtccca ctgagagcag ctatggggac       720
+     caggaggagc cagcacgtgg ggacagctac cgcgcctatg aggatgagta cggctactac       780
+     aaggggcatg gctatgacat gtatgggcag gattactact acaaccagtg a                831
+//
+ID   BTU24240   standard; DNA; MAM; 1728 BP.
+XX
+AC   U24240;
+XX
+SV   U24240.1
+XX
+DT   12-JAN-1997 (Rel. 50, Created)
+DT   04-MAR-2000 (Rel. 63, Last updated, Version 2)
+XX
+DE   Bos taurus Fas/APO-1 antigen gene, promoter region and partial cds.
+XX
+KW   .
+XX
+OS   Bos taurus
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Cetartiodactyla; Ruminantia; Pecora;
+OC   Bovoidea; Bovidae; Bovinae; Bos.
+XX
+RN   [1]
+RP   1-1728
+RX   MEDLINE; 96211163.
+RA   Yoo J., Stone R.T., Kappes S.M., Toldo S.S., Fries R., Beattie C.W.;
+RT   "Genomic organization and chromosomal mapping of the bovine Fas/APO-1
+RT   gene";
+RL   DNA Cell Biol. 15(5):377-385(1996).
+XX
+RN   [2]
+RP   1-1728
+RA   Yoo J., Stone R.T., Kappes S.M., Toldo S.S., Fries R., Beattie C.W.;
+RT   ;
+RL   Submitted (07-APR-1995) to the EMBL/GenBank/DDBJ databases.
+RL   Genetics and Breeding, USDA, ARS, Roman L. Hruska U.S. Meat Animal Research
+RL   Center, P.O. Box 166, Clay Center, NE 68933, USA
+XX
+DR   SPTREMBL; P79112; P79112.
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..1728
+FT                   /chromosome="26"
+FT                   /db_xref="taxon:9913"
+FT                   /organism="Bos taurus"
+FT   promoter        <1..1479
+FT   mRNA            1480..>1728
+FT   5'UTR           1480..1640
+FT   CDS             1641..>1728
+FT                   /codon_start=1
+FT                   /db_xref="SPTREMBL:P79112"
+FT                   /product="Fas/APO-1 antigen"
+FT                   /protein_id="AAB40070.1"
+FT                   /translation="MSGIWVHLSLVSRLCPGEASPSSATGLAR"
+XX
+SQ   Sequence 1728 BP; 435 A; 464 C; 436 G; 393 T; 0 other;
+     tgggctaaaa tggcaaatat taggtaagga agaaccattt gtgaaagttg ttgacttatg        60
+     attcattctc aagagatgct gattttgtca gctgtctcgc tctcctccct cccttcctct       120
+     cgcctttctt atgatttttt tttatttcaa taaacttcta atttcagaat agttttcgac       180
+     ttacagaaaa gttgcaaaga taatacagag tctccatatg ccagaccctt tacacccctc       240
+     tccccaacct cccaccattc atttcttttt gtgtctgttt tgggttggga actgcaggag       300
+     caggatcttc ttcacagcac taacaatctg ctgggcagtg aagcaggggg caggtaaatc       360
+     cacacctgta agacagggcc acgagtgcag agcagaaaac agggagagtg aaagcattta       420
+     gaagcaaagc attagaagca aagcaaagct cctaaccttg aattgggaga caggaagatc       480
+     tcccagacga aaatgtcttg aaaatgtctt cagagaggga tccagatgga tgaggaatga       540
+     gccaggcaaa gggagggaaa ggagagtgtt cctaatggga tacagccaac agggaagatg       600
+     gacaaccgag tgcaggtgca gagcttatgg aggaggcggg ccccagctta ccaactactt       660
+     gcagaatcac gctcacgaag gatgtcatta tacaaacctt ctgtaaaact gttgcgaact       720
+     ggctaaccag acgaatcaac ttttccaaaa cagtaatgac ttcgagctgt taaccaaagc       780
+     actaaaatat actttttttt taaataaaga aatgcagaaa tgagtatcag agggaagtaa       840
+     ttgtacgctt taatcatata gctggaggtg tgtgatttgt cttaggagtt agctttgtac       900
+     tcctcgtgag aataaaatat agagggtcct ccctcttcgg aatcctcaca gcactggcca       960
+     ctacagacac tagtccgggg ttcctgtgag cctttaacgt cgccaccacg gcacacggag      1020
+     ctgagccaag gctgggtctg ctctgggaat cccagcagtc agccgaggct cctgctccga      1080
+     gcaagacgcg tgcgctctgc acttcagtcc tccccagcct ccccagatga aactgcagaa      1140
+     gagtttagaa aggacatggg gcccgttctc aggatcctca cctgaacccg agcatgccag      1200
+     tcgactgcgg aaacgctccc aacgggaatg cccgcttgtg caacaacgct ggcgctttcc      1260
+     ccgctccccg ttcaacaccc cttcccccac cccaccccca actccaggcg cagggttgca      1320
+     gaatcaaagg cgccctcccc tactcgggcg ttccccagct aagcttcctc ctccaacccc      1380
+     caccccctgg ctccggggac atttctttag gtcttttcaa atgagctacc aacaggtgtt      1440
+     cagacacgct gctggagaaa gaggaaagcg tcccgagagt aactgtgcgt gagcgcccgg      1500
+     ggcgggcccg ggaggggagc actctcccag gccggctgga gcgcggggag gggccagtcg      1560
+     gggctcacta ctcaccgggt gcgtaactcg ccctggtgcc agttgtaagg ctccttcact      1620
+     tcggagattg tttcacagcc atgtccggga tctgggttca cttgtcactg gtgagtcgtc      1680
+     tctgccccgg cgaggcctct cccagctcgg ccactgggct ggcgcggg                   1728
+//
+ID   HSMPD3S02  standard; DNA; HUM; 565 BP.
+XX
+AC   U29912;
+XX
+SV   U29912.1
+XX
+DT   03-OCT-1995 (Rel. 45, Created)
+DT   02-JUL-1999 (Rel. 60, Last updated, Version 8)
+XX
+DE   Human AMP deaminase (AMPD3) gene, exon 1a.
+XX
+KW   .
+XX
+OS   Homo sapiens (human)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Primates; Catarrhini; Hominidae; Homo.
+XX
+RN   [1]
+RP   1-565
+RX   MEDLINE; 96201708.
+RA   Mahnke-Zizelman D.K., Eddy R., Shows T.B., Sabina R.L.;
+RT   "Characterization of the human AMPD3 gene reveals that 5' exon useage is
+RT   subject to transcriptional control by three tandem promoters and
+RT   alternative splicing";
+RL   Biochim. Biophys. Acta 1306(1):75-92(1996).
+XX
+RN   [2]
+RP   1-565
+RA   Sabina R.L.;
+RT   ;
+RL   Submitted (22-JUN-1995) to the EMBL/GenBank/DDBJ databases.
+RL   Richard L. Sabina, Biochemistry, Medical College of Wisconsin, 8701
+RL   Watertown Plank Road, Milwaukee, WI 53226, USA
+XX
+CC   approximately 400 bp to next reported sequence, GenBank Accession
+CC   Number U29923.
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..565
+FT                   /chromosome="11"
+FT                   /db_xref="taxon:9606"
+FT                   /organism="Homo sapiens"
+FT                   /clone_lib="RPMI 8402, lambda 2001 library of R. Baer"
+FT                   /map="11p13-pter"
+FT                   /cell_type="T-lymphocyte, cytotoxic"
+FT   promoter        1..178
+FT                   /note="may be part of 1a promoter"
+FT                   /gene="AMPD3"
+FT   5'UTR           143..486
+FT                   /gene="AMPD3"
+FT   exon            143..508
+FT                   /label=exon1a
+FT                   /note="multiple transcript initiation sites"
+FT                   /gene="AMPD3"
+FT   intron          509..>565
+FT                   /label=intron1a
+FT                   /gene="AMPD3"
+XX
+SQ   Sequence 565 BP; 40 A; 233 C; 209 G; 83 T; 0 other;
+     ggggagccgg tgtggaagcc gcggggccag cgcagttgag gtctggggag cccggctggc        60
+     atctgctccg ggctgcgggc gggccccgcg gagcccagga ggcggcgggt gcttccggcc       120
+     aagggccctg gcggccgccg cgcccctgct gctctcaagt ttcccgttgg cgccgcggcc       180
+     cgggcgcttc aggtagcctc tcggctctct ctgctccgct ccgcgcccag gtagggcacc       240
+     gacgggggct gcacgcggct ggccggcttc ctccctgctg aggcggccct ccctcctccc       300
+     gcggggccct cctggccggg gatccgcagc gctgcgccct ctgaacgccc ggcccccgcg       360
+     cctgctgcgg ggcggggcct ggccgggccc tggccccggc gggcctcagt gccagcagcc       420
+     ccgctccgct ctgcccagcg cgtccccttt gctccagccc tgcggccgtc cctttcggcc       480
+     ggcggcatgg ccctgtcgtc cgaacccggt gagtgcgcgc gaggctgcgt gctgaccttg       540
+     ggccagcccc gcgaccctgc gcccc                                             565
+//
+ID   HS302451   standard; DNA; HUM; 1093 BP.
+XX
+AC   U30245;
+XX
+SV   U30245.1
+XX
+DT   14-AUG-1995 (Rel. 44, Created)
+DT   04-MAR-2000 (Rel. 63, Last updated, Version 3)
+XX
+DE   Human myelomonocytic specific protein (MNDA) gene, 5' flanking
+DE   sequence and complete exon 1.
+XX
+KW   .
+XX
+OS   Homo sapiens (human)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Primates; Catarrhini; Hominidae; Homo.
+XX
+RN   [1]
+RP   1-1093
+RX   MEDLINE; 94214126.
+RA   Briggs R.C., Briggs J.A., Ozer J., Sealy L., Dworkin L.L., Kingsmore S.F.,
+RA   Seldin M.F., Kaur G.P., Athwal R.S., Dessypris E.N.;
+RT   "The human myeloid cell nuclear differentiation antigen gene is one of at
+RT   least two related interferon-inducible genes located on chromosome 1q that
+RT   are expressed specifically in hematopoietic cells";
+RL   Blood 83(8):2153-2162(1994).
+XX
+RN   [2]
+RP   1-1093
+RX   MEDLINE; 92355667.
+RA   Briggs J.A., Burrus G.R., Stickney B.D., Briggs R.C.;
+RT   "Cloning and expression of the human myeloid cell nuclear differentiation
+RT   antigen: regulation by interferon alpha";
+RL   J. Cell. Biochem. 49(1):82-92(1992).
+XX
+RN   [3]
+RP   1-1093
+RA   Kao W.Y., Briggs J.A., Dworkin L.L, Briggs R.C.;
+RT   ;
+RL   Submitted (21-JUN-1995) to the EMBL/GenBank/DDBJ databases.
+RL   Robert Briggs, Pathology, Vanderbilt University 23rd and Pierce, Nashville,
+RL   TN 37232-5310, USA
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..1093
+FT                   /chromosome="1"
+FT                   /db_xref="taxon:9606"
+FT                   /organism="Homo sapiens"
+FT                   /map="1q21-22"
+FT   exon            850..1093
+FT                   /note="expression is modulated by interferon alpha; MNDA
+FT                   cDNA sequence can be found in GenBank Accession Number
+FT                   M81750"
+FT                   /number=1
+FT                   /gene="MNDA"
+FT                   /product="myelomonocytic specific protein"
+XX
+SQ   Sequence 1093 BP; 347 A; 217 C; 195 G; 334 T; 0 other;
+     tccttttcca gtcatgacca cattttgctt acagatcagc tagttggtaa ccacagcact        60
+     gtctgctaac tgataccatt catttgacaa ttcagagtta tgatactttg tagtgcaccc       120
+     actgttcttc acaggaaaaa aaaattgcag tacaaagggt ttatcaggcc ccctatcatt       180
+     ccagagtttc agtgctgttc cagaatgttc aaggtttcag tcatgatacg aaccaactat       240
+     ccataaataa tgcaaaaagc atgagtaatc atgaatttaa taatcaaggt aaggcagctc       300
+     agttattata ctcaagagag caactagtat gaaactcttt caaattattt gaataaggat       360
+     ttacatattc ataatgactt tctgcctctg tcaagctcca ggtgtatcag ttattaataa       420
+     ctgggtgaat atgtaggtac tatttaaaca aaaacaattt cacagtagac ccacccctat       480
+     ccaagagatg aagtcaagtt ctggtagcaa tagacatctc taccaagatc tcctgctcct       540
+     gccactctgt gaacaggaaa ggagggagaa actttggtgt tttgcctttc ccaatttata       600
+     ttaagatcct tattcaagcg gctaccggtt tctaatgacc tatatgtaag ttagctttat       660
+     aagaaagttc tgagtttgaa actcctttca gcaagtattt gtaagtcaaa aaagcgaaga       720
+     agaggcacca tttactgtca tttctccttg tgactgagat tacttactac aaagaggaac       780
+     tgaccacttt ctctgacatc tgaaatagaa agctacaaag gctgataggc gtggcttcaa       840
+     aattgtttca tgattacata acttctttct agttaggaat taggacagtg taagaaggcc       900
+     atctacaatc aagattgaga gtggctctaa caagtgccat ttttccttgt tagctttcat       960
+     ttctcagccc tttacaagat taaaatagtc tgcagtttaa tctctccaaa gctttacgga      1020
+     cagtgattct gtcctaaaca agacagtgac tccaggattt ctgaagacta ttgtggaaga      1080
+     agcatccatt aag                                                         1093
+//
+ID   HSARB1S1   standard; DNA; HUM; 682 BP.
+XX
+AC   U49855;
+XX
+SV   U49855.1
+XX
+DT   28-MAR-1996 (Rel. 47, Created)
+DT   02-JUL-1999 (Rel. 60, Last updated, Version 3)
+XX
+DE   Human retinoic acid receptor beta 1 (RARbeta1) gene, 5' region  and
+DE   exon 1.
+XX
+KW   .
+XX
+OS   Homo sapiens (human)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Primates; Catarrhini; Hominidae; Homo.
+XX
+RN   [1]
+RP   1-682
+RX   MEDLINE; 97107426.
+RA   Toulouse A., Morin J., Pelletier M., Bradley W.E.;
+RT   "Structure of the human retinoic acid receptor beta 1 gene";
+RL   Biochim. Biophys. Acta 1309(1-2):1-4(1996).
+XX
+RN   [2]
+RP   1-682
+RA   Toulouse A., Morin J., Pelletier M., Bradley W.E.C.;
+RT   ;
+RL   Submitted (23-FEB-1996) to the EMBL/GenBank/DDBJ databases.
+RL   Institut du Cancer de Montreal, Centre de recherche L.-C. Simard, 1560
+RL   Sherbrooke E., Montreal, Qc H2L 4M1, Canada
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..682
+FT                   /chromosome="3"
+FT                   /db_xref="taxon:9606"
+FT                   /organism="Homo sapiens"
+FT                   /map="3p24"
+FT                   /tissue_type="placenta"
+FT   promoter        1..50
+FT                   /gene="RARbeta1"
+FT   exon            51..285
+FT                   /number=1
+FT                   /gene="RARbeta1"
+FT   intron          286..>682
+FT                   /number=1
+FT                   /gene="RARbeta1"
+XX
+SQ   Sequence 682 BP; 102 A; 227 C; 247 G; 106 T; 0 other;
+     aggggcagca accagagcag cagcagtggc agcagtagca ggcgccggcc gccgccgccg        60
+     ctccggctca gctcacgcgg aaaccccact ggggcccgtc gtggctccgc gcggttgcgg       120
+     gccagcgtgg agaggctggg accgtggcgc ccgggggcgg gggcctggcg ccagggggcg       180
+     gggcgcagcg agccgggctc ccgctgtctg ctctcagcgg cggcggcagg ggctgaggca       240
+     cagccagcgg cggccgccgc ggactccaag gcagcccgcc aaaagtaaag ccaggagagc       300
+     gcgctggcgg gtcttcctgt tgggtggctg cttgtcccaa gcccctagct tccccggacc       360
+     ccaagctggg tctggaagac cagggcattt gcatggcatc cagggaccgg ctgcctagca       420
+     gggattttgc gtgtaccgcg gcggggccgg gggctggggg ttggggggtc tgcagcggga       480
+     gcccgcgacc gatcccagga catctggact cgcggacaac tttgcgccgg aatcctcttc       540
+     caagttccct ttattgctat tgtcttagcg cctgtctgac agtctccccg gactccagct       600
+     ttgttctcat taggccaaac ccgccctccc caggggcgtg aacccaggag tcgctggcaa       660
+     gttgcacctg ccagccggat cc                                                682
+//
+ID   HSU52432   standard; DNA; HUM; 1604 BP.
+XX
+AC   U52432;
+XX
+SV   U52432.1
+XX
+DT   02-SEP-1996 (Rel. 49, Created)
+DT   01-JUL-1999 (Rel. 60, Last updated, Version 3)
+XX
+DE   Human G-protein coupled inwardly rectifying potassium channel
+DE   Kir3.1 (HGIRK1) gene, sequence flanking the transcription
+DE   initiation site.
+XX
+KW   .
+XX
+OS   Homo sapiens (human)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Primates; Catarrhini; Hominidae; Homo.
+XX
+RN   [1]
+RP   1-1604
+RX   MEDLINE; 97224457.
+RA   Schoots O., Voskoglou T., Van Tol H.H.;
+RT   "Genomic organization and promoter analysis of the human G-protein-coupled
+RT   K+ channel Kir3.1 (KCNJ3/HGIRK1)";
+RL   Genomics 39(3):279-288(1997).
+XX
+RN   [2]
+RP   1-1604
+RA   Schoots O., Voskoglou T., Van Tol H.H.M.;
+RT   ;
+RL   Submitted (26-MAR-1996) to the EMBL/GenBank/DDBJ databases.
+RL   O. Schoots, Molecular Neurobiology, Clarke Institute of Psychiatry, 250
+RL   College Street, Toronto, ON M5T 1R8, Canada
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..1604
+FT                   /db_xref="taxon:9606"
+FT                   /note="leukocyte genomic library lambda EMBL-3 SP6/T7
+FT                   (Clontech #HL1111j)"
+FT                   /organism="Homo sapiens"
+FT                   /cell_type="leukocyte"
+XX
+SQ   Sequence 1604 BP; 315 A; 427 C; 554 G; 308 T; 0 other;
+     tctagatatt ctgagccttt ctaatagagc catttgcaga aaggatttct attagtgttt        60
+     ctctcctttc tgttctcatc ctaaggcccc tcctgcttcc tgcaactttg agttctgaat       120
+     atgcctatct gagagccagt tgggatctct gtttatgatg caaccccaaa tccaggcatc       180
+     cgtttaaacg agtgcccagt tacagagaca tattgtactt ctcttccttc agagagcagc       240
+     atttgctttt tactgggggc tttctgactg atgcaggggg gcgaggaagg agagttggcg       300
+     ggcgtttggg agcagattta gagccgcttc tcattggagg ggctcgcttt tcctgagctg       360
+     ccagacactg caggctcaac tgaggctcgg aggtgcaatt caggctggtg gagcagcggg       420
+     ggaaggcagg gacaggcggg gctagcgcgg ctctgcagct gatcacacgc accaccacac       480
+     acaccacatt cctgctgccc cggcttgccc ctcgcatctt ccacccgggg ccaccgaggc       540
+     gctgacaagg agtgggggac cgaagaagga agaggcagag gaaaagctag agcggcgcta       600
+     ctgtttaacc tgaaagtctg accggcagcc caaggctcga accccgtcca gcagcaccgc       660
+     tgtcgcctgg aaggagggca cagcgccaag gaacccacga gcccccgctc gagtcattct       720
+     gtgctctgtg cgccaaggat ctttctggca gggacagcgc ggtgccctca gggaggtgcg       780
+     gacgttgggg gacctgcatt ggcgcccatc gtggtacacc aggaaaagtg ggaacgagga       840
+     aaacagccgt gagcgcagag tgcgaggcca ggctgccgct accgccctct gcgccgcctc       900
+     ctgccctctc ccgctgggtg agtgcccagg cttcgcgcac tgccgtgtct cagctgagcg       960
+     cgggggcggc ctgcgggccc ttgagggtcc gccggagggc cccggtggcg cccgcggaaa      1020
+     ctcggcggtc gggggacgcc aggcggacag gtctctggag tccggaaccc gggaatctga      1080
+     gcccggaggg tgggtagggg gcgttgcacc agtgcccggc agacatgcct ttgggcggga      1140
+     ttttggctaa aagataggag acaggtgcgc cgggggtgcg gggagcggtc ccagggggcg      1200
+     ggagattggg gagcggcggg gaggggggag ggtactggtc caggcaggta aaggcagctt      1260
+     cttaggcagc cagcgagttg gcaggtgggt tgggactcgc ttgtcaactc attaatttta      1320
+     agcagtcagt ttgggggtac tgcaggataa tcaggagggc cgtggggagt caagaggtga      1380
+     cccgggatgc cggtggtggg gaaagaaaag aggagcctct ggaagcttgg aggcaaaatt      1440
+     gcgcttgggt tcctgttcct tgcatccctc ctggcttgag tgcgggagaa cactttttaa      1500
+     agactcacct tggaaagaag gcctccgtcc caggggagaa ggagaggcgt ctgcaggggg      1560
+     cagagaccgc agctacctgc cgggtgcgcc ccccacccag gagc                       1604
+//
+ID   HSU54701   standard; DNA; HUM; 5663 BP.
+XX
+AC   U54701;
+XX
+SV   U54701.1
+XX
+DT   23-AUG-1996 (Rel. 49, Created)
+DT   04-MAR-2000 (Rel. 63, Last updated, Version 3)
+XX
+DE   Human phenol sulfotransferase (STP) gene, complete cds.
+XX
+KW   .
+XX
+OS   Homo sapiens (human)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Primates; Catarrhini; Hominidae; Homo.
+XX
+RN   [1]
+RP   1-5663
+RX   MEDLINE; 96211162.
+RA   Bernier F., Soucy P., Luu-The V.;
+RT   "Human phenol sulfotransferase gene contains two alternative promoters:
+RT   Structure and expression of the gene";
+RL   DNA Cell Biol. 15(5):367-375(1996).
+XX
+RN   [2]
+RP   1-5663
+RA   Luu-The V., Bernier F.;
+RT   ;
+RL   Submitted (11-APR-1996) to the EMBL/GenBank/DDBJ databases.
+RL   V. Luu-The, Molecular Endocrinology, CHUL Research Center, 2705 Laurier
+RL   boulevard, Quebec, Quebec G1V-4G2, Canada
+XX
+DR   SPTREMBL; Q92818; Q92818.
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..5663
+FT                   /chromosome="16"
+FT                   /db_xref="taxon:9606"
+FT                   /organism="Homo sapiens"
+FT                   /map="16p12.1-p11.2"
+FT   promoter        1..934
+FT                   /note="Alternative promoter sequence for the first mRNA"
+FT                   /gene="STP"
+FT   mRNA            join(935..1000,2072..2223,2328..2453,2543..2640,
+FT                   3857..3983,4079..4173,4699..4879,5001..5332)
+FT                   /gene="STP"
+FT   exon            935..1000
+FT                   /note="5'untranslated sequence for the first mRNA"
+FT                   /number=1
+FT                   /gene="STP"
+FT   promoter        1001..2001
+FT                   /note="Alternative promoter 2 for the second mRNA"
+FT                   /gene="STP"
+FT   exon            2002..2071
+FT                   /note="exon 2a; 5'untranslated region for the second mRNA"
+FT                   /gene="STP"
+FT   mRNA            join(2002..2223,2328..2453,2543..2640,3857..3983,
+FT                   4079..4173,4699..4879,5001..5332)
+FT                   /gene="STP"
+FT   exon            2072..2223
+FT                   /note="exon 2b; sequence common to both types of mRNAs"
+FT                   /gene="STP"
+FT   CDS             join(2076..2223,2328..2453,2543..2640,3857..3983,
+FT                   4079..4173,4699..4879,5001..5113)
+FT                   /codon_start=1
+FT                   /db_xref="SPTREMBL:Q92818"
+FT                   /gene="STP"
+FT                   /product="phenol sulfotransferase"
+FT                   /protein_id="AAC50480.1"
+FT                   /translation="MELIQDTSRPPLEYVKGVPLIKYFAEALGPLQSFQARPDDLLIST
+FT                   YPKSGTTWVSQILDMIYQGGDLEKCHRAPIFMRVPFLEFKAPGIPSGMETLKDTPAPRL
+FT                   LKTHLPLALLPQTLLDQKVKVVYVARNAKDVAVSYYHFYHMAKVHPEPGTWDSFLEKFM
+FT                   VGEVSYGSWYQHVQEWWELSRTHPVLYLFYEDMKENPKREIQKILEFVGRSLPEETVDF
+FT                   MVQHTSFKEMKKNPMTNYTTVPQEFMDHSISPFMRKGMAGDWKTTFTVAQNERFDADYA
+FT                   KKMAGCSLTFRSEL"
+FT   intron          2224..2327
+FT                   /number=1
+FT                   /gene="STP"
+FT   exon            2328..2453
+FT                   /number=3
+FT                   /gene="STP"
+FT   intron          2454..2542
+FT                   /number=2
+FT                   /gene="STP"
+FT   exon            2543..2640
+FT                   /number=4
+FT                   /gene="STP"
+FT   intron          2641..3856
+FT                   /number=3
+FT                   /gene="STP"
+FT   exon            3857..3983
+FT                   /number=5
+FT                   /gene="STP"
+FT   intron          3984..4078
+FT                   /number=4
+FT                   /gene="STP"
+FT   exon            4079..4173
+FT                   /number=6
+FT                   /gene="STP"
+FT   intron          4174..4698
+FT                   /number=5
+FT                   /gene="STP"
+FT   exon            4699..4879
+FT                   /number=7
+FT                   /gene="STP"
+FT   intron          4880..5000
+FT                   /number=6
+FT                   /gene="STP"
+FT   exon            5001..5332
+FT                   /number=8
+FT                   /gene="STP"
+FT   polyA_signal    5312..5328
+FT                   /gene="STP"
+FT   misc_feature    5333..5663
+FT                   /note="3' flanking sequence"
+XX
+SQ   Sequence 5663 BP; 1309 A; 1556 C; 1557 G; 1241 T; 0 other;
+     cttggaagtc ttgggagatt cacctttact cagatggttg tttacctgtc tcgtgcacag        60
+     cttgaccttg gactttaaag tgaggataaa gaacgacgag gatgggggat gcccccttcc       120
+     acggggccct gtggcttcca aacctcggcc tcctctggtc tcttgtctgt ggagcctcct       180
+     tcaaacccag ggaaataaaa ccacctgcca cgggttgtgg ttcttctagg atcttctatc       240
+     aatgttctct gaggtcccca ggagccatga agctggggct gactcccagg gcaatgggac       300
+     tgcagtgtcc ttgttctttc ttgttctatg catccatgct ctgctccacc cctgcccctt       360
+     cactctgccc acacacatcc ctctagactg gccttgtggt cagagcctgg agtggcatgg       420
+     gctgctgggg gcctgtgggc tgcactgggc cagaacccct ggcaccttca agactggcct       480
+     ggagccagca ggtaggtgac ctttccaggg cctgcctatc ccagctttct cctccaatcc       540
+     ctcccctctc ttgcctgggt caattagaga gagcttgtct gttggctgcc tggcagggtg       600
+     gagttcaggg gcaggtcagg agcccagtga cagctcggaa aaaaaaaaaa aaaaaaaaaa       660
+     aaaaaacaga aaaaaaaaac ctacaaaaac aaacccacca ttgggccttt cccctttcat       720
+     tcttctgttt tctacacagc aaactcagtc gtggctttgg agatcacttt aagcttgtct       780
+     ccagctggca cactaaggag ggtaatggag aagctccccc acccccaacc ccaccccttc       840
+     cttccggaag caaatctaag tccagccccg gctccagatc cctcccacag tggacctagg       900
+     aaaccctcag ctcagagaac aaccctgcat tccccacaca gcacccacaa tcagccactg       960
+     cgggcgagga gggcacgagg ccaggttccc aagagctcag gtgagtgaca cagtggaacg      1020
+     gcccagggcg ccctcaccct gctcagcttg tggctctaac attccagaag ctgaggcctc      1080
+     tggcatccct gccctttccc catggatatc ccatttcaga caaccctggc ctgcgtgaat      1140
+     ccccctccct tcccttgttt gtttgttttt ttccccgggg aggccaggtc ttgctgtcac      1200
+     ccaggctgga gtgctgtggg atcctggcca ctgcagcctt gaattcctgg gctcaagtga      1260
+     ttctcttgcc tcagcctctg gagtagctag gactacaggc cctcatcatc ctgcctggtt      1320
+     aatgtttaag aattttttta aagattttta gagatggggt cttgcaatgc tgcaccaggt      1380
+     tggtctccaa ctcctggcct cagcctccct agggtctggg attataggtg ggagccaccc      1440
+     tgcctaggcc tgtgcttttg ctgagtcatc agagttttgt tcattcccac agcagctctg      1500
+     gcccctagta gcagctcagt tcctcaatgg gccgtgtttg tcctggagcc cagatggact      1560
+     gtggccaggc aagtggatca caggcctggc tggcctgggc ggtttccaca tgtgaggggc      1620
+     tgaggggctc aaggagggga gcatctccac tgggtggagg ctgggggtcc cagcaggaag      1680
+     tggtgagaca aagggcgctg gctggcaggg agacagcaca ggaaggtcct agaggttcct      1740
+     cagtgcagct ggactctcct ggagaccttc acacaccctg acatctgggc cttgcccgac      1800
+     gagggtgctt tcactggtct gcaccatggc ccaggccctg ggattttgaa cagctccgca      1860
+     ggtgaatgaa aggtgaggcc aggctgggga accaccgcat tagagcccga cctggttttc      1920
+     agccccagcc ccgccactga gtggctttgt gagtgcgggc aagtcactca gcctccctag      1980
+     gcctcagtga cttccctgaa agcaagaatt ccactttctt gctgttgtga tggtggtaag      2040
+     ggaacgggcc tggctctggc ccctgacgca ggaacatgga gctgatccag gacacctccc      2100
+     gcccgccact ggagtacgtg aagggggtcc cgctcatcaa gtactttgca gaggcactgg      2160
+     ggcccctgca gagcttccag gcccggcctg atgacctgct catcagcacc taccccaagt      2220
+     ccggtaagtg aggagggcca cccaccctct cccaggtggc agtccccacc ttggccagcg      2280
+     aggtcgtgcc ctcagcctgc tcacctccca tctccctccc tctccaggca ctacctgggt      2340
+     aagccagatt ctggacatga tctaccaggg tggtgacctg gagaagtgtc accgagctcc      2400
+     catcttcatg cgggtgccct tccttgagtt caaagcccca gggattccct caggtgtgtg      2460
+     agtgtgtcct gggtgcaagg ggagtggagg aagacagggc tggggcttca gctcaccaga      2520
+     ccttccctga cccactgctc agggatggag actctgaaag acacaccggc cccacgactc      2580
+     ctgaagacac acctgcccct ggctctgctc ccccagactc tgttggatca gaaggtcaag      2640
+     gtgaggcagg gcacagtgtt tcacatccat aatcccagca ctttgggagg ctgaggcagg      2700
+     cagatcacct gaggttggga gtttgagagc accctgagca acatagaaga accttgtctc      2760
+     tactaaaaat acaaaattag ccgggtgtgg tggcgggtgc ctgtaatccc agctactccg      2820
+     aagcctgaga caggagaatc acttgaaccc gggagaagga ggttgtggtg agccagagat      2880
+     cccaccattg cattccagcc tgagcaacaa gagcaaaact cacaaaaata aataaataaa      2940
+     taaatatata aataaaaata aaactgtggc acctgtggtg gctcactgct gtaatgccag      3000
+     cactttggga ggccaaattg ggtggatcac ttgagctcag gagttacaga ccagcccggg      3060
+     aaacatgggg aggtctccat ctctataaaa atgcaaaata tcagcagggc atggtggcat      3120
+     agcgctgtag ttccagctac tggaaagtct gaggttggag gattgcttga gcctggaagg      3180
+     tcaaggttgc agtgagttat tatcactcca gtgcactcca acttgggcga cagaaaaaaa      3240
+     gaaagaccac ggtccttttt tttttttttt tttttgagac tctctgtctc aaaaataaat      3300
+     aaataaaata aaataaaata aaataaatcc cacaataaaa agaaaaagca aaggtccagg      3360
+     tgtggggcat gtgaatccag ggaaggaggc cctggctcag cccagctttg gtcctgttct      3420
+     tctgggaaag tcgcctcact tcctccagcc ttgtctcatc ttctgcggcg gggactgtct      3480
+     gcctcttgct ctgatgacca agaacgtaag actcttcagt gtagacctaa gaaagctaga      3540
+     gggtgggtcc tcacaggccc acaaaatttg gtggcggtgg gatcacggct ggtggagcat      3600
+     gccttgctcc agattggggt gtgacgcatt gatgcagatt atattactat agaatatgat      3660
+     ggtctcaggg accaggcagg actttggctt ctgagcaggg ttccaggcct cctgacttgg      3720
+     ccctaccggt gcccgtgaga tctcaaacaa gtcagcctct aagcctcagg ttcctccttt      3780
+     gccaatccaa gagatgagct ggcctgggac aggctgtgtg gtgatggtgc tggggttgag      3840
+     tcttctgccc ctgcaggtgg tctatgttgc ccgcaacgca aaggatgtgg cagtttccta      3900
+     ctaccacttc taccacatgg ccaaggtgca ccctgagcct gggacctggg acagcttcct      3960
+     ggagaagttc atggtcggag aaggtgggtt tgatgggagg aaggaaagtg tggagccaag      4020
+     gggtggtggc tacaacgcac agcaaccctg tgttggcacc ccttgcctgc ttctccagtg      4080
+     tcctacggat cctggtacca gcacgtgcag gagtggtggg agctgagccg cacccaccct      4140
+     gttctctacc tcttctatga agacatgaag gaggtgagac cacgtgcgat gcttccctcc      4200
+     atgtgactcc tgggggcagg cacctcacag ggacccgcca aggccaccca gccccctccc      4260
+     tgggcagccc ccacagcagg accagattcc ccatcctgcc ttcttggccc aggcctcccc      4320
+     actaaggccc cacctggcag cgggccccac acagctctca tctctcgcac ctgagtcagc      4380
+     tgcatggggg gccacggatc agaaacttag tcctattgct actccctgcc aaagggtgtg      4440
+     ctacccaggg ccacagtcac agaagaagac catcacggtc ctcacccata ggagccaagc      4500
+     ccagctcatg atgggatcac agggcagaca gcaattcttt ttacccccgg gactgggggc      4560
+     cctgggggtt gaggagttgg ctctgcaggg tttctaggag aagtggccag atcgcctctg      4620
+     aggttagaga aggggacccc ttttactttt cctgaatcag taatccgagc ctccactgag      4680
+     gggccctctg ctgctcagaa cccgaaaagg gagattcaaa agatcctgga gtttgtgggg      4740
+     cgctccctgc cagaggagac cgtggacttc atggttcagc acacgtcgtt caaggagatg      4800
+     aagaagaacc ctatgaccaa ctacaccacc gtcccccagg agttcatgga ccacagcatc      4860
+     tcccccttca tgaggaaagg tgggtgctgg ccagcagggg gtttggggcg ggtgggagca      4920
+     gcagctgcag cctccccata ggcacttggg gcctcccctg ggatgagact ccagctttgc      4980
+     tccctgcctt cctccccgag gcatggctgg ggactggaag accaccttca ccgtggcgca      5040
+     gaatgagcgc ttcgatgcgg actatgcgaa gaagatggca ggctgcagcc tcacgttccg      5100
+     ctctgagctg tgagaggggc tcctggagtc actgcagagg gagtgtgcga atcaaacctg      5160
+     accaagcggc tcaagaataa aatatgaatt gagggcccgg gacggtaggt catgtctgta      5220
+     atcccagcaa tttggaggct gaggtgggag gatcatttga gcccaggagt tcgagaccaa      5280
+     cctgggcaac atagtgagat tctgttaaaa aaataaaata aaataaaacc aatttttaaa      5340
+     aagagaataa aatatgattg tgggccaggc agagtggctc atgcctgtaa tcccagcaat      5400
+     ttgagaagtt gaggctagag gatcactgga ggacaggagt ttgggaccag cctgttcaac      5460
+     attacaagac atcatcccta caaaaatttg agaaaattat ctgtacgtga tggtgggcac      5520
+     ctgtagtccc agctacttga caagtgaagg caggaggatc gcctgagcca gggaggttat      5580
+     ggctgcagtg ggctgactgg gctaatccac tcaagcctga gggacagagc aaatcttgct      5640
+     tgagaaataa ataaaataca att                                              5663
+//
+ID   HSU69634   standard; DNA; HUM; 1515 BP.
+XX
+AC   U69634;
+XX
+SV   U69634.1
+XX
+DT   21-JAN-1997 (Rel. 50, Created)
+DT   04-MAR-2000 (Rel. 63, Last updated, Version 3)
+XX
+DE   Human neurotensin receptor gene, promoter region.
+XX
+KW   .
+XX
+OS   Homo sapiens (human)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Primates; Catarrhini; Hominidae; Homo.
+XX
+RN   [1]
+RP   1-1515
+RA   Le F., Groshan K., Zeng X.P., Richelson E.;
+RT   "Characterization of the genomic structure, promoter region and a
+RT   tetranucleotide repeat polymorphism of the human neurotensin receptor
+RT   gene";
+RL   J. Biol. Chem. 0:0-0(1996).
+XX
+RN   [2]
+RP   1-1515
+RA   Le F., Groshan K., Zeng X.P., Richelson E.;
+RT   ;
+RL   Submitted (05-SEP-1996) to the EMBL/GenBank/DDBJ databases.
+RL   Neuropharmacology, Mayo Clinic Jacksonville, 4500 San Pablo Rd,
+RL   Jacksonville, FL 32224, USA
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..1515
+FT                   /chromosome="20"
+FT                   /db_xref="taxon:9606"
+FT                   /organism="Homo sapiens"
+FT                   /map="20q13"
+FT   promoter        1..1515
+FT                   /gene="neurotensin receptor gene"
+XX
+SQ   Sequence 1515 BP; 266 A; 507 C; 511 G; 231 T; 0 other;
+     gaattctcct agctgggcgg gcccgggagg gggttcctca gcctcccgct tccctcaaca        60
+     ccctgcgacc cccgccccag cctgcccagg tttcctgctc ccagcacagc aggtgcagcc       120
+     agccatgtgc acaaaggcca ggctggttcc ctgggctgca ctcgagcagc tcctcccagc       180
+     cctgcacaca tggggcagca gctctaccca acctctccca ggggttctgg ggaggaggga       240
+     gcaggggagg gggcggggag ggcccaaaaa agggacagta ttgccctggg ggcccctggg       300
+     caacccaaac atggaggggg gggcaagctt gtgcctggcc acctatgcca ttgccaccag       360
+     ttgctggggg ggacacggaa aggacaggaa tcttgccctc acctggctcc cgagccaagg       420
+     ggccggggca acctgtgagg acaattcaga gggagggagt gtgcaaagcc tgcagggcct       480
+     gggaggatgc gtgctggggc tgcctctccc aaatcctgct ggggcgcagg ctctcagggt       540
+     ggcttctgat gacaaatcca ggcagtaata aggggcccag ggcatcacat cccatagcgt       600
+     catgagacca gcccagggtg ccagatgcag ggccctgagt ggggagggtg ctgctctggg       660
+     cacctgcttt ctgccctccc tcattcaccc ctccccagac tttgatgaaa ccatctgtgg       720
+     ctcccggcct ctgcaggacc cagcccctca gctcctcagc ccctgcaggt gtccctcggt       780
+     actgcctcac gccatcctgc cccaggtgat aactatgccc tgagccccca ccatttccac       840
+     tgggcacatc ccagaaatac gcattcacag accagggacg cccatgactg cggccagatt       900
+     ttaaaaggaa tcaccagaaa tgtaatctcc agtggtccta gagccccctg ggcacccagc       960
+     ttctggcacc ctgtggacac ccaggagtgg gggtcggccc aaccagctgt gcaggcgccc      1020
+     aggccctgcc aggggggagg ttcctccctc cctgcttgcc ttccggataa aaccttaacc      1080
+     ccaactgagc gagcccaggg ttgggggagg tgcatagttc ccttcctagc cggtgcgaga      1140
+     aattgcggag aacagggaag agggtggcag gaagggtctg gtgcacgata cccgccgcgc      1200
+     ccgctcggaa tcctggttcc cctggagcgc tcaccccagc ccgccctgcc ccggggagcg      1260
+     cgagggggcg acccgccagg ctgcacccgg gcagggcggg gatggcggcg ggggctgcct      1320
+     ccctcgtccg ccgccacccc ccactgctgg gcgcgccgcg cggccgccgg ctccgtggag      1380
+     acgcgcagag ccgggagggc gcgggcgcgg cgggaggtgt gcggggctgg ggtgcgcgga      1440
+     gagcgcgagg gaggagattc tgagcgaggg aggggagcgc gcccgggcag cagtgcgtgc      1500
+     gctcctcccg gcgcc                                                       1515
+//
+ID   HSULDHX01  standard; DNA; HUM; 1984 BP.
+XX
+AC   U75286;
+XX
+SV   U75286.1
+XX
+DT   12-NOV-1996 (Rel. 49, Created)
+DT   01-JUL-1999 (Rel. 60, Last updated, Version 3)
+XX
+DE   Human fatty aldehyde dehydrogenase (ALDH10) gene, 5' flanking
+DE   region and exon 1.
+XX
+KW   .
+XX
+OS   Homo sapiens (human)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Primates; Catarrhini; Hominidae; Homo.
+XX
+RN   [1]
+RP   1-1984
+RX   MEDLINE; 97179213.
+RA   Rogers G.R., Markova N.G., De Laurenzi V., Rizzo W.B., Compton J.G.;
+RT   "Genomic organization and expression of the human fatty aldehyde
+RT   dehydrogenase gene (FALDH)";
+RL   Genomics 39(2):127-135(1997).
+XX
+RN   [2]
+RP   1-1984
+RA   Compton J.C., Rogers G.R., Markova N.G., De Laurenzi V., Rizzo W.B.;
+RT   ;
+RL   Submitted (17-OCT-1996) to the EMBL/GenBank/DDBJ databases.
+RL   Laboratory of Skin Biology, NIAMS, National Institutes of Health, 6 Center
+RL   Dr., MSC 2757, Building 6/Room 429, Bethesda, MD 20892-2757, USA
+XX
+DR   SWISS-PROT; P51648; DHA4_HUMAN.
+XX
+CC   Distance between segment 1 and 2 - approx 2 kb.
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..1984
+FT                   /db_xref="taxon:9606"
+FT                   /organism="Homo sapiens"
+FT   misc_feature    1..1351
+FT                   /note="5' flanking sequence"
+FT                   /gene="ALDH10"
+FT   GC_signal       872..877
+FT                   /gene="ALDH10"
+FT   GC_signal       1160..1165
+FT                   /gene="ALDH10"
+FT   GC_signal       1218..1223
+FT                   /gene="ALDH10"
+FT   GC_signal       1302..1307
+FT                   /gene="ALDH10"
+FT   GC_signal       1350..1355
+FT                   /gene="ALDH10"
+FT   exon            1352..1762
+FT                   /number=1
+FT                   /gene="ALDH10"
+FT   5'UTR           1352..1609
+FT                   /gene="ALDH10"
+FT   intron          1763..>1984
+FT                   /number=1
+FT                   /gene="ALDH10"
+XX
+SQ   Sequence 1984 BP; 431 A; 531 C; 632 G; 379 T; 11 other;
+     tttaaaaggg aggagcgggc tggaggggaa agagggagaa catggtcatt actgaatcca        60
+     cacattgcac aaatagaaaa aggaacaggc aggggaatag tcaattatgt atttgcctcc       120
+     tgctgtgtaa atcagcactt cagtaagata aggtgaggac agagcagcta cctgtgggga       180
+     catttaacct tttatctgta gctatctgct tagggacata gagaaaggca gnttcttgca       240
+     tgactcagct ttttgcttaa ttttttcctt ttggcatatg aattgagctc ccacgngntt       300
+     ttggttggtt ttgggcataa gtggagagtt caattggggc cagggccccg agttattttc       360
+     ttttcacaaa tatacccttt agagttcaga ggaaaggctg ggattagagc cttctttgag       420
+     cactattcat ggattacatg agggagtngc tgtgaaaaga gggccccgga ctaagccctg       480
+     ggcacctgaa caagtgagag gtcaggaagg ggagaaaaat ccagcaaagg aaccccagag       540
+     gacccggcca gtagctaaaa agaaaagtgc ggaagagtgc agggaaatgg taaagaaaag       600
+     aaagctttcc acaagacagg accgatcagc tgagccaact gctgctgagt acagtgatga       660
+     gagctgaagt ctctcgcccg aaaggcaata aggcgggagg gggaaacctg agggcagcgg       720
+     gttctctctt gggagcggga acacggaacc atgggcagcg aggcaaatgc agcctgggga       780
+     gaagctctga gtaacggacg tgcgaggatg atgcttgtgc aagaaggaaa tgaccgctgt       840
+     cccggctccg cgggagacga accccggctt cccgccctca gggactagct ctccagggaa       900
+     ctgggacggt cagtgccggt cgaggcagct cctcgctgaa ggaaggagca ggggacaggg       960
+     aacggaatgg ggagcgctag cccccaacta cgtccatctg gccatgtttg aagagccana      1020
+     aaatggagga gggaacccct agagcgtgcc agacggagac tgctctccgt ngcagtcggg      1080
+     gcgcttccgg cagggcgccn actcccagcc gagcgccctc cgcctgctcc tccaggattc      1140
+     ctcttcgccc tttctggggc cgccccgggg cgctctcagn aggatggcca acaccttccc      1200
+     tccatcccta caccccgccg ccccctgccc gtggccgcgc tcggctcccg cactgctcac      1260
+     tccaccccct acatcccagc ccgctgccag agccggggag agggcggggg ccgcgtgggc      1320
+     gagaccgtga acagcggctg tcacgtgggc cgcccaggcc aataggggtg aggctttggg      1380
+     tccagctcag tcctcccccg gcgcctccga ctggcagtgg gactcagcgg gcgtggaggt      1440
+     cgcggctgag cgagcgagcc ctgggcgagt gaattgtggc tgtgggttga cggtggagac      1500
+     accccccgga gggaggcgga gggaagggag gcgaggcctg cacctgcatg cttcccgcct      1560
+     cccactcccc agcgcccccg gaccgtgcag ttctctgcag gaccaggcca tggagctcga      1620
+     agtccggcgg gtccgacagg cgttcctgtc cggccggtcg cgacctctgc ggtttcggct      1680
+     gcagcagctg gaggccctgc ggaggatggt gcaggagcgc gagaaggata tcctgacggc      1740
+     catcgccgcc gacctgtgca aggtancacg cgtgcggcgg ggtgtgggga aactggcccc      1800
+     cgccgngcac ttgtggactg gagtcttcgg ctgggttttg tttttgcttt tacatttngg      1860
+     attactccac cactgggagt atgatctcca gcgatacaga taaagccaaa gttcccgcag      1920
+     actttccagg tcctctagca ctcagaaggg catatgttac ctagcttctg tggttccttt      1980
+     tctg                                                                   1984
+//
+ID   HSU80601   standard; DNA; HUM; 632 BP.
+XX
+AC   U80601;
+XX
+SV   U80601.1
+XX
+DT   09-FEB-1997 (Rel. 50, Created)
+DT   04-MAR-2000 (Rel. 63, Last updated, Version 5)
+XX
+DE   Human novel unknown gene, partial 3'UTR, and VEGF-related factor
+DE   (VRF) gene, promoter region.
+XX
+KW   .
+XX
+OS   Homo sapiens (human)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Primates; Catarrhini; Hominidae; Homo.
+XX
+RN   [1]
+RP   1-632
+RX   MEDLINE; 97168987.
+RA   Silins G., Grimmond S., Egerton M., Hayward N.;
+RT   "Analysis of the promoter region of the human VEGF-related factor gene";
+RL   Biochem. Biophys. Res. Commun. 230(2):413-418(1997).
+XX
+RN   [2]
+RP   1-632
+RA   Silins G.U.;
+RT   ;
+RL   Submitted (29-NOV-1996) to the EMBL/GenBank/DDBJ databases.
+RL   Queensland Institute of Medical Research, P.O., Royal Brisbane Hospital,
+RL   Herston, Queensland, 4029, Australia
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..632
+FT                   /chromosome="11"
+FT                   /db_xref="taxon:9606"
+FT                   /organism="Homo sapiens"
+FT                   /map="11q13"
+FT   3'UTR           <1..77
+FT                   /note="novel unknown gene"
+FT   polyA_signal    60..65
+FT                   /note="novel unknown gene"
+FT   promoter        80..435
+FT                   /note="minimal promoter of VRF"
+FT                   /gene="VRF"
+FT   misc_feature    317
+FT                   /note="major transcription initiation site of VRF"
+FT                   /gene="VRF"
+FT   misc_feature    333
+FT                   /note="major transcription initiation site of VRF"
+FT                   /gene="VRF"
+FT   misc_feature    335
+FT                   /note="major transcription initiation site of VRF"
+FT                   /gene="VRF"
+FT   misc_feature    342
+FT                   /note="major transcription initiation site of VRF"
+FT                   /gene="VRF"
+FT   misc_feature    392
+FT                   /note="major transcription initiation site of VRF"
+FT                   /gene="VRF"
+FT   misc_feature    400
+FT                   /note="major transcription initiation site of VRF"
+FT                   /gene="VRF"
+FT   CDS             630..>632
+FT                   /codon_start=1
+FT                   /note="Unknown"
+FT                   /gene="VRF"
+FT                   /product="VEGF-related factor"
+FT                   /protein_id="AAD14880.1"
+FT                   /translation="M"
+XX
+SQ   Sequence 632 BP; 47 A; 295 C; 224 G; 66 T; 0 other;
+     ctgcagtgcg ttcccgcttt gcttccttcc ctggacggcc cgctccccga aacgcgcgca        60
+     ataaagtgat tcgcagagct cgtgtccggc tccctcctta aggcccgacg cccccggccc       120
+     cggcctcgcc aaggggcagc gccccgccct ccgggtagtg gcggcggcga ctggggagcc       180
+     cagcctcctg ggcggtgcgt cccctttccc ctgccgcggc gggaggcggg agggggtgtg       240
+     tggaggaggc gggccccgcc gacggcctcg cccccccacc ccgccgcccc gcccccgccc       300
+     cacgggccgg tggggagcgc gtgtctgggt cacatgagcc gcctgcccgc cagcccgggc       360
+     ccagcccccc gccgcccccg ccgtccccgc cgccgctgcc cgccgccacc ggccgcccgc       420
+     ccgcccggct cctccggccg cctccgctgc gctgcgctgc gctgcctgca cccagggctc       480
+     gggagggggc cgcggaggag ccgccccccg cgcccggccc ccgcccgccg cgcccgggcc       540
+     cgcgccatgg ggctctggct gccgccgccc cccgcgccgc cgggctaggg cgatgcgggc       600
+     gcccccggcg ggcggccccg gcgggcacca tg                                     632
+//
+ID   BTCAMPPK   standard; DNA; MAM; 926 BP.
+XX
+AC   X75410;
+XX
+SV   X75410.1
+XX
+DT   13-NOV-1993 (Rel. 37, Created)
+DT   29-APR-1997 (Rel. 51, Last updated, Version 9)
+XX
+DE   B.taurus gene for cAMP-dependent protein kinase beta2 suabunit
+XX
+KW   cAMP-dependent protein kinase C beta subunit.
+XX
+OS   Bos taurus
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Cetartiodactyla; Ruminantia; Pecora;
+OC   Bovoidea; Bovidae; Bovinae; Bos.
+XX
+RN   [1]
+RA   Wiemann S., Steuer B., Alonso A., Kinzel V., Pyerin W.;
+RT   "Promoter of the gene encoding the bovine catalytic subunit of
+RT   cAMP-dependent protein kinase isoform C beta 2";
+RL   Biochim. Biophys. Acta 1309:211-220(1996).
+XX
+RN   [2]
+RC   revised by [3]
+RA   Wiemann S.;
+RT   ;
+RL   Submitted (05-NOV-1993) to the EMBL/GenBank/DDBJ databases.
+RL   S. Wiemann, EMBL, Meyerhofstr. 1, 69012 Heidelberg, FRG
+XX
+RN   [3]
+RP   1-926
+RA   Wiemann S.;
+RT   ;
+RL   Submitted (29-APR-1997) to the EMBL/GenBank/DDBJ databases.
+RL   S. Wiemann, EMBL, Meyerhofstr. 1, 69012 Heidelberg, FRG
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..926
+FT                   /chromosome="XI left arm"
+FT                   /db_xref="taxon:9913"
+FT                   /organism="Bos taurus"
+FT                   /tissue_type="heart"
+FT                   /dev_stage="adult"
+FT                   /clone_lib="vectorette PCR library"
+FT   CDS             914..>926
+FT                   /EC_number="2.7.1.37"
+FT                   /product="protein kinase"
+FT                   /protein_id="CAA53163.1"
+FT                   /translation="MAAY"
+FT   mRNA            823..>926
+FT                   /product="cbeta2 subunit of cAMP-dependent protein kinase"
+FT   mRNA            843..>926
+FT                   /product="cbeta2 subunit of cAMP-dependent protein kinase"
+FT   mRNA            844..>926
+FT                   /product="cbeta2 subunit of cAMP-dependent protein kinase"
+FT   promoter        459..864
+FT                   /gene="cbeta2 subunit of cAMP-dependent protein kinase"
+XX
+SQ   Sequence 926 BP; 277 A; 132 C; 168 G; 349 T; 0 other;
+     ctagaaatga acatatctca gtcaactaga aggatttttt ccctctcaat tgaaatttct        60
+     tgctgtgact gattttatat attttaaatc ttaatatttt ttcaaatcat agaatgtttt       120
+     aaaatgtact gctgatgtcc acttgtcagc agattatgtt tggtaagcaa agaatcccag       180
+     ggacagagga gcctagtggg ctgccgtcta tggggtcaca cagagtcgga catgactgaa       240
+     gtgacttagc agcagcagca gcaactacca tactaagttt ttgtaatttc tgtatgtatt       300
+     agatttaagt cagtgagtta gcaatgttga ggttttttaa attatagttc acattttttt       360
+     cattaaaagt tatgtttgtt ttttaatgtt ttgcagtatc tgttccatac cagttttcaa       420
+     tgaaaagtta actgtttata aggatctata aagtctatac tagtctgtat tagctgattt       480
+     gctgggggaa aaaaccatac aatcttttaa acattatatt cagagagtgg tttgaccttc       540
+     agttatttat atagggttgt aatgtatgtt taaatagttt ttccttttaa aatttttttc       600
+     agcttattat ttgtatttaa agctttatat ttaatgttct tattaacctg tgtgttagta       660
+     ttaaaacact caaacataga cccttttagg atgacattgc aagtctttaa aatcttcatc       720
+     tctagttgga cagttttaag gctcagtaat gtgctgtttt atattaacag gaaacagaac       780
+     agcagtagtg gtttgaatac tctgcaaaca ggaagtttga cacatgcata gctcttagct       840
+     tctgtgtaag tagttgttga gctccttctg gaaatatttt cagttacgat aagttaagtg       900
+     taaatacacg tgaatggcag cttaca                                            926
+//
+ID   HSDBIEX12  standard; DNA; HUM; 2692 BP.
+XX
+AC   X94563;
+XX
+SV   X94563.1
+XX
+DT   01-MAR-1996 (Rel. 47, Created)
+DT   05-AUG-1998 (Rel. 56, Last updated, Version 4)
+XX
+DE   H.sapiens dbi/acbp gene exon 1 & 2
+XX
+KW   dbi/acbp gene; diazepam-binding inhibitor/acyl-CoA-binding protein.
+XX
+OS   Homo sapiens (human)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Primates; Catarrhini; Hominidae; Homo.
+XX
+RN   [1]
+RA   Swinnen J.V., Esquenet M., Rosseels J., Claessens F., Rombauts W.,
+RA   Heyns W., Verhoeven G.;
+RT   "A human gene encoding diazepam-binding inhibitor/acyl-CoA-binding
+RT   protein:transcription and hormonal regulation in the androgen-sensitive
+RT   human prostatic adenocarcinoma cell line LNCaP";
+RL   DNA Cell Biol. 15:197-208(1996).
+XX
+RN   [2]
+RP   1-2692
+RA   Swinnen J.V.;
+RT   ;
+RL   Submitted (28-DEC-1995) to the EMBL/GenBank/DDBJ databases.
+RL   J.V. Swinnen, Katholic University of Leuven, Legendo, Campus Gasthuisberg
+RL   O&N, Herestraat 49, 3000 Leuven, BELGIUM
+XX
+RN   [3]
+RA   Swinnen J.V., Alen P., Heyns W., Verhoeven G.;
+RT   "Identification of Diazepam-binding Inhibitor/Acyl-CoA-binding Protein as a
+RT   Sterol Regulatory Element-binding Protein-responsive Gene";
+RL   J. Biol. Chem. 273:19938-18844(1998).
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..2692
+FT                   /db_xref="taxon:9606"
+FT                   /organism="Homo sapiens"
+FT                   /clone_lib="HL1067j (Clontech)"
+FT                   /clone="hgDBI3"
+FT   exon            1163..1259
+FT                   /evidence=EXPERIMENTAL
+FT                   /label=ex1
+FT                   /number=1
+FT   exon            1758..1843
+FT                   /evidence=EXPERIMENTAL
+FT                   /label=ext2
+FT                   /note="exon 1b"
+FT                   /note="used only in type 2 transcripts"
+FT   exon            2386..2503
+FT                   /evidence=EXPERIMENTAL
+FT                   /label=ex2
+FT                   /number=2
+XX
+SQ   Sequence 2692 BP; 532 A; 827 C; 730 G; 603 T; 0 other;
+     tgtgtaacaa tctcgcaaag acgttcccct ccgtctcctc atcctctttt caaacccttt        60
+     tacgatttcc catctcactc agcatgacag tcaaagtccc tgtgatggcc aacttctgca       120
+     tcacctagcc agtctgccac cgccaaaact ctccagcctc atctttctac tcttcccctg       180
+     gttccttgcc cacgccttta cacttgttct ctgcttggaa tcttccctcc cctccttgag       240
+     gaactttctc aaatgtcacc ttccctcaat actccccctc ctccatttaa aactataaac       300
+     ttccaactct ctaagcccct aaagtactct atatttaact tattgtataa actactgtcc       360
+     ctacttgtaa gttccaagat tgcagggatt cacccgcttt gttcactgct gtctgccaag       420
+     gtctagaaca gtgcaagtta cccaacagga gttcaataaa cagccattca tttaacaaat       480
+     atttgctgag cacttcgtcc cgtccaagtt tgttaaatca agacaaataa gacaccgtcc       540
+     ctgcctttaa cgcaccagat ggagaaatgc accacagaca taaatgtgca atacaggcct       600
+     gacactacgg ccacaagcaa gtcaaagaac gtgccaaaag ttcagaggaa gaagcctcgg       660
+     cttcgccttt cgggagacca gtccagcttt ccaccatcac gctgctcatc agggaccatc       720
+     tccgggggtc tcctctagac cccaagggag gagcgggtcc cgcccgccat tcccaggtct       780
+     cagagtttac ttgtccagag atgcaacttc cggcctcttc aggccgggca agatttaagg       840
+     aaagaaaaga aacataagga cctccgttct tcggtctccg tcccctcccc ttcccccgcg       900
+     tgccgtcccc acaacgggcc aggactgaac ccaactctcg accaactccc ggcagcaaaa       960
+     ctaagcaccc tacttccgtt gtccccacct gttcccggcg tccccttcgg ctactcccgg      1020
+     cgtttgcgca agcggtccca cgtgggctcg ggcggggcta gcgccgcggc gggggctggg      1080
+     cacgccccta gcgcatagct ggcttctgat tggctttccg gtgctcgccc gagcagggtt      1140
+     ggggcgagtg gaccgcgcct ctaaaggcgc ttgccagtgc aatctgggcg atcgcttcct      1200
+     ggtcctcgcc tcctccgctg tctccctgga gttcttgcaa gtcggccagg atgtctcagg      1260
+     tacagcgcgt gcacagccag gctgcgaagg tgcagcgggc gggaggcccg ttgggggctc      1320
+     agccggctgc cagaagctct cgggctcttt ccttccgtgc ccctcacttg ctcatgggcc      1380
+     catgcctagc cctgattcgt tggacagagc cttgtgagcg ggattttccg tttggggatt      1440
+     tctaaatctg ctgcccaccc cgcaactgcc ggaaagttgc ccatggggtg gacttcgctg      1500
+     tgtagcggga gaggggtggg agtcgagggt gcttgatgga gagatggggg aaggggttgc      1560
+     acggattgga ggagcgagga gactcagtcc ccatcccgaa gcacagggca ggacgtcgcg      1620
+     gcggagtggg gaagcgagga gtccgtggcc gggagcttgg aggtcagggg aagtacgggg      1680
+     ccggctgctc agagtgcggg acgaggagaa tcgcggcccg gggagaggtg acccaggggc      1740
+     ccctcccttc tctccagtgt agacccttgt ctgagaccga gctatgtggg gcgacctctg      1800
+     gctcctcccg cctgcctctg ccaatccggg cactgggaca gaggtcggtg ttgaacgcgc      1860
+     gggccccagg gggagggagg ggaccaacgg gctccggcgc tgacaccgcg gcactcatgc      1920
+     cctgtcccct ttcagctgtt tccagcatac tgtgccccgt ctgtcctcag gccagggctt      1980
+     cgctgcagcc ccggccactc cctagtgcct ggcccggtgg tggccaggca gttggccgcg      2040
+     ctgcttctcc cgcagagggg acccccactg gggcgaaggc ttggcctgcc ctcttcactg      2100
+     ctgtatttcc agacctgatg cctgcgtttg tgagagctct ggatatatgg ttttcgattg      2160
+     aatgagtgaa ctggaggggc ttccccttct tgtgttgctg aatctttcta gctgccctgt      2220
+     tggggcaggg aggggcagac acacttcagg ggctgcattg cccgaagggt gccacctttc      2280
+     ccacctctcc atccccgtaa ctgggctgtc atcaggccac agtaggattc ttaccctctc      2340
+     ccacccagag gaggccctca atcctctcct ctcccttcca tttaggctga gtttgagaaa      2400
+     gctgcagagg aggttaggca ccttaagacc aagccatcgg atgaggagat gctgttcatc      2460
+     tatggccact acaaacaagc aactgtgggc gacataaata caggtatgca gagcgggggt      2520
+     tggaagggca tctgctcatc aaagcaggct cagcagccca gactggaagt ccctgggaac      2580
+     ttcactctca aactgcctga ggccctactc ttcaggtggg gtatggtgat ggttcctgag      2640
+     gtggaaaaga ccatgttccg gattctcagt gtctccagta gtaacagaat tc              2692
+//
+ID   HSACTHPRO  standard; DNA; HUM; 1066 BP.
+XX
+AC   Y10100;
+XX
+SV   Y10100.1
+XX
+DT   17-DEC-1996 (Rel. 50, Created)
+DT   21-JAN-1997 (Rel. 50, Last updated, Version 5)
+XX
+DE   H.sapiens ACTH receptor promoter & exon 1
+XX
+KW   ACTH receptor; promoter.
+XX
+OS   Homo sapiens (human)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Primates; Catarrhini; Hominidae; Homo.
+XX
+RN   [1]
+RP   1-1066
+RA   Naville D.;
+RT   ;
+RL   Submitted (10-DEC-1996) to the EMBL/GenBank/DDBJ databases.
+RL   D. Naville, INSERM-INRA U418, Hopital Debrousse, 29 rue Soeur Bouvier, F- 
+RL   69322 LYON cedex 05, FRANCE
+XX
+RN   [2]
+RA   Naville D., Jaillard C., Barjhoux L., Durand P., Begeot M.;
+RT   "Genomic structure and promoter characterization of the human ACTH receptor
+RT   gene";
+RL   Biochem. Biophys. Res. Commun. 230:7-12(1997).
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..1066
+FT                   /chromosome="18"
+FT                   /db_xref="taxon:9606"
+FT                   /organism="Homo sapiens"
+FT                   /map="p11.2"
+FT   promoter        <1..1017
+FT                   /note="ACTH receptor promoter"
+FT   exon            1018..>1066
+FT                   /product="ACTH receptor"
+XX
+SQ   Sequence 1066 BP; 287 A; 257 C; 210 G; 312 T; 0 other;
+     ctgcagggca tgttgcggag gcacacacct actcagaaac agtcgaagtc tgggatgatc        60
+     ctgggtccat gagttcctgg ggacaacacg ctttgcctca gtgacaggcc aggaaaagcc       120
+     actttataaa attgtgttta cccgcctggc aaattcaact caggcctctc tctttgggtc       180
+     ttttccagac cacccacgtg tgaacacttt ttagcttggg gcggaacgtc acatttcaga       240
+     aacagccact ggtttggcac cagccccaaa aacccaggac catctggaaa cttggcccaa       300
+     ttccacactt caacattcct gttactgtga ctgacaccaa cagtagccct tccctgcagg       360
+     ccccggcagg cagaaaacac acagcattgc accctaaaat ggaagaattt tgctttgaat       420
+     gatggctctt atctatggcg gtttctgtga agtttttgga cggagaagca ttggcagaac       480
+     acagggtttt tttcttgtct ggacccatgc gtcatatgtg cacttgagca cacagttccc       540
+     tcactctcat tgtttagtct tgtgaaatag ggataatggg gctattccct tcttcttaat       600
+     gaaactaatg agccaaatat ttgcaagata tatcaagaag tttgctagaa gttttaaaac       660
+     aaattcttcc aaaaccattt tctcaaaaac ctgatttatt taattcctta gttctttttg       720
+     gaaataaatg caactctaaa gtggcattta aaaagagcaa gatgacaatt ccataatctg       780
+     ctagaaacat tgtcataaac attggaagta accttgacta gctgagctca tggaaattat       840
+     gtcttcatct gcctgtgtct ttccatttct ctaacttcac attaccagaa atgcacagtt       900
+     catgtgggat gacatttatt caaggtaatg ataacaatct agctgtatct ccggtgatgc       960
+     atgtgttccg gcccttcccg gcccaaggtc cacttgcttg cttttctctc cgagctcatt      1020
+     ccttctcatt cattttgccc agaaagttcc tgcttcagag ctgaag                     1066
+//
+ID   MMG67PRO   standard; DNA; ROD; 1352 BP.
+XX
+AC   Z49978;
+XX
+SV   Z49978.1
+XX
+DT   06-JAN-1996 (Rel. 46, Created)
+DT   06-JAN-1996 (Rel. 46, Last updated, Version 2)
+XX
+DE   M.musculus DNA for GAD67 gene promotor sequence.
+XX
+KW   .
+XX
+OS   Mus musculus (house mouse)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Teleostomi;
+OC   Euteleostomi; Mammalia; Eutheria; Rodentia; Sciurognathi; Muridae; Murinae;
+OC   Mus.
+XX
+RN   [1]
+RP   1-1352
+RA   Szabo G., Kortvely E., Urban Z., Greenspan R., Katarova Z.;
+RT   "Genomic Organization of the Mouse Glutamic Acid Decarboxylase Gene Coding
+RT   for the 67kDa Isoform and Its Multiple Promoter Region";
+RL   Unpublished.
+XX
+RN   [2]
+RP   1-1352
+RA   Szabo G.;
+RT   ;
+RL   Submitted (29-JUN-1995) to the EMBL/GenBank/DDBJ databases.
+RL   Szabo G., Biological Research Center, Biochemistry, Temesvari krt. 62.,
+RL   Szeged, Hungary, 6701
+XX
+DR   MGD; MGI:95632; Gad1.
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..1352
+FT                   /db_xref="taxon:10090"
+FT                   /organism="Mus musculus"
+FT                   /strain="BALB/c"
+FT                   /dev_stage="adult"
+FT   CAAT_signal     794..799
+FT   CAAT_signal     941..946
+FT   GC_signal       1078..1083
+FT   GC_signal       1094..1099
+FT   GC_signal       1113..1118
+FT   TATA_signal     813..816
+FT   TATA_signal     979..983
+XX
+SQ   Sequence 1352 BP; 344 A; 385 C; 364 G; 259 T; 0 other;
+     ccccaaaaat ccagtttgtt ttgcccctaa aggatgagaa acggagggag aggaaaaaga        60
+     aagccaggag gtagcggcga gaaggctaga agaggccggc cgttacagag cctttcgggc       120
+     atctccaggt gttgtctagg gcgcaccagg gaaaaggccg ccagcacggg gtctctgtgt       180
+     gtttggcgcc ctctggtgga aattttttcc aataccgcct ttttatggtg ggggacttca       240
+     ccccgctcag taatgtgctt aaatattgcc aagagagaat cattgaacag cgtgaaactg       300
+     aaaagaagcg aggagagcgg gccaagacac ggagtgccgt cctggcttcc cggagccacc       360
+     ctccatgctc tgctgcccca ggcgtgtgga gcggcactcg tgcgtgttat taaccttcag       420
+     acatgatcaa ttacgaagat ttcttttacc cctctccagg gagagggctc agagaaaggg       480
+     aaatagaccc cttgcctctt gtggtgccag gtagctgtgt tcgaacgagg tagtgtggag       540
+     atggactgga agaagaaacg ggagtgcaga aactccaggg tctgtctggg tggtcccctc       600
+     atctccgctt tgcctgtaca gccatactgg ctcagtagag cgctccctag gacaccaccc       660
+     agagaaaacc ttctggaatc gccaatccag gacaaccaca ggagattgat caaggcaaag       720
+     caaatattgt agtcttctcc aagatacggg atggagggct aagaagaggg gaaggaagaa       780
+     tcacccagtg agacaaaatt cttcgtagga attatatttt cccttgccct cacccaacat       840
+     cgcctatctc aaaaataatt taaaaacaaa aaacaaacaa acaaacaaaa aacagagcgt       900
+     gctgagtgca ttctggatta ctcataggac tttgtcacac acaccctcct ttctggtcgc       960
+     aaacccgtga gctggattta taatcgccct acaaagctcc agaggcagtc agacacctgc      1020
+     aaaggagccc caggctccgc ggacgagctg cccccgcgag caacggcctc gtgattcccc      1080
+     gcccgacggg gtccccgcct ccccactccg cccccgcctc ccccaagccc agcggccgcc      1140
+     tctccggatc tctcccttct tcaggctctc cgtgccggac cagggatcgt gcaagcaagg      1200
+     aagcagccct ggggtgacac ccagcacgta ctcctgtgac agagccgagc ccagcccagc      1260
+     cccgggacgc ttcgcagagg agtcgcggga gggtccagct cgctgtcgct gaaccgaggt      1320
+     gggtaaatac cggatcaccc ggacttgcca ga                                    1352
+//
+ID   AF223952   standard; DNA; ROD; 7502 BP.
+XX
+AC   AF223952;
+XX
+SV   AF223952.1
+XX
+DT   25-JUL-2000 (Rel. 64, Created)
+DT   25-JUL-2000 (Rel. 64, Last updated, Version 1)
+XX
+DE   Mus musculus PER1 (Per1) gene, partial cds, alternatively spliced.
+XX
+KW   .
+XX
+OS   Mus musculus (house mouse)
+OC   Eukaryota; Metazoa; Chordata; Craniata; Vertebrata; Euteleostomi; Mammalia;
+OC   Eutheria; Rodentia; Sciurognathi; Muridae; Murinae; Mus.
+XX
+RN   [1]
+RP   1-7502
+RA   Yamaguchi S., Mitsui S., Miyake S., Yan L., Onishi H., Yagita K.,
+RA   Suzuki M., Shibata S., Kobayashi M., Okamura H.;
+RT   "The 5' upstream region of mPer1 gene contains two promoters and is
+RT   responsible for circadian oscillation";
+RL   Curr. Biol. 10(14):873-876(2000).
+XX
+RN   [2]
+RP   1-7502
+RA   Yamaguchi S., Mitsui S., Okamura H.;
+RT   ;
+RL   Submitted (12-JAN-2000) to the EMBL/GenBank/DDBJ databases.
+RL   Anatomy and Brain Science, Kobe University School of Medicine,
+RL   Kusunoki-cho, Chuo-ku, Kobe, Hyogo 650-0017, Japan
+XX
+DR   SPTREMBL; Q9JII8; Q9JII8.
+XX
+FH   Key             Location/Qualifiers
+FH
+FT   source          1..7502
+FT                   /db_xref="taxon:10090"
+FT                   /organism="Mus musculus"
+FT                   /strain="129/Sv"
+FT                   /map="11B"
+FT   mRNA            join(1831..1900,7095..>7502)
+FT                   /note="alternatively spliced"
+FT                   /gene="Per1"
+FT                   /product="PER1A"
+FT   exon            1831..1900
+FT                   /number=1A
+FT                   /gene="Per1"
+FT   exon            5550..5594
+FT                   /number=1B
+FT                   /gene="Per1"
+FT   mRNA            join(5550..5594,7095..>7502)
+FT                   /note="alternatively spliced"
+FT                   /gene="Per1"
+FT                   /product="PER1B"
+FT   exon            7095..7502
+FT                   /number=2
+FT                   /gene="Per1"
+FT   CDS             7228..>7502
+FT                   /codon_start=1
+FT                   /db_xref="SPTREMBL:Q9JII8"
+FT                   /gene="Per1"
+FT                   /product="PER1"
+FT                   /protein_id="AAF87329.1"
+FT                   /translation="MSGPLEGADGGGDPRPGEPFCPGGVPSPGAPQHRPCPGPSLADDT
+FT                   DANSNGSSGNESNGPESRGASQRSSHSSSSGNGKDSALLETTESSK"
+XX
+SQ   Sequence 7502 BP; 1700 A; 1895 C; 2023 G; 1884 T; 0 other;
+     gctagccaag aaataagggc tattagagag ctgggggcga gggtggggat ggtgcatact        60
+     tttaagccta gtatttgggt ggtagtggca tatggatctc tgtgaggtta aggtcagcct       120
+     ggtatacaaa gagtccagaa cagccaggac tatgttacac aaaggaatcc tgtcttgaga       180
+     aaaaaaaaat tagagctact tttttttttt ttggtttctc tgtgcagtcc tggctgtctt       240
+     ggaactcact ctgtagacca gagctggcct cgaactcaga aatctgcctg cctctgcctt       300
+     ccaagtgctg ggattaaagt cgtgcgccac catgcccagc ttagaagtac ttttaaaaat       360
+     agattttcag gggctggaga gatggctcag cagttaagag cactgactgc tcttccaaag       420
+     gtgctgaatt caattcccag caatcacatg gtgactcaca accatctaga aatggatccg       480
+     atgccctctt ctggtgtgtc tgaagacagc tacaatgtac tcatacaaat cttaaaaaca       540
+     aacaaacaaa aattagattt tcaaagttgg gcagagccag gtggattggc aatctccggg       600
+     tttgggggca gccaggtcta cagagtgagt tctagaacag ccagagcaac acagagaaac       660
+     cctgtctggg ccgggcagtg ggggcacacg cctttaatcc cagcagaggc aggtggattt       720
+     ctgagttcga ggccagccta gtctacagag tgagttccag gacagccagg gctacacaga       780
+     gaagccctgt ctcgaagaaa aaagaaaaaa agaagaaaga aacctgtctg gaatacaccc       840
+     cccgccccgc aaaagggtgt cattggaaat tatttcagag gttctaaagt actgaggtgt       900
+     cttacagcct atcctaaatt ctacctttat ggagagttta aataaggctt tttgcattta       960
+     attcttggaa ttacttctag gtttaatgtc tccataggcc ttacaatacc aagctacctt      1020
+     tatggtgtca gagacctggg ttcagacttt agctctttta tcaatataca taatctaatt      1080
+     ccgacagatt acgtaacctc tcagcctctt ttgtgaggtt atgggtagtg agccggcctt      1140
+     cttgggagtc tgcaagaagg ggctggccag ccaggcccaa agaaaataaa taggaggcga      1200
+     ctgtcatttc accgtcattg tcatgcaatc taatgatatc ttcagtgtag tgctcagatt      1260
+     tttaagcttt ggggatcact agagacacaa agctcaggca ccagaaacct cttgtaatgc      1320
+     cagagtctcc aaagtatgcc cactacgcca tagcctgtca gatctacgcc tgcgtacaag      1380
+     tcgctcggca cgcctgcgca gacttcgcag tattgggtaa gtgtcgtcaa ggaaaatccc      1440
+     cagcttctgg gtaaacaagt tgccgcgtga gccagcctgc acgtgttccc tacagctctg      1500
+     agccctctca gcctatgaga aagtttttag ggcagggctg gcatttgcgt cactgattta      1560
+     ggcagggcgg ggttgtctct gcagccagta aaaatgttga gagtgggtgg gggtgtggct      1620
+     tccggtcaga tgtccaatca acgagttggg gcgcccccgc cctcacgtgg ctctatcact      1680
+     accggttgtc atattgtcca atgggaaagt gactaagttc tgaaatgcca atggttgctt      1740
+     tacaagggct tgccggctgc acgcggagcg gggcatgggt tggcgtctct gagccaataa      1800
+     gctagggagg cgtgacagaa cgggcggtgg gagggcctcg aggattctgt ggaggagccc      1860
+     caggagtgaa gaaatttgga gtctacgtgc gctcggaact gtgagtaacc ccttactctg      1920
+     gagccgtcga acttgtgttt ttggggaggt gcgctcgacc aaaaggggtg tcagtggcgt      1980
+     ggtgtgtgtg agggatcatg caaatgtgaa ttagctgcag aacaaatgcc taatggttgt      2040
+     ggagaaagag accaaaagtt cagctctagg ggaacatgaa tgagagttac cagcaacaga      2100
+     tctctcacca ctctagggtc cctggacact aatgcctagc gcagggtgct cagaagcccc      2160
+     tagccatccg agggagccga agcgcctgcg atatgacccc tgagagctgg ttatggtttg      2220
+     gggtaggctc cctaaacact tggaagagac cgccctggta gggcgggcgg gaacgtagta      2280
+     tggtgatctg agaaaggctg gtgtgttgat ttgaccgaaa ggctgtctca tcacgactat      2340
+     aggtggtatc gtggcctcag ggacatgctc gaaaatagga atgggctagt aatttgttgg      2400
+     attctgaaag ggaggatagg gtggagggtt tctgtacacc gtttcgtcta ctcttcttaa      2460
+     gctgctagag gtggagttac caaaggactg ctctggtgtc tagacggtcg gtcgggcaga      2520
+     ggtgagggag gagagggagg aagtgagatt cttaggaaag cagtgtgcct gcaggcttct      2580
+     cgagtgatct cgggttttga gcatagaaac gaaccatgat ggtgcgcacg gagcacaaac      2640
+     aatgccttga gatcaggcta aggggagaga aggaaaagga attggatata gcctgtattc      2700
+     taggcaccaa gcttagaaac aggggaatac tccccccgca gtcctacggt gctggaatgc      2760
+     agtgtagagg tttggtaaca ctttacaggg tccctaagcc agcaggacaa gccatcatta      2820
+     gggcttgaac cttgggctcc attattagga agctgagaat gaagcagaca attaaggcaa      2880
+     gtttagtaac tacctactaa gtcttagttt ttccttatga catcagggtg atacttacct      2940
+     tcagttgttt gggggcttac atgagaacaa tatgtgtaaa gttcttagca cagcgcttgg      3000
+     atcatttaca aacacaaact ataaggtaac aaaagaatag cgatagagtt ggggatttat      3060
+     gtgcatgctg tggccagaga gcaatctcca tcttctgttt ttctgcaagt tttgatgact      3120
+     cctcttttcc ctctccctga tttttttttt tttttttttt ttggtcttcg ggcaccagcc      3180
+     caaattccat cattcctccc tgtattcctc tcccaagatc tgggccccag actgaggcaa      3240
+     tttgctgtgt cccagtttga cttcatctta aatccattct ctctgaccac cccccccccc      3300
+     acctattctg tgctgtaata gtaactagaa agtctgcctc taaagagggg ccccagggaa      3360
+     ggagcaaagg tgcgttctct ctcagaacct aggcctccaa tttacccgcc ctagctcttt      3420
+     ggtacctggc cagcaaccgt gtacagtctg gtgacgggga aaagccaatg ccaggagttt      3480
+     taagacccag ctgagggagg gtaaaagtag gtcccgcaaa gagaaccagg catgggggcg      3540
+     ggggaggggg acccccttcc tcctaactgt ctctccagga atttttggct tttgtacagg      3600
+     accgctgtcg ttgggttggg ggaggcgcca aggctgtgtg catgtcctgg gccatcagcc      3660
+     aagagaacac gatgttccct agtgcgctgg ccgccgccct ctggggctgg ccgcctccca      3720
+     aaccgctgcc tctccagcct ccctgcccca cattccccag ctgcctcgcc ccgcctcctg      3780
+     cctccgcttt gacgtcacct ccctctcctg cccccgcttc tccattgacg gcagcagagc      3840
+     ctggttactg tgggggactg atgaggcccg acagcctggg ccttgggatc aggttggggc      3900
+     tgtttggagt gctgaaacct tttgtctgtg taaatgacag atagggaagt gggcgagcaa      3960
+     tggctgcttg ggtcagagga atcacaccta aatccttgag agctgtggaa agagaaaggg      4020
+     gtctggaaaa aaaaaaagga cagcacacgg tcacaacgca gtacgagggg gcaggagagc      4080
+     agcatcattt tcaggaggag gaagctgagc actcagcctc ccgtgtcttt tgttttctgt      4140
+     gtttccctgc ttctgttttt ctgggttatt ttataacagg tctgtgtccc agcatttcta      4200
+     tagaaccttg tctcgccgcc tcctctaagg gaaacaccat tgttaaggaa agctttagcc      4260
+     acgtgacagt gaggggcgtg cacttaacag ctgattatgt cagccgctgc gtgttggcct      4320
+     cttcacttgc cacctacgtt tgcagggaag cctgagaact actcagccca ggcctaggga      4380
+     aggggactct gtcactgtag ctctcctgga cccagactgg catgttgtcc ccccctcccc      4440
+     aaaatcgagt ctctattctc tttttatgaa tcaatgctct acttttcttt tgaaaacata      4500
+     atttgttgcc tcctctcctg aggctctctc tcccctacct atccttaata gaaacagagc      4560
+     catcctgttt accgagcatc tactgtcagt cctgacgctg agacgtactt accttactgc      4620
+     tgagaataca gtaaatgaga cagatgggct tgctgctggg ttcatgaacc ttggcttttg      4680
+     tattctaagc agcaggaata aaaagcccaa taaaaagccc ttgccaccca gccacccatc      4740
+     ctttttctgc ctactgctgc aactgccctc tctgctgccc cttttgtagt actggcttcc      4800
+     tggtccccac ttttggggca gccctaaatg tgggtggctg catcctctgc agaggcagca      4860
+     ctagtcacca agtaggcttc ctggagacct tttctctgat tggctagtga agcacctgct      4920
+     tttgtttcct ttcacagtag ccattggctt tccctgtcct ttccgtttgt ccgtatcctt      4980
+     ccatcaccca ctcacccctt aacgacacgt gggccctcaa ttgcccttct ctcaggatct      5040
+     gaagggtcag aggaaagggt tggattcttt ataacaaggc tggggagagg ccagggaatg      5100
+     tcagtctagg tttttctctc tcccacttcc cttgggtagc agacatttca ttcacccggc      5160
+     accaggacag gtgtcttgtt ctgccaagct ggtcagttta ggaagtaggt ttctcttgag      5220
+     cacttcctgt ggcccaggta tcctccctga aaaggggtag tttccctccc tcacttccct      5280
+     ttcattattg acggtgtgag acatcctgat cgcattggct gactgagcgg tgtctgaggc      5340
+     ccttcagccc agcaccagca cccaagtcca cgtgcaggga tgtgtgtgac acagccctga      5400
+     cctcagtggg ggccagtagc caatcagatg ccaggaagag atccttagcc aaccgggggc      5460
+     ggggcctgcg gctcttcggg cagaaggcca atgaggggca gggcctggca ttatgcaacc      5520
+     cgcctcccag cctcgcggag cttctgggtt gcgggccgaa acggcaagcg gatggagggc      5580
+     gctcgaacgg ccaggtaggg atccctgctg caatcctagg gttagtcttt gtcccggagc      5640
+     ttggccgcca ctacttccaa cgtgatgggt cgctttcagc tctcagagag caaaacaata      5700
+     atctgccttt cctgtcacta tccacccttc cccgcccctg ggccctaggt gttcaactca      5760
+     acccgtcacg ggttgtctgc gtttgttatt cgttcaccta atctcctcct ctgctcctcc      5820
+     agagcagcca tcctgaacct aagagacctt tagcgaacac gaccccttta cacattgctc      5880
+     gacactcggg agtccatggg tttgccctag cccaaagacc cccttcaggc ttctgcgctc      5940
+     cctgtcttcc tccctccaat tcctggcctc gtgccggtcg tgatgtcaac cgcttcaggc      6000
+     tggaacatcc tgttctcagc gctagttctt gctgttggcc acagccttcc ttcccttttc      6060
+     tcctggcgct cagaaaatac ttgggatggg ggtgtggtta gacagggagt agaggaaaaa      6120
+     ctatatatgc tggttgttgt gtgtccccta tctatgtggt agtagggtta actagaaaag      6180
+     taagggacga aggaagatgc ctgagtcgtt gcctatggca agtggtaact ccagtcctgg      6240
+     tgtttgggag tgggcagggg cttgagaaag aaaagcagtg tcttgatcag aataatgttc      6300
+     gaggcaagag cgaggatggg ggcgtttcca caaagagcag aggccgagtg gggaagctag      6360
+     gacttgctcc tggagttcct ctagtttgtt actcttcaca tggctcctag gctctttggg      6420
+     ccctgggaat ttgttatggt gggtgttctt ctcctccccg ctgccctgaa ccttgttagc      6480
+     cagtatgagg gtgtgttggc cagtatagga ctgggtctgt ttcccacttc cacgaagatg      6540
+     gggattgggg gaggagtcgt tcctgccctc ctgtggtccc tccagcaacc gctgagctca      6600
+     gcggctgacg tcggtttccc tggcgaccgc ggctgtggcg gaagcgcgtg gtggggccag      6660
+     gcacatcggc gcgcatgtgc agcgggggtg gcaccgcccc cggataaaat tagcccggaa      6720
+     gcctaaatat aggaggcgat cagctcaccc cctgctccga ggcctcagag tcccagacca      6780
+     ggtggggacc tgatgagaat ttgggcatag gaaacctgca agctttgacc ctcagctact      6840
+     gttctagtcg attgttcagg ctgtactcat tccacactgg caaggggtgt aagagatggc      6900
+     ctacgagagc tgcctttcta cctgtggtat ccttaggtcc ccctaaggaa atagaacata      6960
+     tttctattgc aagccccagg cctgagtcac aacagtgagg ggcaggcaga ggaaggactg      7020
+     ggtgtagcca gcagatgctg tggggttaat agctcagctt ttgctaaaca ttcctttttg      7080
+     gtttcttttt ctaggtgtcg tgattaaatt agtcagccct cagagacagg cgtcctacct      7140
+     cctttatcca gacctcaaaa gccccgttgt gcacccgtgg tggcttcttc accttccctg      7200
+     tttcgtcctc cactgtatgg cccagacatg agtggtcccc tagaaggggc cgatggggga      7260
+     ggagacccca ggcccggaga acctttttgt cctggaggag tcccatcccc tggggccccg      7320
+     cagcaccggc cttgtccagg ccccagcctg gctgatgaca ctgatgcaaa cagcaatggc      7380
+     tcaagtggca atgagtccaa cggacccgag tccaggggcg catctcagcg gagttctcat      7440
+     agttcctctt ctggcaatgg caaggactca gctctgctgg agaccactga gagcagcaag      7500
+     ag                                                                     7502
+//
diff --git a/dazzle-webapp/test.style b/dazzle-webapp/test.style
new file mode 100644
index 0000000..33735fc
--- /dev/null
+++ b/dazzle-webapp/test.style
@@ -0,0 +1,17 @@
+<?xml version="1.0" standalone="yes"?>
+
+<DASSTYLE>
+  <STYLESHEET>
+    <CATEGORY id="default">
+      <TYPE id="default">
+        <GLYPH>
+	  <ARROW>
+	    <HEIGHT>10</HEIGHT>
+	    <COLOR>yellow</COLOR>
+	    <PARALLEL>yes</PARALLEL>
+	  </ARROW>
+	</GLYPH>
+      </TYPE>
+    </CATEGORY>
+  </STYLESHEET>
+</DASSTYLE>
diff --git a/dazzle-webapp/tss.style b/dazzle-webapp/tss.style
new file mode 100644
index 0000000..e684b7b
--- /dev/null
+++ b/dazzle-webapp/tss.style
@@ -0,0 +1,17 @@
+<?xml version="1.0" standalone="yes"?>
+
+<DASSTYLE>
+  <STYLESHEET>
+    <CATEGORY id="default">
+      <TYPE id="TSS">
+        <GLYPH>
+	  <TICK>
+	    <HEIGHT>25</HEIGHT>
+	    <COLOR>blue</COLOR>
+	    <OUTLINECOLOR>black</OUTLINECOLOR>
+	  </TICK>
+	</GLYPH>
+      </TYPE>
+    </CATEGORY>
+  </STYLESHEET>
+</DASSTYLE>
diff --git a/dazzle-webapp/welcome.html b/dazzle-webapp/welcome.html
new file mode 100644
index 0000000..9f21f24
--- /dev/null
+++ b/dazzle-webapp/welcome.html
@@ -0,0 +1,6 @@
+<p>
+Dazzle was developed at the <a href="http://www.sanger.ac.uk/">Sanger
+Institute</a> by <a href="mailto:td2 at sanger.ac.uk">Thomas Down</a>.  For
+more information, visit the <a href="http://www.derkholm.net/thomas/dazzle/">Dazzle
+home page</a> or contact the author.
+</p>
diff --git a/debian/README.Debian b/debian/README.Debian
deleted file mode 100644
index 844ccb2..0000000
--- a/debian/README.Debian
+++ /dev/null
@@ -1,23 +0,0 @@
-dazzle for Debian
------------------
-
-This is only a very preliminary release.
-
-To get the upstream example into Tomcat4, please do
-
-	cd /usr/share/doc/dazzle/dazzle-webapp
-	sudo /etc/init.d/tomcat4 stop
-	sudo jar cf /var/lib/tomcat4/webapps/das.war .
-	sudo /etc/init.d/tomcat4 start
-
-The server's welcome page should then be visible at 
-http://localhost:8180/das/
-not at 8080 as hinted in the upstream docs.
-
-Any hints on how to improve packaging are welcome.
-
-Cheers,
-
-Steffen
-
- -- Steffen Moeller <moeller at pzr.uni-rostock.de>, Mon, 24 Jan 2005 00:48:09 +0100
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index c09aac0..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,12 +0,0 @@
-dazzle (1.01r3643-1) UNRELEASED; urgency=low
-
-  [ Steffen Moeller ]
-  * Initial Release
-
-  [ Thorsten Alteholz ]
-  * debian/rules: target get-orig-source added
-
-  [ David Paleino ]
-  * debian/watch fixed.
-
- -- Steffen Moeller <moeller at pzr.uni-rostock.de>  Tue, 05 Dec 2017 14:24:28 +0100
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index f599e28..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-10
diff --git a/debian/control b/debian/control
deleted file mode 100644
index be8642d..0000000
--- a/debian/control
+++ /dev/null
@@ -1,27 +0,0 @@
-Source: dazzle
-Maintainer: Debian Med Packaging Team <debian-med-packaging at lists.alioth.debian.org>
-Uploaders: Steffen Moeller <moeller at pzr.uni-rostock.de>
-Section: science
-Priority: optional
-Build-Depends: debhelper (>= 10),
-               ant,
-               libbiojava-java
-Standards-Version: 3.9.8
-Vcs-Browser: http://anonscm.debian.org/viewvc/debian-med/trunk/packages/dazzle/trunk/
-Vcs-Svn: svn://anonscm.debian.org/debian-med/trunk/packages/dazzle/trunk/
-Homepage: http://biojava.org/wiki/Dazzle/
-
-Package: dazzle
-Architecture: all
-Depends: ${shlibs:Depends},
-         ${misc:Depends},
-         libbiojava-java
-Description: Java-based DAS server
- Dazzle is a general purpose server for the Distributed Annotation System
- (DAS) protocol. It is implemented as a Java servlet, using the BioJava
- APIs. Dazzle is a modular system which uses small "datasource" plugins to
- provide access to a range of databases. Several general-purpose plugins
- are included in the package, and it it straightforward to develop new
- plugins to connect to your own databases.
- .
- Information on DAS is available from http://www.biodas.org/
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index 5b97628..0000000
--- a/debian/copyright
+++ /dev/null
@@ -1,29 +0,0 @@
-Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Source: http://www.derkholm.net/thomas/dazzle/download101.html
-
-Files: *
-Copyright: Thomas Down <td2 at sanger.ac.uk>
-License: LGP-2+
-
-Files: debian/*
-Copyright: Steffen Moeller <moeller at pzr.uni-rostock.de>
-License: LGP-2+
-
-License: LGP-2+
-    This package is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
- .
-    This package is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
- .
-    You should have received a copy of the GNU Lesser General Public
-    License along with this package; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
- .
- On Debian systems, the complete text of the GNU Lesser General
- Public License can be found in `/usr/share/common-licenses/LGPL'.
-
diff --git a/debian/dirs b/debian/dirs
deleted file mode 100644
index 15b505a..0000000
--- a/debian/dirs
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/share/java
-usr/share/doc/dazzle
diff --git a/debian/docs b/debian/docs
deleted file mode 100644
index a188e06..0000000
--- a/debian/docs
+++ /dev/null
@@ -1 +0,0 @@
-docs/*
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index b862d6e..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/make -f
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-
-build: build-stamp
-build-stamp: 
-	dh_testdir
-
-	ant package-main javadocs-main
-
-	touch build-stamp
-
-clean:
-	dh_testdir
-	dh_testroot
-	rm -f build-stamp
-
-	# Add here commands to clean up after the build process.
-	ant clean
-
-	dh_clean
-
-DESTDIR=$(CURDIR)/debian/dazzle
-
-install: build
-	dh_testdir
-	dh_testroot
-	dh_clean -k 
-	dh_installdirs
-
-	cp ant-build/dazzle.jar $(DESTDIR)/usr/share/java/
-	cp -r ant-build/docs/dazzle $(DESTDIR)/usr/share/doc/dazzle/api
-	cp -r dazzle-webapp $(DESTDIR)/usr/share/doc/dazzle/dazzle-webapp
-	(cd $(DESTDIR)/usr/share/doc/dazzle/dazzle-webapp/WEB-INF/lib \
-	  && ln -s ../../../../../java/{biojava,bytecode,dazzle}.jar . )
-
-
-binary-arch: build install
-# Build architecture-dependent files here.
-# We have nothing to do by default.
-#
-binary-indep: build install
-# Build architecture-independent files here.
-	dh_testdir
-	dh_testroot
-	dh_installchangelogs 
-	dh_installdocs
-	dh_installexamples
-	dh_installman
-	dh_link
-	dh_strip
-	dh_compress
-	dh_fixperms
-	dh_shlibdeps
-	dh_gencontrol
-	dh_md5sums
-	dh_builddeb
-
-binary: binary-indep
-.PHONY: build clean binary-indep binary-arch binary install
-
-get-orig-source:
-	mkdir -p ../tarballs
-	uscan --verbose --force-download --destdir=../tarballs
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index 9ff8ea1..0000000
--- a/debian/watch
+++ /dev/null
@@ -1,3 +0,0 @@
-version=4
-
-http://www.derkholm.net/thomas/dazzle/download101.html .*/download/dazzle/dazzle at ANY_VERSION@@ARCHIVE_EXT@
diff --git a/docs/background.png b/docs/background.png
new file mode 100644
index 0000000..8c8d498
Binary files /dev/null and b/docs/background.png differ
diff --git a/docs/deploy.html b/docs/deploy.html
new file mode 100644
index 0000000..778cf5e
--- /dev/null
+++ b/docs/deploy.html
@@ -0,0 +1,312 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><link xmlns:html="http://www.w3.org/1999/xhtml" href="docs.css" type="text/css" rel="stylesheet">
+  <title>Dazzle: Deployment guide</title>
+</head>
+
+<body>
+<h1>Deploying the Dazzle servlet</h1>
+
+<p>
+This document describes the steps required to install and start
+the Dazzle server.  Some knowledge of the DAS system is assumed:
+read the <a href="http://www.biodas.org/documents/spec.html">specification</a>
+for more information.
+</p>
+
+<p>
+These instructions apply to release 1.00 of Dazzle.
+</p>
+
+<h2>Prerequisites</h2>
+
+<p>
+Dazzle requires a runtime environment for the Java 2 platform,
+standard edition (J2SE) version 1.4 or later.
+It also requires a servlet container complying with the servlets
+2.3 specification (a servlet container is a Java-aware web
+server).  Dazzle was developed using the
+<a href="http://jakarta.apache.org/">Tomcat 4.0</a> servlet container,
+and this is recommended.  It has also been tested successfully using
+<a href="http://www.caucho.com/">Resin</a>.
+</p>
+
+<h2>The webapp structure</h2>
+
+<p>
+Servlet containers work with bundles of code and data known
+as <em>webapps</em>.  To deploy Dazzle, you must create a webapp
+with a well-defined structure.  The required files and directories
+are shown below:
+</p>
+
+<pre>
+WEB-INF/
+    web.xml                       Deployment descriptor, used by the servlet container.
+    lib/
+        biojava.jar               BioJava library
+        bytecode.jar              (Required for BioJava)
+        dazzle.jar                DazzleServer code
+    classes/
+dazzlecfg.xml                     Data-sources configuration file
+stylesheet.xml                    Default DAS stylesheet
+welcome.html                      Welcome message, included front page
+</pre>
+
+<p>
+You can add your own data files to this structure, either at the
+top level or in your own directories.  If you are using a datasource
+plugin which isn't included in the core Dazzle package, you can
+either package it as a JAR file (if it isn't already) and place it
+in the <code>WEB-INF/lib</code> directory, or place raw .class files
+in the <code>WEB-INF/classes</code> directory.
+</p>
+
+<p>
+You can download a complete `skeleton' webapp with all these files in
+place from the Dazzle homepage.  In this case, you just need to unpack
+the skeleton, configure your datasources, then follow the deployment
+instructions below.  Alternatively, you can download the source and
+compile your own.  If so, you will need the following:
+</p>
+
+<dl>
+<dt>BioJava (current version)</dt>
+<dd>Available from <a href="http://www.biojava.org/">BioJava.org</a>.  Until
+the BioJava 1.4 release is ready, it is recommended that you use a
+<a href="http://www.derkholm.net/autobuild/">nightly build</a>.
+</dd>
+
+<dt>BioJava bytecode library</dt>
+<dd>Binaries can be downloaded from <a href="http://www.biojava.org/">BioJava.org</a>.
+Also in BioJava CVS.</dd>
+
+<dt>servlet.jar</dt>
+<dd>The Java Servlet 2.3 API files.  This should be included with your Servlet
+container distribution.  These are only needed for compiling Dazzle: when you
+deploy the servlet, it should automatically pick up servlet API classes from
+the servlet container.
+</dd>
+</dl>
+
+<p>
+The current Dazzle sourcecode is available from the
+<a href="http://www.derkholm.net/svn/repos/dazzle/">BioJava Subversion repository</a>. 
+Follow the
+instructions there to connect to the server and check out the <code>dazzle</code>
+module.  You will need to copy all the libraries above into the dazzle directory,
+then use the supplied ANT build-script to compile the code.
+</p>
+
+<h2>Configuring datasources</h2>
+
+<p>
+Dazzle relies on small datasource plugins to supply sequence and feature
+data, and also to customize the DAS messages.  Each Dazzle installation includes
+one or more data sources.  These are defined in an XML configuration file,
+dazzlecfg.xml.  A typical example is shown below:
+</p>
+
+<pre>
+<?xml version="1.0" ?>
+
+<!-- Sample Dazzle configuration file -->
+
+<dazzle xmlns="http://www.biojava.org/2000/dazzle">
+  <datasource id="test" jclass="org.biojava.servlets.dazzle.datasource.EmblDataSource">
+    <string name="name" value="Test seqs" />
+    <string name="description" value="Evalutation sequences for promoter-finding software" />
+    <string name="version" value="1.0" />
+    <string name="fileName" value="test.embl" />
+
+    <string name="stylesheet" value="test.style" />
+  </datasource>
+
+  <datasource id="tss" jclass="org.biojava.servlets.dazzle.datasource.GFFAnnotationSource">
+    <string name="name" value="TSS" />
+    <string name="description" value="Transcription start sites for fickett set" />
+    <string name="version" value="1.0" />
+    <string name="fileName" value="fickett-tss.gff" />
+    <boolean name="dotVersions" value="true" />
+    <string name="mapMaster" value="http://my-server:8080/das/test/" />
+
+    <string name="stylesheet" value="tss.style" />
+  </datasource>
+</dazzle>
+
+</pre>
+
+<p>
+Each <code>datasource</code> element has two required attributes: a unique
+ID, and the fully-qualified Java class-name of the plugin.  The <code>datasource</code>
+element can contain any number of property elements, which set some property of
+the plugin.  Property elements are always named after the data-type of the property
+to be set, and have two attributes: name and value.  The set of properties recognized
+by a given plugin should be listed in the plugin documentation. (NOTE: The format
+of the property elements may change in a future release to match the SOAP encoding
+rules).
+</p>
+
+<p>
+Some properties are commonly recognized by many plugins:
+</p>
+
+<ul>
+<li>name</li>
+<li>description</li>
+<li>version - the version of the database being served</li>
+<li>stylesheet - a path to a DAS stylesheet, relative to the top level of the webapp</li>
+<li>mapMaster</li>
+</ul>
+
+<p>
+The <code>mapMaster</code> attribute is recognized by all annotation
+server plugins.  It should be set to a URL pointing to the reference server
+whose sequences are annotated by this data source.  Note that this must
+always be an absolute URL, even if the reference datasource is contained
+within the same Dazzle webapp.
+</p>
+
+<h2>The EMBL-file plugin</h2>
+
+<p>
+The EMBL-file plugin provides a DAS reference datasource
+backed by a standard EMBL-format flatfile.  It is included
+in the basic Dazzle package, with classname
+<code>org.biojava.servlets.dazzle.datasource.EmblDataSource</code>.
+</p>
+
+<p>
+Properties of the EMBL plugin:
+</p>
+
+<table border="1">
+<tr>
+  <th>Name</th>
+  <th>Datatype</th>
+  <th>Description</th>
+</tr>
+<tr>
+  <td>name</td>
+  <td>string</td>
+  <td>The display name of the datasource</td>
+</tr>
+<tr>
+  <td>description</td>
+  <td>string</td>
+  <td>A textual description of the datasource</td>
+</tr>
+<tr>
+  <td>version</td>
+  <td>string</td>
+  <td>The version of the database being served (note that individual sequences are served with version numbers taken from the EMBL file</td>
+</tr>
+<tr>
+  <td>stylesheet</td>
+  <td>string</td>
+  <td>Filename of a DAS stylesheet to associate with this datasource</td>
+</tr>
+<tr>
+  <td>fileName</td>
+  <td>string</td>
+  <td>Name of an EMBL file which is read at startup.</td>
+</tr>
+</table>
+
+<h2>The GFF plugin</h2>
+
+<p>
+The GFF plugin is a very lightweight annotation datasource, backed
+by a GFF version 2 file.  It is very easy to set up, but has some
+limitations (no complex features, no links out to external data).
+A more sophisticated `general purpose' annotation datasource should
+be released soon.
+</p>
+
+<p>
+The GFF plugin has class name
+<code>org.biojava.servlets.dazzle.datasource.GFFAnnotationSource</code>.
+The following properties are available:
+</p>
+
+<table border="1">
+<tr>
+  <th>Name</th>
+  <th>Datatype</th>
+  <th>Description</th>
+</tr>
+<tr>
+  <td>name</td>
+  <td>string</td>
+  <td>The display name of the datasource</td>
+</tr>
+<tr>
+  <td>description</td>
+  <td>string</td>
+  <td>A textual description of the datasource</td>
+</tr>
+<tr>
+  <td>version</td>
+  <td>string</td>
+  <td>The version of the database being served.  Individual sequences are served with version numbers copies from the reference server.</td>
+</tr>
+<tr>
+  <td>stylesheet</td>
+  <td>string</td>
+  <td>Filename of a DAS stylesheet to associate with this datasource</td>
+</tr>
+<tr>
+  <td>mapMaster</td>
+  <td>string</td>
+  <td>URL of a DAS reference server.</td>
+</tr>
+<tr>
+  <td>fileName</td>
+  <td>string</td>
+  <td>Name of a GFF file which is read at startup.</td>
+</tr>
+<tr>
+  <td>dotVersions</td>
+  <td>boolean</td>
+  <td>Interpret sequence names contains a '.' character as <em>id</em>.<em>version</em>.</td>
+</tr>
+</table>
+
+<h2>Packaging and deployment</h2>
+
+<p>
+Once you are happy with your configuration file, and you've added any extra
+resource files that are needed, you should package the webapp as a WAR file.
+WAR files are just normal Java ARchives (JAR files) which contain a WEB-INF
+directory and a web.xml file (as show in the directory tree, above).  To
+create this file, change into the directory where you have been building your
+webapp, and type:
+</p>
+
+<blockquote>
+jar cf ../das.war *
+</blockquote>
+
+<p>
+By convention, webapps containing DAS servers are called das.war, but this
+isn't strictly necessary.
+</p>
+
+<p>
+Details of deploying webapps vary between containers.  If you are using
+Tomcat, simply copy the <code>das.war</code> file into the ${TOMCAT_HOME}/webapps/
+directory, then re-start the server.  Note that Tomcat creates temporary directories
+for each deployed webapp (e.g. a <code>das/</code> directory corresponding to das.war).
+If you are replacing an existing webapp with a newer version, you should shut down
+the server then delete the temporary directory before deploying the new webapp.
+</p>
+
+<p>
+When the webapp is deployed, you can test it with your favourite DAS browser.
+You can also try visiting the root page (for instance, http://my-server:8080/das/) using
+a web browser -- you should see a welcome page listing the available data sources.  Note
+that the welcome page can be customized by editing the <code>welcome.html</code>
+file in your webapp.
+</p>
+
+</body>
+</html>
diff --git a/docs/docs.css b/docs/docs.css
new file mode 100644
index 0000000..f1f5311
--- /dev/null
+++ b/docs/docs.css
@@ -0,0 +1,25 @@
+body { background-image: url(background.png) }
+
+pre { background-color: darkslategray;
+       color: wheat;
+       border-width: 3;
+       padding: 5;
+       margin-left: 7%;
+       margin-right: 7%;
+       border-color: red;
+       border-style: solid;
+       font-family: monospace;
+       white-space: pre}
+
+img { margin-left: auto;
+      margin-right: auto;
+      float: none;
+      clear: both}
+
+p.figure { margin-left: auto;
+           margin-right: auto;
+           text-align: center;
+           font-family: sans-serif}
+
+div.caption {text-align: center;
+           font-family: sans-serif}
diff --git a/manifest/dazzle.txt b/manifest/dazzle.txt
new file mode 100644
index 0000000..fc7d0e6
--- /dev/null
+++ b/manifest/dazzle.txt
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Class-Path: biojava.jar bytecode.jar servlet.jar
+
+
diff --git a/resources/META-INF/services/org.biojava.servlets.dazzle.DazzleHandler b/resources/META-INF/services/org.biojava.servlets.dazzle.DazzleHandler
new file mode 100644
index 0000000..cc23b18
--- /dev/null
+++ b/resources/META-INF/services/org.biojava.servlets.dazzle.DazzleHandler
@@ -0,0 +1,10 @@
+org.biojava.servlets.dazzle.EntryPointsHandler
+org.biojava.servlets.dazzle.SequenceHandler
+org.biojava.servlets.dazzle.StylesheetHandler
+org.biojava.servlets.dazzle.LinkHandler
+org.biojava.servlets.dazzle.AlignmentHandler
+org.biojava.servlets.dazzle.StructureHandler
+org.biojava.servlets.dazzle.FeaturesHandler
+org.biojava.servlets.dazzle.GFFFeaturesHandler
+org.biojava.servlets.dazzle.HydraGFFFeaturesHandler
+org.biojava.servlets.dazzle.InteractionHandler
\ No newline at end of file
diff --git a/resources/css/content.css b/resources/css/content.css
new file mode 100644
index 0000000..1dd12d5
--- /dev/null
+++ b/resources/css/content.css
@@ -0,0 +1,475 @@
+.more { text-align: right }
+
+/* ADDITIONAL STYLES FOR ENSEMBL PAGE CONTENT */
+.hi { border: solid 1px red; padding: 0 1px; font-weight: bold }
+.redbox { visibility:hidden; position:absolute; height: 0px; width: 0px;background-color: red; z-index: 100 }
+  div.zmenu { visibility:hidden; position:absolute; top: 800px; left: 800px; width: 200px; z-index: 200 }
+  div.zmenu { border:1px #cccccc solid;}
+  div.zmenu table th { font-size: 0.9em; background-color:#ccc; color:#000; text-align: left; border:1px #cccccc solid; }
+  div.zmenu table td { font-size: 0.9em; color:#666; border-top : 1px #cccccc dotted;}
+  div.zmenu a { text-decoration:none; }
+
+/* Popup Help */
+.pointer { cursor:pointer; }
+.round-button { vertical-align:middle; margin:0px 2px; }
+div.help-popup { visibility:hidden; position:absolute; top: 800px; left: 800px; width: 400px; z-index:200 }
+div.help-popup { border:1px #36b solid;}
+div.help-popup table th { font-size: 0.9em; background-color:#9bb9dd; color:#000; text-align: left; border:1px #9bb9dd solid; }
+div.help-popup table td { font-size: 0.9em; color:#666; border-top : 1px #9bb9dd dotted; padding:0.5em; }
+div.help-popup a { text-decoration:none; }
+a.glossary {text-decoration:none; border-bottom:1px dotted #3366bb; }
+
+/* LAYOUT */
+
+div#settings {
+  background: #efefef;
+  border-bottom: #666 1px solid;
+}
+
+div#settings_content {
+  padding: 7px;
+}
+
+.ch span { /*border: red 1px solid;*/ padding: 2px 2em 2px 2px; }
+li.ch { padding: 6px }
+
+/* Layout columns */
+div.img-plus-table {
+    width:90%;
+    clear:both;
+    border:none;
+    margin:auto; 
+}
+
+div.col-wrapper {
+    width:100%;
+    clear:both;
+    border:none; 
+}
+
+.col-wrapper:after    { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+/* \*/
+* html .col-wrapper { height: 1%; }
+.col-wrapper { display: block; }
+/* */
+
+div.col { float:left; margin:0 1%; }
+
+div.col1 { float:left; width:96%; margin:0 1%; }
+
+div.col2 { float:left; width:47%; margin:0 1%; }
+
+div.col3 { float:left; width:30%; margin:0 1%; }
+
+div.narrow3 { float:left; width:27%; margin: 0 2.5% }
+
+/* HEADINGS */
+h2 { margin-bottom:0.5em; }
+
+.boxed, div.panel h3 { color:#993333; background-color:#fff9af; border:1px solid #ffdf33; margin-top: 0.7em; margin-bottom:1em; padding:2px 4px 2px 4px; }
+
+div.boxed { padding:10px; color:#333333; } 
+div.boxed h3 { margin-top:-0.2em; }
+
+div.panel h3.plain { border:none; background-color:transparent; }
+
+div.alt { color:#3366bb; background-color:#edeeef; border:1px solid #9bb9dd; }
+hr.alt { background-color:#3366bb; }
+div.alt h2, div.alt h3 { color:#3366bb; margin-top:1em; }
+div.alt h2.first, div.alt h3.first { margin-top:0em; }
+div.alt p { color:#000; margin-top:-0.5em; }
+div.alt a { text-decoration:none; }
+div.alt a:visited { color:#3366bb; }
+div.alt a:hover { color:#cc0000; }
+
+div.pale {  background-color:#ffffcc; border:1px solid #ffdf33; }
+div.pale a { text-decoration:none; }
+
+div.white {  background-color:#fff; border:1px solid #ffdf33; }
+div.white a { text-decoration:none; }
+
+div.pre { color:#339966; background-color:#eefff8; border:1px solid #aaeecc; }
+div.user_info { color:#111; background-color:#e7feff; border:1px solid #469fdd; }
+
+div.favourites-species-list {
+  margin: 10px 0px 0px 0px;
+  padding-left: 20px;
+}
+
+ul#favourites_list li, ul#species_list li { cursor:move; }
+
+div.tab_content_panel {
+  padding: 0px 5px 5px 5px;
+}
+
+div.tab_footer {
+  padding: 4px;
+}
+
+div.tab a, div.tab a:link, div.tab a:visited {
+  text-decoration: none;
+}
+
+div.selected a, div.selected a:link, div.selected a:visited {
+  color: #111;
+}
+
+#pre_tab, #pre {
+  color:#339966;
+  background-color:#CCFFCC;
+}
+
+#pre_tab selected {
+  border-bottom: 1px solid #CCFFCC; 
+}
+
+div.tab {
+  position: relative;
+  left: 0px;
+  top: 1px;
+  float: left;
+  width: 35%;
+  padding: 5px;
+  background: #ffffcc;
+  border-top: 1px solid #ffdf33;
+  border-right: 1px solid #ffdf33;
+  border-left: 1px solid #ffdf33;
+  border-bottom: 1px solid #ffdf33;
+  margin-right: 3px;
+}
+
+div.selected {
+  background: #fff;
+  border-bottom: 1px solid white;
+  font-weight: bold;
+}
+
+div.tab_content {
+  border: 1px solid #ffdf33;
+  padding: 5px;
+}
+
+div.pre_content {
+  background-color:#CCFFCC;
+}
+
+
+/* LISTS */
+#page ol li { list-style-type:decimal; list-style-image:none; }
+
+#page ul li { list-style-image:url(/img/red_bullet.gif); }
+#page ul.checklist li { list-style-image:url(/img/checkbox.gif) }
+
+#page ul.level2 li { list-style-image:url(/img/blue_bullet.gif); }
+
+#page ul.spaced li { margin-bottom:0.5em;}
+#page ol.spaced li { margin-bottom:0.5em;}
+
+dt { font-weight:bold; }
+                                                                                
+dd { margin-bottom:1em; }
+
+
+/****************************** IMAGES ************************************/
+
+img.float-left { float:left; margin-right:10px; }
+
+img.float-right { float:right; margin-left:10px; }
+
+.screenshot { text-align:center; margin:10px auto; }
+
+.karyomap { text-align:center; margin:auto; }
+
+.flash { margin:20px auto; }
+.tutorial { width:675px; height:600px; }
+
+/* JavaScript dropdown menus on images*/
+                                                                                   
+table.ddmenu { border:1px solid #ffdf33; background-color: #ffffdd}
+.ddmain, td.ddmain { background-color: #ffffdd; font-size: 8pt; font-family: Arial, helvetica, verdana, sans-serif; color: #000; }
+td.ddmain a { background-color:#ffffdd; text-decoration:none; font-size:8pt; font-family: Arial, helvetica, verdana, sans-serif; color:#3366bb; }
+.dddiv_button { background-color: #ffdf33; }
+.dddiv { position: absolute; top:0px; left:0px; z-index: 100; visibility: hidden; }
+
+/* JavaScript popup menus on images*/
+
+div#zmenu { font-family:arial,sans-serif,helvetica; font-size:0.9em; border:1px #cccccc solid;}
+div#zmenu th { background-color:#ccc; color:#000; }
+div#zmenu td { color:#555555;}
+div#zmenu a { text-decoration:none; }
+
+/* Mark up for geneseqview features */
+span.n   { background-color:#fefefe; color:black; } /* Normal bp */
+span.ns { background-color:#caff70; color:black; } /* SNP */
+span.nd { background-color:#12ff70; color:black; } /* Deletion */
+span.nc { background-color:#b0e2ff; color:black; } /* Conversed regions */
+span.no { background-color:#ffd700; color:black; } /* Codons */
+span.e   { background-color:#fefefe; color:red; }   /* Exon */
+span.es { background-color:#caff70; color:red; }
+span.ed { background-color:#12ff70; color:red; }
+span.ec { background-color:#b0e2ff; color:red; }
+span.eo { background-color:#ffd700; color:red; }
+
+div.user_setting {
+  padding-bottom: 25px;
+}
+
+/* TABLES */
+
+td.settings_header {
+  text-align: center;
+  border-bottom: 1px solid #666;
+}
+
+td.dark, div.dark {
+  background: #efefef;
+}
+
+div.group a, div.group a:link, div.group a:visited {
+  text-decoration: none;
+  font-weight: bold;
+}
+
+td.very_dark {
+  background: #dfdfdf;
+}
+
+td.invite {
+  background: #CCFFCC;
+}
+
+td.top {
+  border-top: 1px solid #999;
+} 
+
+
+tr { vertical-align:top; }
+
+th, td { text-align:left; border:none; color:#333333; }
+
+table.two-column { border-collapse:collapse; width: 100% }
+
+th.two-column, td.two-column { vertical-align:top; padding:0px 0.5em 0.5em 0.5em; border:1px solid #ccc; }
+
+th.two-column { width:15%; font-size:1.1em; color:#333333;
+    background-color:#f0f0f0; text-align:left; padding-top:0.5em; }
+
+td.two-column p {
+   /*border: dotted 1px red; */
+    margin-top: 0.5em; margin-bottom: 0.5em;
+}
+
+td.two-column dl, td.two-column ul, td.two-column ol {
+   /*border: dotted 1px green; */
+    margin-top: 0.5em; margin-bottom: 0.5em;
+}
+
+td.two-column dl ul { margin-top: 0px ; margin-bottom: 0.4em }
+
+td.two-column table {
+  /* border: dotted 1px blue;*/ 
+    margin-top: 0.5em; margin-bottom: 0.5em;
+}
+td.two-column table { margin: 0px }
+
+td.two-column th, td.two-column td { padding: 0px }
+td.two-column dt, td.two-column li, td.two-column dd, td.two-column td, td.two-column th {
+ /* border: solid 1px #fc9;*/ margin-top: 0px; margin-bottom: 0.3em;
+}
+td.two-column tr { vertical-align: top }
+
+table.stacked tr { vertical-align: top }
+
+th.stacked { background-color:#ffffcc; border:1px solid #ffdf33; 
+             color:#993333; text-align:center; padding:4px;}
+
+td.stacked { padding:4px; } 
+
+/* Striped spreadsheets */
+
+table.ss { width: 100%; }
+
+table.ss tr.ss_header { background-color:#ccc; border-width:1px 0px 0px 0px; border-color:#ccc; border-style:solid; }
+
+table.ss th { background-color: #ccc; border-width:1px 0px 0px 0px; border-color:#ccc; border-style:solid; padding:0.2em; vertical-align: top }
+
+table.ss td { vertical-align: top; padding:0.2em; }
+
+table.ss .left-border {  border-left:1px #ccc solid;  }
+
+table.ss .right-border {  border-right:1px #ccc solid;  }
+
+table.ss .bottom-border {  border-bottom:1px #ccc solid;  }
+
+table.ss tr.bg1 { background-color:#fff; }
+
+table.ss tr.bg2 { background-color:#f0f0f0; } /* grey stripe */
+
+table.tint tr.bg2 { background-color:#ffffcc; } /* coloured stripe */
+
+table.info-image { width:100%; margin:10px 0px; }
+table.info-image td.image { text-align:center; padding-right:20px; }
+
+
+/****************************** FORMS **********************************/
+
+div.formpanel { padding:1em; margin:auto; border:1px solid #ccc;}
+div.formpanel-left { padding:1em; border:1px solid #fff; }
+div.formpanel div, div.formpanel-left div { margin-top:5px; }
+
+.formblock { left: 0px; right: 0px; position: relative; }
+.formblock p { width: 100%; padding: 0px; margin: 0px;  }
+.formblock .formpadding { width: 29%; height: 1px; padding: 0px; margin:0px; float: left; left: 0px; top: 0px }
+.formblock h6 {
+  float: left; width: 29%; top: 0px; left: 0px; padding: 0px; padding-right: 10px; margin: 0px; text-align: right;
+  color: #993333; font-size: 1em; font-weight: bold; margin-top: 0.8em;
+}
+.formwide { margin-bottom: 0.5em; }
+.formwide h6, .forminline h6 {
+  top: 0px; left: 0px; padding: 0px; margin: 0px; 
+  color: #993333; font-size: 1em; font-weight: bold;
+}
+.formblock .formcontent { float: left; font-size: 1em; padding: 2px; width: 65%; margin-bottom: 0.8em; vertical-align:middle; }
+.formcenter, .formcenter div { display:block; text-align:center; margin-bottom: 0.8em;}
+.formcontent p { margin-top:0.3em; }
+.forminline, .forminline div { display:inline; }
+.forminline h6 { display:inline; margin-right:1em; }
+.tight { padding:0px; margin: 0px; }
+.middle { vertical-align:middle; }
+
+.radiocheck label, .radiocheck1col label { float: left; } /* width: 250px; } */
+
+.formblock textarea { width: 90%; height: 10em; }
+.formblock input.normal { width: 90% }
+.formblock .short  { width: 6em }
+.formblock .medium  { width: 12em }
+/** bug fix to get floats within their bordered div.... */
+.infoblock:after, .radiocheck1col:after, .radiocheck:after, .formblock:after  { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.infoblock, .radiocheck, .radiocheck1col, .formblock { display: inline-block; }
+/* Holly Hack Targets IE Win only \*/
+* html .infoblock, * html .radiocheck, * html .radiocheck1col, * html .formblock { height: 1%;}
+.infoblock, .radiocheck, .radiocheck1col, .formblock               { display: block; }
+/* end of Holly hack */
+.radiocheck { float: left; width: 15em; }
+.radiocheck1col .radio, .radiocheck .radio { display: inline; float: left }
+
+form#change_chr { margin:10px; }
+
+/**************************** MISCELLANEOUS *******************************/
+
+div.notice {
+    width:90%; margin:2em auto; padding: 1em;
+    background: #ffffcc; border:1px solid #993333;
+}
+
+div.notice h4 { margin:0px; text-align:center; }
+
+p.error {
+    width:50%; margin:2em auto; padding: 1em;
+    background: #fcc; color:#000; border:2px solid #993333;
+}
+
+.red { color:#933; }
+
+.blue-bullet {
+    background-image:url(blue_bullet.gif); background-repeat:no-repeat;
+    background-position:left center; padding-left:8px; }
+
+h2.breadcrumbs { color:#333333; }
+a.breadcrumb { text-decoration:none }
+
+p.footnote { font-size:85%; }
+a.fnlink { text-decoration:none; }
+
+ul.flush li { margin-left:-2em; }
+.alert { background-color:#fff9af; padding: 1px 0.5em; color:#000; font-style:italic; }
+
+/************************ PAGE-SPECIFIC STYLES *************************/
+
+/* Ensembl homepage */
+
+.sp-thumb { float:left; margin-right:4px; clear:left; }
+dl.species-list dt { margin:0px; padding:0px; min-height:15px;   font-size:120%; font-style:italic; font-weight:bold; }
+dl.species-list dd { margin:-2px 0px 2px 0px; padding:0px; min-height:40px; }
+dl.species-list dt a, dl.species-list dd a { text-decoration:none; }
+
+dl.species-list-small dt { margin:0px; padding:0px; min-height:15px; font-style:italic; font-weight:bold; }
+dl.species-list-small dd { margin:-2px 0px 2px 0px; padding:0px; min-height:30px;  }
+dl.species-list-small dt a, dl.species-list dd a { text-decoration:none; }
+
+ul.species-list li { margin-left:-20px; padding:0px; cursor:pointer; }
+ul.species-list span.sp { font-size:120%; font-style:italic; font-weight:bold; }
+ul.species-list li a { text-decoration:none; }
+div.species-news p { margin:0px; padding:4px 0px; font-size:110%; min-height:40px; }
+
+/* Species homepages */
+
+table#species-stats { width:100%; }
+
+table#species-stats td { padding:4px 0px; }
+
+table#species-stats td.data { font-weight:bold; }
+
+table#species-stats td.value { text-align:right;}
+
+/* Information and Documentation pages */
+
+a.info { text-decoration: none; font-weight:bold; }
+.blue {color: rgb(51, 102, 187); }
+
+/* HelpDesk */
+.example { width:90%; margin:1em auto; padding:20px;
+          border:1px solid #ccc; background:#eee; color:#000; }
+
+/* Other pages */
+
+div#page table.sitemap td ul.sitemap li.toggle { list-style:none; margin-left:-15px; }
+img.toggle-box { padding-right:4px; }
+dl.sitemap, ul.sitemap { margin:-0.5em -2em; }
+dl.sitemap a, ul.sitemap a { text-decoration:none; }
+dl.sitemap dt { font-size:115%; font-style:italic; }
+dl.sitemap dd { padding-bottom:0.5em; }
+table.sitemap td { padding:0px 40px; }
+
+a.cv-button    { font-size: 0.9em; background-color:#993333; color:#fff; font-weight:bold; text-decoration:none; border: 2px outset #993333; padding:2px; margin: 3px; }
+a.cv_plusminus { font-family:'Arial Black'; font-size: 30px; font-weight:bold; color:#993333; padding:5px; vertical-align:super; text-decoration:none; }
+.cv-zoom   { height: 30px; width: 13px; border: 0px; margin: 10px 0px 0px 0px; }
+.cv-zoom-2 { height: 16px; width: 13px; border: 0px; margin: 10px 0px 0px 0px; }
+
+.short_id_list dt { float: left; width: 6em; padding: 0px; margin: 0.2em 1em 0.2em 0.2em; border: 0; }
+.long_id_list dt { float: left; width: 13em; padding: 0px; margin: 0.2em 1em 0.2em 0.2em; border: 0; }
+
+table.grid { border-collapse: collapse }
+.grid tr td, .grid tr th { border: solid 1px #555555; border-collapse: collapse; padding: 0.2em; }
+
+/* Private formatting */
+table.bug td { border:solid 1px #555555 }
+
+table.zoom { display: inline }
+table.zoom, table.zoom tr td { border:0px; margin:0px; padding:0px; background-color:#ffffe7; font-weight: bold; }
+table.zoom tr td { vertical-align: bottom }
+table.zoom tr td img { margin-top: 0px }
+.navbox { background-color: #ffffe7 }
+
+
+/* CODE RELATED CSS */
+code { font: 1em andale mono, sans-serif; font-weight: bold; color: #990000 }
+.code { position: relative; border: 1px solid #666; background: #eee; margin: 1em 1em 0.2em 1em; padding: 0.2em 0.5em; }
+.code h4 { font-size: 1em; padding: 0.2em 0.5em ; z-index: 2; margin: -1em 0 0 -1em; border: 1px solid #666; background-color: #eee; }
+.code pre { margin: 0.5em 0em 1.5em 0em; font: 0.8em andale mono, sans-serif; color: #000 }
+.code pre:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.code pre { display: inline-block; }
+/* Holly Hack Targets IE Win only \*/
+* html .code pre { height: 1%;}
+.code pre               { display: block; }
+/* end of Holly hack */
+
+/* hide the rest of the file from Safari */
+.bogus { font-style:normal;# }
+.multicol { float: left; width: 16em; white-space: nowrap }
+
+    table.newzmenu { font-size: 0.9em; width: 200px; border: 2px solid #cccccc; padding: 0px; margin: 0px; border-collapse: collapse }
+    table.newzmenu th { background-color: #cccccc; text-align: left; padding: 1px 2px; vertical-align: top; border: 1px solid #cccccc }
+    table.newzmenu td { border: 1px solid #cccccc; padding: 1px 2px }
+    table.newzmenu td dl { margin: 0px }
+
diff --git a/resources/css/dazzle.css b/resources/css/dazzle.css
new file mode 100644
index 0000000..bea194e
--- /dev/null
+++ b/resources/css/dazzle.css
@@ -0,0 +1,286 @@
+/* STYLESHEET FOR DAZZLE  */
+
+
+/************* Styles for generic HTML elements **************/
+
+body { font-family: Luxi Sans, Geneva, Helvetica, Tahoma, Arial, sans-serif; 
+    font-size:76%; color:#555555; background-color:#fff;     
+    padding: 0px; margin: 0px; border: 0px;}
+pre, code, kbd {font-family:monospace; }
+div, p, span, li, dd, dt, th, td, pre, code, kbd { font-size:1em; }
+p  { margin-top:0.6em; margin-bottom:0.6em; }
+h1 { font-size:2em;   color:#3366bb; margin:1.2em 0px 0px 0px; padding:0px; }
+h2 { font-size:1.5em; color:#555555; margin:0.5em 0px 0px 0px; padding:0px; }
+h3 { font-size:1.2em; color:#993333; margin:1.5em 0px 0px 0px; padding:2px; }
+h4 { font-size:1.1em; color:#000; margin:1em 0px 0px 0px; padding:0px;}
+h5 { font-size:1em;   color:#000; margin:0px; padding:0px;}
+.viewname { font-size:1em; font-style:italic; color:#993333; }
+img  { border: 0px }
+hr   { display: none; }
+hr.show { display: block; }
+/* ul li { list-style:none outside none; } */
+
+a { color:inherit; text-decoration:none; } /* neutral style for anchor target */
+a:link    { color:#3366bb; text-decoration:underline; }
+a:visited { color:#993333; text-decoration:underline; }
+a:hover   { color:#cc0000; text-decoration:underline; }
+a:active  { color:#cc0000; text-decoration:underline; }
+
+form { border:none; margin-top: 0px; margin-bottom: 0px; padding:0px; }
+.form-button { color:#993333; font-weight:bold;
+    font-style:italic; padding:2px;  }
+.red-button { background-color:#993333; color:#fff; font-weight:bold;
+    font-style:italic; padding:2px; border:1px outset #993333; }
+.blue-button { background-color:#3366bb; color:#fff; font-weight:bold;
+    font-style:italic; padding:2px; border:1px outset #3366bb; }
+a.red-button, a.blue-button { padding:4px; color:#fff; text-decoration:none; } 
+a.red-button:visited, a.blue-button:visited { color:#fff; text-decoration:none; }
+
+/* Miscellaneous text styles */
+.bg1 { background:#fff; }
+.bg2 { background:#ffffdd; }
+.bg3 { background:#ffffcc; }
+.bg4 { background:#fff9af; }
+.bg5 { background:#ffffe7; }
+.hilite { background:#ccff99; }
+
+.serif    { font-family: Serif, Palatino, Times, "Times New Roman", serif; }
+.latin { font-style:italic; }
+.normal { font-style:normal; font-weight:normal; }
+
+kbd.line { display:block; margin-left:20px; }
+.nowrap { white-space:nowrap; }
+.left { text-align:left; }
+.right { text-align:right; }
+.center { text-align:center; }
+.middle { vertical-align:middle; }
+.bottom { vertical-align:bottom; }
+.autocenter { margin: 0 auto; }
+.small { font-size:80%; }
+
+/************ Section-specific styles ************/
+
+#masthead    { position: absolute; height: 5.5em; margin: 0px; padding: 0px; width: 100%; z-index: 5;
+               border: 0px; top: 0px; left: 0px; background-color: #fff }
+#masthead h1 { margin:0px; padding:0.4em 0.5em 0.5em 0.2em; font-size: 2em; background-color: #fff }
+#masthead a  { text-decoration:none; }
+#masthead a.home    { font-size:0.9em; font-weight: bold; font-style: italic;
+                      color:#933; vertical-align:super; }
+#masthead a.section { font-size:1.5em; color:#36b; }
+
+#search, #closewindow { position: absolute; right: 0.4em; top: 0.4em; z-index: 10; left:auto; margin:0px; padding:0px; text-align: right; border: 0px; }
+#accountlinks a { font-weight:bold; text-decoration:none; }
+          
+#release, #release-t { top: 5em; position: absolute; }
+#release, #release-t {  margin: 1px 0px; 
+                       right: 0px; height:1.5em; background-color:#9bb9dd;
+                       padding:0.2em 0px 0.2em 0px; border-style:solid; 
+                       border-width:1px 0px 1px 0px; border-color:#3366bb; }
+              
+#release-t   { z-index: 19; right: 0px; }
+#release     { width:100%; z-index:20; left:0px; color:#fff; font-weight:bold; }
+#release div { padding-left: 0.5em; }
+#release a   { text-decoration:none; }
+#help        { z-index: 30; padding: 0.5em; height:1.5em; position:absolute; top:4.5em; right: 0px; margin: 0.5em 1em; }
+/* #help a      { background-color:#3366bb; color:#fff; font-weight:bold;
+               font-style:italic; padding:2px; border:1px outset #3366bb;
+               text-decoration:none; } */
+#help a      { color:#fff; font-weight:bold; padding:2px;
+               text-decoration:none; }
+#page       { height 7em; right: 0px; left: 0px; z-index: 1; margin: 0px; padding: 0px; top: 0em; background: none; width: 100%; }
+#copy #a1, #page #i1    { padding: 0px 0px 0px 210px; background: none; }
+#copy #a2, #page #i2    { padding: 0px 5px 0px 0px; background: none; }
+
+#copy {right: 0px; left: 0px; z-index: 1; margin: 0px; padding: 0px; background: none  }
+#page div.sptop { height: 7em; }
+#page div.sp { height: 1em; }
+
+#related { z-index: 15; position: absolute; left: 0px; top: 7em; padding: 0px; border: 0px; margin: 0px; width: 211px; }
+#related-box { background-color:#fff9af; color:#333333; margin:0px 20px 0px 0px; padding:10px 0px 10px 0px; 
+    border-width:0px 1px 0px 0px; border-style:solid; border-color:#ffdf33; }
+#related h2 { background-color:#fff; color:#993333; font-size:1.2em; margin:0px -10px 0px 0px; padding:2px 0px 2px 10px; 
+  border-width:1px 1px 1px 0px; border-style:solid; border-color:#ffdf33; }
+#related form { padding-left:10px; }
+#related ul { padding-left: 0px; margin-left: 30px; border: 0px }
+#related li {   padding-top:4px; }
+#related li.bullet {   list-style: disc url(/img/yellow_bullet.gif); }
+#related a {    font-weight:bold; text-decoration:none; }
+
+/* Hide complex stuff from IE5 for Mac with a backslashed comment  \*/
+#related h2 { background-color:#fff; color:#993333; font-size:1.2em; margin:0px -10px 0px 0px; padding:2px 0px 2px 10px; overflow:hidden;
+  border-width:1px 1px 1px 0px; border-style:solid; border-color:#ffdf33; }
+/* end hack */
+
+p.archive-link { text-align:center; margin-top:2em; }
+p.affil-link { text-align:center; margin-top:4em; }
+
+/********************** Drop-down menus ************************/
+
+/*  CSS menus for IE Win and Gecko */
+
+/* Hide this funky stuff from IE5 for Mac with a backslashed comment  \*/
+.dropdown {position:relative; top:0px; left:0px; z-index:auto}
+.dropdown:hover { z-index:1; }
+.dropdown ul {position:absolute; top:1em; left:5px; width:200px; z-index:1;
+                    display: none; }
+.dropdown:hover ul {display:block;}
+.dropdown ul li { border:1px solid #ffdf33; padding:2px; margin:0px;
+                    background-color:#ffffcc; list-style:none; }
+/* end hack */
+
+* html .dropdown { position: relative; top: auto; left: auto; z-index: auto; display: block }
+* html .dropdown:hover  {z-index:1; }
+* html .dropdown ul { position: relative; top: auto; left: auto; width: auto; z-index: auto; display: block; list-style: none;}
+* html .dropdown:hover { display: block; }
+* html .dropdown ul li { border: 0px; padding: 2px; margin: 0em; margin-left: -25px; background-color: #fff9af; list-style: none; }
+* html #related li.bullet ul li.m { list-style: none url(/img/blank.gif); }
+/* end funky menu styling */
+
+
+/********************** Wizard stylings ************************/
+
+div.progress_bar {
+  padding-bottom: 10px;
+}
+
+div.progress_bar td {
+  border-top: 1px solid #3366bb;
+  border-bottom: 1px solid #3366bb;
+  color: #3366bb;
+  background: #fff9af;
+  text-align: center;
+}
+
+div.progress_bar td.todo {
+  background: #9bb9dd;
+}
+
+div.wizard {
+  padding: 20px;
+}
+
+div.wizard label {
+  padding-bottom: 15px;
+}
+div.wizard_previous {
+  padding-top: 45px;
+}
+
+div.wizard_check {
+  width: 90%;
+  border: 1px solid #9bb9dd;
+  background: #efefef;
+  color: #3366bb;
+  padding: 5px;
+}
+
+div.wizard_check b {
+  color: #333;
+}
+
+div#wizard_ticket{
+  width: 45%;
+  float: left;
+}
+
+div#wizard_ticket{
+  width: 45%;
+  float: left;
+}
+
+div#blast_queue_ticket {
+  padding: 20px;
+}
+
+div#blast_queue_message {
+  width: 60%;
+  padding: 5px;
+  float: left; 
+}
+
+div#blast_queue_stamp {
+  width: 30%;
+  float: right; 
+  text-align: right;
+}
+
+div#blast_queue_stamp_content {
+  width: 70%;
+  text-align: center;
+  padding: 5px;
+}
+
+div#blast_queue_stamp_content td {
+  border: 3px solid #9bb9dd;
+  color: #3366bb;
+  text-align: center;
+  background: #efefef;
+}
+
+div#blast_queue_stamp_content td.time {
+  background: #9bb9dd;
+  color: #efefef;
+  font-weight: bold;
+  padding: 1px;
+}
+
+div#blast_queue_stamp_content h1 {
+  margin: 0px;
+  padding: 0px;
+}
+
+div#blast_queue_stamp_content sup {
+  font-size: 50%;
+}
+
+div#blast_queue_ticket h2 {
+  margin: 0px;
+  padding: 0px 0px 10px 0px; 
+  color: #3366bb; 
+}
+
+div#evangelism_container {
+  margin-top: 50px;
+  padding: 5px;
+  width: 90%;
+  border: 1px solid #00cc00;
+  background: #ddFFdd;
+}
+
+div#evangelism_title  {
+  font-weight: bold;
+}
+
+div#evangelism_content {
+  padding: 6px;
+}
+
+div.wizard ul{
+  padding: 0px;
+  margin: 5px 0px 8px 18px;
+}
+
+div.bookmark_item {
+  padding: 3px;
+}
+
+div.bookmark_manage {
+  display: inline;
+  padding-left: 5px;
+}
+
+div.bookmark_editor {
+  display: inline;
+}
+
+div.bookmark_manage a:visited, div.bookmark_editor a:visited {
+  color: #3366bb;
+}
+
+span.bullet {
+  padding-right: 10px;
+}
+
+div.fragment {
+  display: none;
+}
diff --git a/resources/css/printer-styles.css b/resources/css/printer-styles.css
new file mode 100644
index 0000000..46c77d9
--- /dev/null
+++ b/resources/css/printer-styles.css
@@ -0,0 +1,18 @@
+/* Stylesheet for print version of site */
+body, h2, h4 { color:#000000; }
+body { background-position:top right; background: none }
+
+#related, #search, #help, #release-t { display: none }
+
+#copy, #copy #a1, #copy #a2, #page, #page #i1, #page #i2 { margin: 0px; padding: 0px }
+
+#release { position: absolute; right: 0.4em; top: 0.4em; z-index: 10; margin:0px;
+           padding:0px; border: 0px; border-style:none; border-width:0px;
+           border-color:transparent; background-color:transparent; text-align:right; color:#000000; }
+
+#release div { background-color:transparent; text-align:right; color:#000000; margin-right:2em; }
+
+.print_hide_tr, .print_hide_table, .print_hide_block, .print_hide { display: none }
+
+#page div.sptop { height: 5em }
+
diff --git a/resources/css/screen-styles.css b/resources/css/screen-styles.css
new file mode 100644
index 0000000..352646c
--- /dev/null
+++ b/resources/css/screen-styles.css
@@ -0,0 +1,36 @@
+body { color: #555555; }
+
+#related, #search, #help, #release-t { display: block }
+
+#copy, #page { width: 100%; padding: 0px ; background: none }
+#page { width: 100%; padding:0px; background: none; }
+
+#copy #a1, #page #i1 { padding: 0px 0px 0px 210px; background: none; }
+#copy #a2, #page #i2 { padding: 0px 5px 0px 0px; background: none; }
+
+#release { width: 100%; top: 5em; margin: 1px 0px; text-align: left;
+           right: 0px; height:1.5em; background-color:#9bb9dd;
+           padding:0.2em 0px 0.2em 0px; border-style:solid;
+           border-width:1px 0px 1px 0px; border-color:#3366bb;
+           z-index:20; left:0px; color:#fff; font-weight:bold; }
+
+#release div { padding-left: 0.5em; }
+
+.print_hide { display: inline }
+.print_hide_block { display: block }
+.print_hide_table { display: table }
+.print_hide_tr { display: table-row }
+
+#page div.sptop { height: 7em }
+
+.mart_main_menubar { border-bottom: 1px solid black; }
+.mart_summarypanel_datasets { border-width: 1px 1px 1px 1px; border-color: #999 }
+#mart_mainpanel { border-width: 1px 1px 1px 1px; border-color: #999 }
+.mart_databasemenu, .mart_interfacemenu, .mart_datasetmenu { border-bottom-width: 1px; border-bottom-color: #999; }
+.dummyLine { border-bottom: 1px solid #999 }
+div#mart_mainpanel { border: 1px solid #999 }
+div#mart_bottom_bar { border: 0px; border-top: 1px solid black }
+
+.mart_btn {    background-color: #993333; color: #fff; border: 2px outset #933 }
+.mart_btnhov { background-color: #993333; color: #fff; border: 2px outset #933 }
+
diff --git a/resources/org/biodas/das1/dasdna.dtd b/resources/org/biodas/das1/dasdna.dtd
new file mode 100755
index 0000000..b07d0fa
--- /dev/null
+++ b/resources/org/biodas/das1/dasdna.dtd
@@ -0,0 +1,8 @@
+<!ELEMENT DASDNA (SEQUENCE+)>
+<!ELEMENT SEQUENCE (DNA)>
+<!ATTLIST SEQUENCE id CDATA #REQUIRED>
+<!ATTLIST SEQUENCE start CDATA #REQUIRED>
+<!ATTLIST SEQUENCE stop CDATA #REQUIRED>
+<!ATTLIST SEQUENCE version CDATA #REQUIRED>
+<!ELEMENT DNA (#PCDATA)>
+<!ATTLIST DNA length CDATA #REQUIRED>
diff --git a/resources/org/biodas/das1/dasdsn.dtd b/resources/org/biodas/das1/dasdsn.dtd
new file mode 100755
index 0000000..4b0048a
--- /dev/null
+++ b/resources/org/biodas/das1/dasdsn.dtd
@@ -0,0 +1,8 @@
+<!ELEMENT DASDSN (DSN+)>
+<!ELEMENT DSN (SOURCE, DESCRIPTION?, MAPMASTER)>
+<!ELEMENT SOURCE (#PCDATA)>
+<!ATTLIST SOURCE id CDATA #REQUIRED>
+<!ATTLIST SOURCE version CDATA #IMPLIED>
+<!ELEMENT DESCRIPTION (#PCDATA)>
+<!ATTLIST DESCRIPTION href CDATA #IMPLIED>
+<!ELEMENT MAPMASTER (#PCDATA)>
diff --git a/resources/org/biodas/das1/dasep.dtd b/resources/org/biodas/das1/dasep.dtd
new file mode 100755
index 0000000..5e8f280
--- /dev/null
+++ b/resources/org/biodas/das1/dasep.dtd
@@ -0,0 +1,11 @@
+<!ELEMENT DASEP (ENTRY_POINTS)>
+<!ELEMENT ENTRY_POINTS (SEGMENT*)>
+<!ATTLIST ENTRY_POINTS href CDATA #REQUIRED>
+<!ATTLIST ENTRY_POINTS version CDATA #REQUIRED>
+<!ATTLIST ENTRY_POINTS id CDATA #IMPLIED>
+<!ELEMENT SEGMENT (#PCDATA)>
+<!ATTLIST SEGMENT id CDATA #REQUIRED>
+<!ATTLIST SEGMENT start CDATA #REQUIRED>
+<!ATTLIST SEGMENT stop CDATA #REQUIRED>
+<!ATTLIST SEGMENT orientation CDATA #REQUIRED>
+<!ATTLIST SEGMENT subparts CDATA #IMPLIED>
\ No newline at end of file
diff --git a/resources/org/biodas/das1/dasgff.dtd b/resources/org/biodas/das1/dasgff.dtd
new file mode 100755
index 0000000..28595c1
--- /dev/null
+++ b/resources/org/biodas/das1/dasgff.dtd
@@ -0,0 +1,35 @@
+<!ELEMENT DASGFF (GFF)>
+<!ELEMENT GFF (SEGMENT+)>
+<!ATTLIST GFF version CDATA #REQUIRED>
+<!ATTLIST GFF href CDATA #REQUIRED>
+<!ELEMENT SEGMENT (FEATURE+)>
+<!ATTLIST SEGMENT id CDATA #REQUIRED>
+<!ATTLIST SEGMENT start CDATA #REQUIRED>
+<!ATTLIST SEGMENT stop CDATA #REQUIRED>
+<!ATTLIST SEGMENT version CDATA #REQUIRED>
+<!ATTLIST SEGMENT label CDATA #IMPLIED>
+<!ELEMENT FEATURE (TYPE, METHOD, START, END, SCORE, ORIENTATION, PHASE, GROUP*, LINK*, NOTE*, TARGET*)>
+<!ATTLIST FEATURE id CDATA #REQUIRED>
+<!ATTLIST FEATURE label CDATA #IMPLIED>
+<!ATTLIST FEATURE version CDATA #IMPLIED>
+<!ELEMENT TYPE (#PCDATA)>
+<!ATTLIST TYPE id CDATA #IMPLIED>
+<!ATTLIST TYPE category CDATA #IMPLIED>
+<!ATTLIST TYPE reference CDATA "no">
+<!ATTLIST TYPE subparts CDATA "no">
+<!ELEMENT METHOD (#PCDATA)>
+<!ATTLIST METHOD id CDATA #IMPLIED>
+<!ELEMENT START (#PCDATA)>
+<!ELEMENT END (#PCDATA)>
+<!ELEMENT SCORE (#PCDATA)>
+<!ELEMENT ORIENTATION (#PCDATA)>
+<!ELEMENT PHASE (#PCDATA)>
+<!ELEMENT GROUP (NOTE*, LINK*, TARGET*)>
+<!ATTLIST GROUP id CDATA #REQUIRED>
+<!ELEMENT NOTE (#PCDATA)>
+<!ELEMENT LINK (#PCDATA)>
+<!ATTLIST LINK href CDATA #REQUIRED>
+<!ELEMENT TARGET (#PCDATA)>
+<!ATTLIST TARGET id CDATA #REQUIRED>
+<!ATTLIST TARGET start CDATA #REQUIRED>
+<!ATTLIST TARGET stop CDATA #REQUIRED>
diff --git a/resources/org/biodas/das1/dasres.dtd b/resources/org/biodas/das1/dasres.dtd
new file mode 100755
index 0000000..335b2b3
--- /dev/null
+++ b/resources/org/biodas/das1/dasres.dtd
@@ -0,0 +1,11 @@
+<!ELEMENT DASRES (RESOLVE)>
+<!ELEMENT RESOLVE (SEGMENT)>
+<!ATTLIST RESOLVE version CDATA #REQUIRED>
+<!ELEMENT SEGMENT (RELCOORD+)>
+<!ATTLIST SEGMENT id CDATA #REQUIRED>
+<!ATTLIST SEGMENT start CDATA #REQUIRED>
+<!ATTLIST SEGMENT stop CDATA #REQUIRED>
+<!ELEMENT RELCOORD EMPTY>
+<!ATTLIST RELCOORD id CDATA #REQUIRED>
+<!ATTLIST RELCOORD start CDATA #REQUIRED>
+<!ATTLIST RELCOORD stop CDATA #REQUIRED>
diff --git a/resources/org/biodas/das1/dassequence.dtd b/resources/org/biodas/das1/dassequence.dtd
new file mode 100644
index 0000000..40d454f
--- /dev/null
+++ b/resources/org/biodas/das1/dassequence.dtd
@@ -0,0 +1,7 @@
+<!ELEMENT DASSEQUENCE (SEQUENCE+)>
+<!ELEMENT SEQUENCE (#PCDATA)>
+<!ATTLIST SEQUENCE id CDATA #REQUIRED>
+<!ATTLIST SEQUENCE start CDATA #REQUIRED>
+<!ATTLIST SEQUENCE stop CDATA #REQUIRED>
+<!ATTLIST SEQUENCE version CDATA #REQUIRED>
+<!ATTLIST SEQUENCE molecule CDATA #REQUIRED>
diff --git a/resources/org/biodas/das1/dasstyle.dtd b/resources/org/biodas/das1/dasstyle.dtd
new file mode 100755
index 0000000..4290ea9
--- /dev/null
+++ b/resources/org/biodas/das1/dasstyle.dtd
@@ -0,0 +1,32 @@
+<!ELEMENT DASSTYLE (STYLESHEET)>
+<!ELEMENT STYLESHEET (CATEGORY+)>
+<!ATTLIST STYLESHEET version CDATA #REQUIRED>
+<!ELEMENT CATEGORY (TYPE+)>
+<!ATTLIST CATEGORY id CDATA #REQUIRED>
+<!ELEMENT TYPE (GLYPH)>
+<!ATTLIST TYPE id CDATA #REQUIRED>
+<!ELEMENT GLYPH (BOX | TOOMANY | ARROW | LINE | CONNECTOR | TEXT | EX | CROSS | DOT | TRIANGLE | SPAN)>
+<!ATTLIST GLYPH zoom CDATA #IMPLIED>
+<!ELEMENT BOX (WIDTH?, COLOR?, OUTLINECOLOR?, LINEWIDTH?)>
+<!ELEMENT TOOMANY (WIDTH?, COLOR?, OUTLINECOLOR?, LINEWIDTH?)>
+<!ELEMENT ARROW (WIDTH?, COLOR?, PARALLEL?, NORTHEAST?, SOUTHWEST?)>
+<!ELEMENT LINE (WIDTH?, COLOR?)>
+<!ELEMENT CONNECTOR (WIDTH?, COLOR?)>
+<!ELEMENT TEXT (FONT?, FONTSIZE?, STRING?, STYLE?, COLOR?)>
+<!ELEMENT EX (WIDTH?, COLOR?)>
+<!ELEMENT CROSS (WIDTH?, COLOR?)>
+<!ELEMENT DOT (WIDTH?, COLOR?)>
+<!ELEMENT TRIANGLE (COLOR?, WIDTH?, OUTLINECOLOR?, LINEWIDTH?)>
+<!ELEMENT SPAN (COLOR?, WIDTH?)>
+<!ELEMENT WIDTH (#PCDATA)>
+<!ELEMENT COLOR (#PCDATA)>
+<!ELEMENT OUTLINECOLOR (#PCDATA)>
+<!ELEMENT LINEWIDTH (#PCDATA)>
+<!ELEMENT PARALLEL (#PCDATA)>
+<!ELEMENT NORTHEAST (#PCDATA)>
+<!ELEMENT SOUTHWEST (#PCDATA)>
+<!ELEMENT FONT (#PCDATA)>
+<!ELEMENT FONTSIZE (#PCDATA)>
+<!ELEMENT STRING (#PCDATA)>
+<!ELEMENT STYLE (#PCDATA)>
+
diff --git a/resources/org/biodas/das1/dastypes.dtd b/resources/org/biodas/das1/dastypes.dtd
new file mode 100755
index 0000000..069decd
--- /dev/null
+++ b/resources/org/biodas/das1/dastypes.dtd
@@ -0,0 +1,14 @@
+<!ELEMENT DASTYPES (GFF)>
+<!ELEMENT GFF (SEGMENT)>
+<!ATTLIST GFF version CDATA #REQUIRED>
+<!ATTLIST GFF href CDATA #REQUIRED>
+<!ELEMENT SEGMENT (TYPE+)>
+<!ATTLIST SEGMENT id CDATA #REQUIRED>
+<!ATTLIST SEGMENT start CDATA #REQUIRED>
+<!ATTLIST SEGMENT stop CDATA #REQUIRED>
+<!ATTLIST SEGMENT version CDATA #REQUIRED>
+<!ATTLIST SEGMENT label CDATA #IMPLIED>
+<!ELEMENT TYPE (#PCDATA)>
+<!ATTLIST TYPE id CDATA #REQUIRED>
+<!ATTLIST TYPE method CDATA #IMPLIED>
+<!ATTLIST TYPE category CDATA #IMPLIED>
diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..5e94951
--- /dev/null
+++ b/src/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: 
+
diff --git a/src/org/biojava/servlets/dazzle/AbstractDazzleHandler.java b/src/org/biojava/servlets/dazzle/AbstractDazzleHandler.java
new file mode 100644
index 0000000..8c047cd
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/AbstractDazzleHandler.java
@@ -0,0 +1,53 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import org.biojava.servlets.dazzle.datasource.*;
+
+/**
+ * Handler which implements one or more DAS commands.
+ */
+
+public abstract class AbstractDazzleHandler implements DazzleHandler {
+    private final Class requirements;
+    private final String[] _commands;
+    private final String[] _caps;
+    
+    protected AbstractDazzleHandler(Class requirements, String[] commands, String[] caps) {
+        super();
+        this.requirements = requirements;
+        this._commands = commands;
+        this._caps = caps;
+    }
+    
+    public boolean accept(DazzleDataSource dds) {
+        return requirements.isInstance(dds);
+    }
+    
+    public String[] capabilities(DazzleDataSource dds) {
+        return _caps;
+    }
+    
+    public String[] commands(DazzleDataSource dds) {
+        return _commands;
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/AlignmentHandler.java b/src/org/biojava/servlets/dazzle/AlignmentHandler.java
new file mode 100644
index 0000000..671db55
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/AlignmentHandler.java
@@ -0,0 +1,279 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.biojava.utils.xml.*;
+import org.biojava.servlets.dazzle.datasource.*;
+import org.biojava.bio.structure.*;
+import org.biojava.bio.program.das.dasalignment.* ;
+import org.biojava.bio.Annotation ;
+
+
+/**
+ * Handler which implements the DAS ALIGNMENT command.
+ *
+ * @author Andreas Prlic
+ */
+
+public class AlignmentHandler extends AbstractDazzleHandler {
+    
+    private final static String NS_ALI = "http://www.efamily.org.uk/xml/das/2004/06/17/alignment.xsd";
+    private final static String NS_DASALI = "http://www.efamily.org.uk/xml/das/2004/06/17/dasalignment.xsd";
+
+    public AlignmentHandler() {
+        super(
+            AlignmentSource.class,
+            new String[] {"alignment"},
+            new String[] {"alignment/1.0"}
+        );
+    }
+
+  
+    public void run(
+        DazzleServlet dazzle,
+        DazzleDataSource dds,
+        String cmd,
+        HttpServletRequest req,
+        DazzleResponse resp
+    )
+        throws IOException, DataSourceException, ServletException, DazzleException
+    {
+	//System.out.println("run AlignmentHandler");
+
+	AlignmentSource ali_dds = (AlignmentSource)dds;
+	
+	String queries[] = req.getParameterValues("query") ;
+	
+	if ( queries == null) {
+		throw new DataSourceException("you did not request a query! the spec defines the alignment command to look like das/yourDASSourceName/alignment?query=XXX");
+	}
+	String query=queries[0];
+	String subject = "";
+	try {
+	    String subjects[] = req.getParameterValues("subject") ;
+	    subject = subjects[0] ;
+	} catch (NullPointerException e) {
+	    // no subject specified... ignore	    
+	}
+
+	
+	String queryCoordSys = "";
+	try {
+	    queryCoordSys = req.getParameterValues("querycoordsys")[0] ;
+	} catch (NullPointerException e) {
+	    // no subject specified... ignore	    
+	}
+	
+	
+
+	String subjectCoordSys = "";
+	try {
+	    subjectCoordSys = req.getParameterValues("subjectcoordsys")[0] ;
+	} catch (NullPointerException e) {
+	    // no subject specified... ignore	    
+	}
+
+	
+	//   System.out.println("query >"+query+"< querycoordsys >"+queryCoordSys 
+	//		   + "< subject:>"+subject+"< subjectcoordsys >" 
+	//		   + subjectCoordSys + "<");
+	
+	//ali_dds.setQuery(query);
+	    
+	//System.out.println("getting alignment");
+	Alignment[] alignments ;
+	
+	try {
+	    alignments = ali_dds.getAlignments(query,queryCoordSys,subject,subjectCoordSys);	   
+	} catch (Exception e) {
+	    //System.out.println("error during parsing of ali");
+	    throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS,e);
+	}
+		
+	if ( ( alignments == null ) || alignments.length == 0) {
+		throw new DazzleException(DASStatus.STATUS_BAD_REFERENCE,"no alignments found for reference " + query);
+	}
+	
+	//System.out.println("no way back, starting to write response ...");
+	XMLWriter xw = resp.startDasXML(false);
+
+	xw.openTag("dasalignment");
+	xw.attribute("xmlns",NS_DASALI);
+	xw.attribute("xmlns:align",NS_ALI);
+	xw.attribute("xmlns:xsd","http://www.w3.org/2001/XMLSchema-instance");
+	xw.attribute("xsd:schemaLocation",NS_DASALI + " " + NS_DASALI);
+	
+	if ( alignments != null ) {
+	    for (int alinr=0;alinr<alignments.length;alinr++){
+	    
+		Alignment alignment = alignments[alinr] ;
+	    	
+		String aligType = ali_dds.getAlignmentType();
+		xw.openTag("alignment");
+		xw.attribute("alignType",aligType);
+		Annotation[] objects = alignment.getObjects() ;
+		for ( int o = 0 ; o < objects.length;o++) {
+		    Annotation object = objects[o];
+		    xw.openTag("alignObject");
+		    xw.attribute("dbAccessionId",(String)object.getProperty("dbAccessionId"));	    
+		    xw.attribute("intObjectId",(String)object.getProperty("intObjectId"));	    
+		    xw.attribute("objectVersion",(String)object.getProperty("objectVersion"));	    
+		    if ( object.containsProperty("type")) {
+			xw.attribute("type",(String)object.getProperty("type"));	    
+		    }
+		    xw.attribute("dbSource",(String)object.getProperty("dbSource"));	    
+		    xw.attribute("dbVersion",(String)object.getProperty("dbVersion"));	    
+		    if ( object.containsProperty("dbCoordSys")) {
+			xw.attribute("dbCoordSys",(String)object.getProperty("dbCoordSys"));	
+		    }
+		    
+		    if ( object.containsProperty("details")){
+			List details = (List) object.getProperty("details");
+			for ( int det = 0 ; det< details.size();det++) {
+			    Annotation detanno = (Annotation) details.get(det);
+			    xw.openTag("alignObjectDetail");
+			
+			    xw.attribute("dbSource",(String)object.getProperty("dbSource"));
+			    xw.attribute("property",(String)detanno.getProperty("property"));
+			    xw.print((String)detanno.getProperty("detail"));
+			    xw.closeTag("alignObjectDetail");
+			}
+		    }
+
+		    xw.closeTag("alignObject");
+		}
+	    
+
+	    
+		// get the scores ...
+		Annotation[] scores = alignment.getScores();
+		for ( int s = 0 ; s < scores.length;s++) {
+
+		    Annotation score = scores[s];
+		    String scorename  = (String) score.getProperty("methodName");
+		    String scorevalue = (String) score.getProperty("value");
+
+		    xw.openTag("score");
+		    xw.attribute("methodName",scorename);
+		    xw.attribute("value",scorevalue);
+		    xw.closeTag("score");
+		} 
+	    
+
+		// and now the alignment blocks ...
+		Annotation[] blocks = alignment.getBlocks();
+		for ( int b = 0 ; b < blocks.length;b++) {
+		    Annotation block = blocks[b] ;
+		    xw.openTag("block");
+		    xw.attribute("blockOrder",(String)block.getProperty("blockOrder"));
+		    if (block.containsProperty("blockScore")) {
+			xw.attribute("blockScore",(String)block.getProperty("blockScore"));
+		    }
+		
+		    List segments = (List)block.getProperty("segments");
+		    for ( int s = 0 ; s < segments.size();s++) {
+
+			Annotation segment = (Annotation)segments.get(s);
+			xw.openTag("segment");
+			xw.attribute("intObjectId",(String)segment.getProperty("intObjectId"));
+			if ( segment.containsProperty("start")) 
+			    xw.attribute("start",(String)segment.getProperty("start"));
+			if ( segment.containsProperty("end")) 
+			    xw.attribute("end",(String)segment.getProperty("end"));
+			if ( segment.containsProperty("strand")) 
+			    xw.attribute("strand",(String)segment.getProperty("strand"));
+		    
+			if ( segment.containsProperty("cigar")) {
+			    xw.openTag("cigar") ;
+			    xw.print((String)segment.getProperty("cigar"));
+			    xw.closeTag("cigar");
+
+			}		    		    
+			xw.closeTag("segment");
+		    }
+		    xw.closeTag("block");
+		}
+
+		// geo3D part
+		// still missing ...
+		// do vector stuff
+		Annotation[] vectors  = alignment.getVectors();
+		//System.out.println("vectors length:" + vectors.length);
+		Annotation[] matrices = alignment.getMatrices();
+		for ( int i = 0 ; i < vectors.length; i++) {
+		    Annotation vector = vectors[i];
+		    xw.openTag("geo3D");
+		    String intObjectId = (String)vector.getProperty("intObjectId") ;
+		    xw.attribute("intObjectId",intObjectId);
+		    xw.openTag("vector");
+		
+		    Atom vec = (Atom) vector.getProperty("vector") ;
+
+		    String x = vec.getX()+"";
+		    xw.attribute("x",x) ;
+
+		    String y = vec.getY()+"";  ;
+		    xw.attribute("y",y) ;
+
+		    String z = vec.getZ()+"";  
+		    xw.attribute("z",z) ;
+
+		    xw.closeTag("vector");
+		
+		    // get the correct matrix
+		    for ( int j=0;j<matrices.length;j++){
+
+			Annotation matrix = matrices[j];
+
+			String intId = (String)matrix.getProperty("intObjectId");
+		    
+			if ( intId.equals(intObjectId)) {
+			    xw.openTag("matrix");
+
+			    for ( int u=1; u<=3; u++){
+				for ( int v=1; v<=3; v++){
+				    String mat = "mat"+u+v;
+				    String val = (String) matrix.getProperty(mat) ;
+				    xw.attribute(mat,val);
+				}
+			    }
+			    xw.closeTag("matrix");
+			}
+		    }
+		
+		    xw.closeTag("geo3D");
+		}
+		xw.closeTag("alignment");
+	    } 
+	}
+	xw.closeTag("dasalignment");
+	xw.close();
+	
+    }
+
+}
+    
diff --git a/src/org/biojava/servlets/dazzle/DASQueryStringTranslator.java b/src/org/biojava/servlets/dazzle/DASQueryStringTranslator.java
new file mode 100644
index 0000000..a3be684
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/DASQueryStringTranslator.java
@@ -0,0 +1,121 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.util.*;
+import java.io.*;
+import java.net.URLDecoder;
+
+import javax.servlet.http.*;
+
+/**
+ * Wraps up an HttpServletRequest, and allows for handling
+ * of query strings separated by ';' as well as '&'.
+ *
+ * @author Thomas Down, Benjamin Schuster-Boeckler
+ */
+
+class DASQueryStringTranslator extends HttpServletRequestWrapper {
+    private String queryString = null;
+    private Hashtable params = null;
+    
+    public DASQueryStringTranslator(HttpServletRequest req) {
+        super(req);
+    }
+    
+    public void setRequest(HttpServletRequest req) {
+        super.setRequest(req);
+        
+        // Since we cache a few things, these need to be flushed.
+        
+        this.queryString = null;
+        this.params = null;
+    }
+    
+    protected String getQueryStringTranslated() {
+        if (queryString != null)
+            return queryString;
+        
+        if (getMethod().equalsIgnoreCase("POST")) {
+            try {
+                BufferedReader br = new BufferedReader(getReader());
+                queryString = br.readLine();
+            } catch (Exception ex) {
+            }
+        } else {
+            queryString = getQueryString();
+	    if (queryString == null || queryString.length() == 0)
+		return null;
+            try {               
+                queryString = URLDecoder.decode(queryString,"UTF-8");                
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();                
+            }
+        }
+        if (queryString == null || queryString.length() == 0)
+            return null;
+        if (queryString.indexOf(';') >= 0) {
+            StringBuffer sb = new StringBuffer();
+            for (int i = 0; i < queryString.length(); ++i) {
+                char c = queryString.charAt(i);
+                if (c == ';')
+                    c = '&';
+                sb.append(c);
+            }
+            queryString = sb.toString();
+        }
+        return queryString;
+    }
+    
+    protected Hashtable getParameters() {
+        // Only works for GETs
+        
+        if (params == null) {
+            String p = getQueryStringTranslated();
+            if (p == null) 
+                params = new Hashtable();
+            else
+                params = HttpUtils.parseQueryString(p);
+        }
+        
+        return params;
+    }
+    
+    public String getParameter(String name) {
+        Hashtable params = getParameters();
+        String[] vals = (String[]) params.get(name);
+        if (vals != null)
+            return vals[0];
+        return null;
+    }
+    
+    public String[] getParameterValues(String name) {
+        Hashtable params = getParameters();
+        String[] vals = (String[]) params.get(name);
+        return vals;
+    }
+    
+    public Enumeration getParameterNames() {
+        Hashtable params = getParameters();
+        return params.keys();
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/DASStatus.java b/src/org/biojava/servlets/dazzle/DASStatus.java
new file mode 100644
index 0000000..bbc256e
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/DASStatus.java
@@ -0,0 +1,68 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.util.*;
+
+/**
+ * Status codes for DAS responses.
+ *
+ * @author Thomas Down
+ * @since 1.1
+ */
+
+public class DASStatus {
+    public static final int STATUS_OKAY = 200;
+    public static final int STATUS_OK = 200;
+
+    public static final int STATUS_BAD_COMMAND = 400;
+    public static final int STATUS_BAD_DATASOURCE = 401;
+    public static final int STATUS_BAD_COMMAND_ARGUMENTS = 402;
+    public static final int STATUS_BAD_REFERENCE = 403;
+    public static final int STATUS_BAD_STYLESHEET = 404;
+    public static final int STATUS_BAD_COORDS = 405;
+
+    public static final int STATUS_SERVER_ERROR = 500;
+    public static final int STATUS_UNSUPPORTED_FEATURE = 501;
+    
+    private static final Map<Integer,String> errorMessages;
+
+    static {
+        errorMessages = new HashMap<Integer,String>();
+        errorMessages.put(new Integer(STATUS_BAD_COMMAND), "Bad command");
+        errorMessages.put(new Integer(STATUS_BAD_DATASOURCE), "Bad datasource");
+        errorMessages.put(new Integer(STATUS_BAD_COMMAND_ARGUMENTS), "Bad command arguments");
+        errorMessages.put(new Integer(STATUS_BAD_REFERENCE), "Bad reference");
+        errorMessages.put(new Integer(STATUS_BAD_STYLESHEET), "Bad stylesheet");
+        errorMessages.put(new Integer(STATUS_BAD_COORDS), "Bad coordinates");
+        errorMessages.put(new Integer(STATUS_SERVER_ERROR), "Server error");
+        errorMessages.put(new Integer(STATUS_UNSUPPORTED_FEATURE), "Unimplemented feature");
+    }
+    
+    public static String getErrorDescription(int code) {
+        String desc =  errorMessages.get(new Integer(code));
+        if (desc == null) {
+            desc = "Unknown error";
+        }
+        return desc;
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/DazzleException.java b/src/org/biojava/servlets/dazzle/DazzleException.java
new file mode 100644
index 0000000..3a79995
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/DazzleException.java
@@ -0,0 +1,83 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+/**
+ * Exception thrown to indicate a failure in a Dazzle command handler.  Where
+ * possible, these exceptions should be constructed with a valid DAS error code.
+ * The <code>DASStatus</code> class provides helpful constants.  If a handler
+ * throws one of these exceptions before the HTTP header is complete, the controller
+ * servlet will produce a sensible DAS error page.  For this reason, handlers
+ * should attempt to perform all operations likely to trigger an exception
+ * before they start emitting any XML.
+ *
+ * @author Thomas Down
+ * @since 1.1
+ */
+
+public class DazzleException extends Exception {
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private int dasStatusCode;
+    
+    public int getDasStatus() {
+        return dasStatusCode;
+    }
+    
+    public DazzleException(int sc) {
+        super();
+        this.dasStatusCode = sc;
+    }
+    
+    public DazzleException(int sc, Exception ex) {
+        super(ex);
+        this.dasStatusCode = sc;
+    }
+    
+    public DazzleException(int sc, String msg) {
+        super(msg);
+        this.dasStatusCode = sc;
+    }
+    
+    public DazzleException(int sc, Exception ex, String msg) {
+        super(msg, ex);
+        this.dasStatusCode = sc;
+    }
+    
+    public DazzleException() {
+        this(DASStatus.STATUS_SERVER_ERROR);
+    }
+    
+    public DazzleException(Exception ex) {
+        this(DASStatus.STATUS_SERVER_ERROR, ex);
+    }
+    
+    public DazzleException(String message) {
+        this(DASStatus.STATUS_SERVER_ERROR, message);
+    }
+    
+    public DazzleException(Exception ex, String message) {
+        this(DASStatus.STATUS_SERVER_ERROR, ex, message);
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/DazzleHandler.java b/src/org/biojava/servlets/dazzle/DazzleHandler.java
new file mode 100644
index 0000000..b0d636c
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/DazzleHandler.java
@@ -0,0 +1,48 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.biojava.servlets.dazzle.datasource.*;
+
+/**
+ * Handler which implements one or more DAS commands.
+ */
+
+public interface DazzleHandler {
+    public boolean accept(DazzleDataSource dds);
+    
+    public String[] capabilities(DazzleDataSource dds);
+    
+    public String[] commands(DazzleDataSource dds);
+    
+    public void run(
+        DazzleServlet dazzle,
+        DazzleDataSource dds,
+        String cmd,
+        HttpServletRequest req,
+        DazzleResponse resp
+    )
+        throws IOException, ServletException, DataSourceException, DazzleException;
+}
diff --git a/src/org/biojava/servlets/dazzle/DazzleResponse.java b/src/org/biojava/servlets/dazzle/DazzleResponse.java
new file mode 100644
index 0000000..d3634c4
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/DazzleResponse.java
@@ -0,0 +1,109 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+
+import java.io.*;
+import javax.servlet.http.*;
+import org.biojava.utils.xml.*;
+
+/**
+ * Handle the response to a DAS command.
+ * This is a subclass of HttpServletResponse with some extra methods for
+ * managing the lifecycle of a DAS request
+ *
+ * @author Thomas Down
+ * @since 1.1
+ */
+
+public class DazzleResponse extends HttpServletResponseWrapper {
+    private final DazzleServlet dazzle;
+    private boolean statusIsSet = false;
+
+    public static final boolean displayXSL = false;
+    
+    DazzleResponse(HttpServletResponse resp, DazzleServlet dazzle) {
+        super(resp);
+        this.dazzle = dazzle;
+    }
+    
+    
+    
+    public void setDasStatus(int scode) {
+        if (statusIsSet) {
+            dazzle.log("Warning: attempt to reset DAS status");
+        } else {
+            ((HttpServletResponse) getResponse()).setIntHeader("X-DAS-Status", scode);
+            statusIsSet = true;
+        }
+    }
+    
+    /** Starts the DAS-XML response
+     * @param docType the document type of the DAS response
+     * @param dtdName the name of the .dtd 
+     * 
+     * @return the XMLWriter object that is used to write the DAS-XML 
+     * @throws IOException 
+     */
+    public XMLWriter startDasXML(String docType, String dtdName) 
+        throws IOException
+    {
+        setDasStatus(DASStatus.STATUS_OK);
+        setContentType(DazzleServlet.XML_CONTENT_TYPE);
+        PrintWriter pw = getWriter();
+        XMLWriter xw = new PrettyXMLWriter(pw);
+        
+        xw.printRaw("<?xml version='1.0' standalone='no' ?>");
+        if ( displayXSL )
+           xw.printRaw("<?xml-stylesheet type=\"text/xsl\" href=\"das.xsl\"?>");   
+        xw.printRaw("<!DOCTYPE " + docType + " SYSTEM '" + dtdName + "' >");
+        
+        return xw;
+    }
+
+
+    /** Starts the DAS-XML response
+     * 
+     * @return the XMLWriter object that is used to write the DAS-XML 
+     * @throws IOException 
+     */
+    public XMLWriter startDasXML() 
+    		throws IOException
+    {
+    	boolean showXSL = displayXSL;
+        return startDasXML(showXSL);
+    }
+    
+    public XMLWriter startDasXML(boolean showXSL) throws IOException{
+    	   setDasStatus(DASStatus.STATUS_OK);
+           setContentType(DazzleServlet.XML_CONTENT_TYPE);
+           PrintWriter pw = getWriter();
+           XMLWriter xw = new PrettyXMLWriter(pw);
+           
+           xw.printRaw("<?xml version='1.0' standalone='no' ?>");
+           if ( showXSL )
+        	   xw.printRaw("<?xml-stylesheet type=\"text/xsl\" href=\"das.xsl\"?>");    
+           return xw;
+    	
+    }
+
+}
diff --git a/src/org/biojava/servlets/dazzle/DazzleServlet.java b/src/org/biojava/servlets/dazzle/DazzleServlet.java
new file mode 100644
index 0000000..60172da
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/DazzleServlet.java
@@ -0,0 +1,720 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.biojava.utils.*;
+import org.biojava.utils.xml.*;
+
+import org.biojava.servlets.dazzle.datasource.*;
+
+/**
+ * A general purpose server for the Distributed Annotation System.  Should be a
+ * fully compliant implementation of DAS/1.52
+ *
+ * <p>
+ * When the servlet is initialized, it reads an XML configuration file (dazzlecfg.xml by
+ * default), which should configure one or more plugins implementing the DazzleDataSource
+ * interface.  These are then served as DAS DSNs.
+ * </p>
+ *
+ * @author Thomas Down
+ * @author Andreas Prlic
+ * @version 1.0.95
+ */
+
+public class DazzleServlet extends HttpServlet {
+	//
+	// General configuration
+	//
+			
+	private static final long serialVersionUID = 1L;
+	
+	public static final String DAZZLE_VERSION = "DazzleServer/1.0.95 (20090715; BioJava 1.7)";
+	
+	public static final String DAS_PROTOCOL_VERSION = "1.53E";
+	
+	public static final String[] DAS_CORE_CAPABILITIES = new String[] {"dsn/1.0"};
+	
+	public static final String XML_CONTENT_TYPE     = "text/xml";
+	public static final String SOURCES_CONTENT_TYPE = "application/x-das-sources+xml";
+	
+	public static final String DEFAULT_STYLESHEET = "/stylesheet.xml";
+	public static final String WELCOME_MESSAGE    = "/das_welcome.html";
+	public static final String DAS_SOURCES_LIST   = "/sources.xml";
+	public static final String XSL_FILE           = "/das.xsl";
+	
+	public static final String DAZZLE_INSTALLATION_TYPE = "org.biojava.servlets.dazzle.datasource.BasicDazzleInstallation";
+	public static final boolean REGEXP_SUPPORT = false;
+	public static final boolean TOLERATE_MISSING_SEGMENTS = false;
+	
+	//
+	// Runtime stuff
+	// 
+	
+	private DazzleHandler[] handlers;
+	private DazzleInstallation installation;
+	
+	//
+	// Local configuration flags
+	//
+	
+	private boolean gzipEncoding = true;
+	
+	/**
+	 * Get info about this servlet.
+	 */
+	
+	public String getServletInfo() {
+		return DAZZLE_VERSION;
+	}
+	
+	/**
+	 * Initialize DAS services, and load the XML configurations.
+	 */
+	
+	public void init(ServletConfig config)
+	throws ServletException
+	{
+		super.init(config);
+				
+		// Initialize handlers
+		
+		try {
+			Set handlerNames = Services.getImplementationNames(
+					DazzleHandler.class,
+					getClass().getClassLoader()
+			);
+			List<Object> handlerList = new ArrayList<Object>();
+			for (Iterator i = handlerNames.iterator(); i.hasNext(); ) {
+				String handlerName = (String) i.next() ;
+				System.out.println("adding handler " + handlerName);
+				handlerList.add(getClass().getClassLoader().loadClass(handlerName).newInstance());
+			}
+			handlers = (DazzleHandler[] ) handlerList.toArray(new DazzleHandler[0]);
+		} catch (Exception ex) {
+			throw new ServletException("Error initializing handler", ex);
+		}
+		
+		// Initialize installation
+		
+		String installClassName = config.getInitParameter("dazzle.installation_type");
+		if (installClassName == null) {
+			installClassName = DAZZLE_INSTALLATION_TYPE;
+		}
+		
+		try {
+			Class installClass = getClass().getClassLoader().loadClass(installClassName);
+			installation = (DazzleInstallation) installClass.newInstance();
+			installation.init(config);
+		} catch (DataSourceException ex) {
+			log("Error initializing installation", ex);
+			throw new ServletException("Error initializing installation");
+		} catch (ClassCastException ex) {
+			throw new ServletException("Not a Dazzle installation: " + installClassName);
+		} catch (ClassNotFoundException ex) {
+			throw new ServletException("Couldn't find class: " + installClassName);
+		} catch (InstantiationException ex) {
+			throw new ServletException("Couldn't instantiate " + installClassName);
+		} catch (IllegalAccessException ex) {
+			throw new ServletException("Couldn't instantiate " + installClassName);
+		}
+	}
+	
+	/**
+	 * Clean up datasources
+	 */
+	
+	public void destroy() {
+		super.destroy();
+		installation.destroy();
+	}
+	
+	/**
+	 * Normal DAS command.  As well as handling GETs, this method
+	 * also gets form-encoded POSTs.
+	 */
+	
+	public void doGet(
+			HttpServletRequest req,
+			HttpServletResponse resp
+	)
+	throws ServletException, IOException
+	{
+						
+		// We `filter' the query string, to accept strings separated
+		// using the ';' character
+		req = new DASQueryStringTranslator(req);
+		
+		// determine content-encoding for reply
+		// we only implement gzip so if that's not found, we
+		// fallback to plaintext.
+		String encodingStr = req.getHeader("Accept-Encoding");
+		
+		// if gzip encoding is required, replace the HttpServletResponse with a gzip version
+		// As IO is now buffered DO REMEMBER TO FLUSH BUFFERS PROPERLY.
+		if (encodingStr != null && gzipEncoding)  {
+			if (encodingStr.indexOf("gzip") != -1) {
+				resp = new HttpServletResponseWrapper(resp) {
+					GZIPOutputStream gzipOut = null;
+					public PrintWriter getWriter() throws IOException {
+						gzipOut = new GZIPOutputStream(getResponse().getOutputStream());
+						return new PrintWriter(gzipOut) {
+							// we return a subclassed PrintWriter which finishes GZIPOutputStream when close is called
+							public void close() {
+								super.close();
+								try {
+									gzipOut.finish();
+								}
+								catch (IOException ie) {
+									System.err.println("Unexpected IOException when closing GZIPOutputStream");
+								}
+							}
+						};
+					}
+				};
+				resp.setHeader("Content-Encoding", "gzip");
+			}
+		}
+		
+		DazzleResponse dazzleResp = new DazzleResponse(resp, this);
+
+		// Allow cross-site access
+		
+		// log("Origin= " + req.getHeader("Origin"));
+		dazzleResp.setHeader("Access-Control-Allow-Origin", "*");
+		// dazzleResp.setHeader("Access-Control-Allow-Credentials", "true");
+		
+		// Let ourselves be known...
+		
+		dazzleResp.setHeader("X-DAS-Version", DAS_PROTOCOL_VERSION);
+		dazzleResp.setHeader("X-DAS-Server", DAZZLE_VERSION);
+		
+		// used to send caps here, now have to wait until we've sorted out the dds
+		
+		String cmdPath = req.getPathInfo();
+		if (cmdPath == null) {
+			cmdPath = "";
+		}
+		
+		StringTokenizer toke = new StringTokenizer(cmdPath, "/");
+		if (! toke.hasMoreTokens()) {
+			welcomePage(req, resp);
+			return;
+		}
+		
+		List<String> nameComponents = new ArrayList<String>();
+		String command = toke.nextToken();
+		String prevComponent = "";
+		while (toke.hasMoreTokens()) {
+			nameComponents.add(command);
+			prevComponent = command;
+			command = toke.nextToken();
+		}		
+		
+		//System.out.println("prevComponent " + prevComponent);
+		try {
+			//System.out.println("*** INFO *** got command " + command);
+			
+			if (command.equals("dsn")) {
+				dsnPage(nameComponents, req, dazzleResp);
+			} else if (command.equals("das.xsl")) {
+				sendXSLFile( dazzleResp);
+			} else if ( command.equals("sources")){
+				sendSources(req,resp);
+			} else if (command.endsWith(".dtd")) {
+				sendDTD(req, dazzleResp, command);
+			} else if (prevComponent.equalsIgnoreCase("css")){
+				// a stylesheet was requested
+				sendStylesheet(req,dazzleResp,command);
+			} else {
+				DazzleDataSource dds = null;
+				try {
+					dds = installation.getDataSource(nameComponents, req);
+				} catch (DataSourceException ex) {
+					sendError(req, dazzleResp, DASStatus.STATUS_BAD_DATASOURCE);
+					return;
+				}
+				
+				List<String> caps = new ArrayList<String>(Arrays.asList(DAS_CORE_CAPABILITIES));
+				DazzleHandler commandHandler = null;
+				for (Iterator hi = Arrays.asList(handlers).iterator(); hi.hasNext(); ) {
+					DazzleHandler handler = (DazzleHandler) hi.next();
+					
+					if (handler.accept(dds)) {
+						//System.out.println("accepting " + dds.getName());
+						caps.addAll(Arrays.asList(handler.capabilities(dds)));
+						//System.out.println(handler.commands(dds));
+						if (Arrays.asList(handler.commands(dds)).contains(command)) {
+							if (commandHandler == null) {
+								commandHandler = handler;
+							}
+						}
+					}
+				}
+				
+				dazzleResp.setHeader("X-DAS-Capabilities", formatCaps(caps));
+				
+				if (commandHandler != null) {
+					commandHandler.run(this, dds, command, req, dazzleResp);
+				} else {
+					sendError(req, dazzleResp, DASStatus.STATUS_BAD_COMMAND, "Command " + command + " is not available for datasource " +dds.getName());
+					
+				}
+			}
+		} catch (DataSourceException ex) {
+			sendError(req, dazzleResp, DASStatus.STATUS_SERVER_ERROR, ex);
+		} catch (DazzleException ex) {		
+			sendError(req, dazzleResp, ex.getDasStatus(), ex);
+		}
+	}
+	
+	private static String formatCaps(List capList) {
+		StringBuffer sb = new StringBuffer();
+		for (Iterator ci = capList.iterator(); ci.hasNext(); ) {
+			sb.append(ci.next());
+			if (ci.hasNext()) {
+				sb.append("; ");
+			}
+		}
+		return sb.toString();
+	}
+	
+	/**
+	 * The only POSTs we support are form-encoded requests, which
+	 * get delegated to doGet.  Anything else is an error.
+	 */
+	
+	public void doPost(HttpServletRequest req,
+			HttpServletResponse resp)
+	throws ServletException, IOException
+	{
+		String contentType = req.getContentType();
+		StringTokenizer ctToke = new StringTokenizer(contentType, "/ ");
+		String ctmedia = null, ctsubtype = null;
+		if (ctToke.hasMoreTokens()) {
+			ctmedia = ctToke.nextToken().toLowerCase();
+		}
+		if (ctToke.hasMoreTokens()) {
+			ctsubtype = ctToke.nextToken().toLowerCase();
+		}
+		
+		if ("application".equals(ctmedia) && "x-www-form-urlencoded".equals(ctsubtype)) {
+			doGet(req, resp);
+			return;
+		}
+		
+		resp.setHeader("X-DAS-Version", DAS_PROTOCOL_VERSION);
+		resp.setHeader("X-DAS-Server", DAZZLE_VERSION);
+		
+		sendError(
+				req, 
+				resp,
+				DASStatus.STATUS_BAD_COMMAND_ARGUMENTS,
+				"Bad POSTed content type: " + contentType
+		);
+	}
+	
+	//
+	// Useful error-handling code.
+	//
+	
+	private void sendError(HttpServletRequest req,
+			HttpServletResponse resp,
+			int statusCode) 
+	throws ServletException, IOException
+	{
+		log("DAS Error: status=" + statusCode);
+		
+		resp.setIntHeader("X-DAS-Status", statusCode);
+		resp.setContentType("text/plain");
+		PrintWriter pw = resp.getWriter();
+		String msg = DASStatus.getErrorDescription(statusCode);
+		pw.println(msg + " (" + statusCode + ")");
+		pw.println();
+		pw.println("URL: " + DazzleTools.fullURL(req));
+	}
+	
+	private void sendError(
+			HttpServletRequest req,
+			HttpServletResponse resp,
+			int statusCode,
+			String message
+	)
+	throws ServletException, IOException
+	{
+		log("DAS Error: " + message);
+		
+		resp.setIntHeader("X-DAS-Status", statusCode);
+		resp.setContentType("text/plain");
+		PrintWriter pw = resp.getWriter();
+		String msg = DASStatus.getErrorDescription(statusCode);
+		pw.println(msg + " (" + statusCode + ")");
+		pw.println();
+		pw.println("URL: " + DazzleTools.fullURL(req));
+		pw.println();
+		pw.println(message);
+	}
+	
+	private void sendError(
+			HttpServletRequest req,
+			HttpServletResponse resp,
+			int statusCode,
+			Throwable exception
+	)
+	throws ServletException, IOException
+	{
+		
+		
+		resp.setIntHeader("X-DAS-Status", statusCode);
+		resp.setContentType("text/plain");
+		
+		PrintWriter pw = resp.getWriter();
+		String msg = DASStatus.getErrorDescription(statusCode);
+		pw.println(msg + " (" + statusCode + ")");
+		pw.println();
+		pw.println("URL: " + DazzleTools.fullURL(req));
+		pw.println();
+		
+		if (statusCode == DASStatus.STATUS_SERVER_ERROR ) {
+		      exception.printStackTrace(pw);
+		      log("DAS Error", exception);
+		}
+		pw.close();
+		pw.flush();
+				
+		
+	}
+	
+	
+	
+	// 
+	// Welcome page
+	//
+	
+	private void welcomePage(
+			HttpServletRequest req,
+			HttpServletResponse resp)
+	throws ServletException, IOException
+	{
+		List<String> dataSourceIDs = null;
+		Map<String,DazzleDataSource> dataSources = new HashMap<String, DazzleDataSource>();
+		try {
+			dataSourceIDs = new ArrayList<String>(installation.getDataSourceIDs(Collections.EMPTY_LIST, req));
+			for (Iterator<String> i = dataSourceIDs.iterator(); i.hasNext(); ) {
+				String id = i.next();
+				try {
+					dataSources.put(id, installation.getDataSource(Collections.nCopies(1, id), req));
+				} catch (DataSourceException ex) {
+					i.remove();
+					log("*** WARNING *** Lost a data source " + id);
+				}
+			}
+		} catch (DataSourceException ex) {
+			sendError(req, resp, DASStatus.STATUS_SERVER_ERROR, ex);
+			return;
+		}
+		
+		resp.setIntHeader("X-DAS-Status", DASStatus.STATUS_OKAY);
+		resp.setContentType("text/html");
+		PrintWriter pw = resp.getWriter();
+		pw.println("<html>");
+		pw.println("<head>");
+		pw.println("<link rel=\"STYLESHEET\" href=\"css/dazzle.css\" type=\"text/css\" />");
+		pw.println("<title>DAS Server information</title>");
+		pw.println("</head>");
+		pw.println("<body>");
+	
+		pw.println("<h1>" + DAZZLE_VERSION + "</h1>");
+	
+		
+		
+		// Information about this installation
+		
+		InputStream is = getServletContext().getResourceAsStream(WELCOME_MESSAGE);
+		if (is != null) {
+			BufferedReader br = new BufferedReader(new InputStreamReader(is));
+			String line;
+			while ((line = br.readLine()) != null) {
+				pw.println(line);
+			}
+		}
+		
+		
+		// DSN list
+		
+		String path = req.getContextPath() + req.getServletPath();
+		//System.out.println("dazzle use path:" + path);
+		pw.println("<ul><li>Do a DAS - <a href=\""+path+"/dsn\">DSN</a> request</ul></li>");
+		
+		pw.println("<h2>Available data sources</h2>");
+		pw.println("<table border=\"1\">");
+		pw.println("<tr><th>ID</th> <th>Description</th> <th>Version</th> <th>Reference?</th><th>Plugin</th></tr>");
+		for (Iterator<String> i = dataSourceIDs.iterator(); i.hasNext(); ) {
+			String id =  i.next();
+			DazzleDataSource dds = (DazzleDataSource) dataSources.get(id);
+			
+			pw.println("<tr>");
+			pw.println("  <td>" + id + "</td>");
+			pw.println("  <td>" + dds.getDescription() + "</td>");
+			pw.println("  <td>" + dds.getVersion() + "</td>");
+			pw.println("  <td>" + ((dds instanceof DazzleReferenceSource) ? "Yes" : "No") + "</td>");
+			pw.println("  <td>" + dds.getDataSourceType() + "/" + dds.getDataSourceVersion() + "</td>");
+			pw.println("</tr>");
+		}
+		pw.println("</table>");
+		
+		
+		pw.println("</body>");
+		pw.println("</html>");
+		pw.close();
+	}    
+	
+	//
+	// DSN command
+	//
+	
+	private void dsnPage(List<String> nameComponents,
+			HttpServletRequest req,
+			DazzleResponse resp)
+	throws ServletException, IOException, DazzleException
+	{
+		List<String> dataSourceIDs = null;
+		Map<String,DazzleDataSource> dataSources = new HashMap<String, DazzleDataSource>();
+		try {
+			dataSourceIDs = new ArrayList<String>(installation.getDataSourceIDs(nameComponents, req));
+			for (Iterator<String> i = dataSourceIDs.iterator(); i.hasNext(); ) {
+				String id =  i.next();
+				List<String> nc = new ArrayList<String>(nameComponents);
+				nc.add(id);
+				try {
+					dataSources.put(id, installation.getDataSource(nc, req));
+				} catch (DataSourceException ex) {
+					i.remove();
+					log("*** WARNING *** Lost a data source " + id);
+				}
+			}
+		} catch (DataSourceException ex) {
+			sendError(req, resp, DASStatus.STATUS_SERVER_ERROR, ex);
+			return;
+		}
+		
+		String refBase = req.getRequestURL().toString();
+		//deprecated: String refBase = HttpUtils.getRequestURL(req).toString();
+		if (refBase.endsWith("dsn")) {
+			refBase = refBase.substring(0, refBase.length() - 3);
+		} else if (refBase.endsWith("dsn/")) {
+			refBase = refBase.substring(0, refBase.length() - 4);
+		} else {
+			sendError(req, resp, DASStatus.STATUS_BAD_COMMAND);
+			return;
+		}
+		
+		XMLWriter xw = resp.startDasXML("DASDSN", "dasdsn.dtd");
+		
+		xw.openTag("DASDSN");
+		for (Iterator<String> i = dataSourceIDs.iterator(); i.hasNext(); ) {
+			String id =  i.next();
+			DazzleDataSource dataSource = (DazzleDataSource) dataSources.get(id);
+			
+			xw.openTag("DSN");
+			xw.openTag("SOURCE");
+			xw.attribute("id", id);
+			String version = dataSource.getVersion();
+			if (version != null) {
+				xw.attribute("version", version);
+			}
+			xw.print(dataSource.getName());
+			xw.closeTag("SOURCE");
+			xw.openTag("MAPMASTER");
+			if (dataSource instanceof DazzleReferenceSource) {
+				String ref = refBase + id + "/";
+				xw.print(ref);
+			} else {
+				xw.print(dataSource.getMapMaster());
+			}
+			xw.closeTag("MAPMASTER");
+			String description = dataSource.getDescription();
+			if (description != null) {
+				xw.openTag("DESCRIPTION");
+				xw.print(description);
+				xw.closeTag("DESCRIPTION");
+			}
+			xw.closeTag("DSN");
+		}
+		xw.closeTag("DASDSN");
+		xw.close();
+	}
+	
+	/** DAS2- style sources description of the DAS sources, as is also supported by the DAS registry.
+	 * e.g. see http://www.dasregistry.org/das1/sources/
+	 * 
+	 * @param req
+	 * @param resp
+	 * @throws ServletException
+	 * @throws IOException
+	 */
+	private void sendSources(HttpServletRequest req,
+			HttpServletResponse resp)
+	throws ServletException, IOException
+	{
+		
+		//TODO: automatically build up the sources description form the data-sources
+		//add optional configuration fields to the dazzleconfig.xml file that allows
+		//to specify the information that can not be inferred automatically
+		
+		System.out.println("getting sources listing from file: " +DAS_SOURCES_LIST );
+		
+		InputStream is = getServletContext().getResourceAsStream(DAS_SOURCES_LIST);
+		
+		
+		resp.setContentType(XML_CONTENT_TYPE);
+		
+		PrintWriter pw = resp.getWriter();
+		 
+		if (is != null) {
+			BufferedReader br = new BufferedReader(new InputStreamReader(is));
+			String line;
+			while ((line = br.readLine()) != null) {
+				pw.println(line);
+			}
+		}
+		pw.flush();
+		
+		pw.close();
+		
+	}
+	
+	//
+	// Old style Dazzle CAPABILITIES command
+	//
+	/*
+	private void capabilitiesPage(HttpServletRequest req,
+			DazzleResponse resp)
+	throws ServletException, IOException
+	{
+		XMLWriter xw = resp.startDasXML("DASCAP", "dascap.dtd");
+		
+		xw.printRaw("<?xml version='1.0' standalone='no' ?>");
+		
+		xw.openTag("capabilities");
+		sendCapability(xw, "featureTable", "dasgff");
+		sendCapability(xw, "featureTable", "xff");
+		xw.closeTag("capabilities");
+		xw.close();
+	}
+	
+	private void sendCapability(XMLWriter xw,
+			String type, 
+			String value)
+	throws IOException
+	{
+		xw.openTag("capability");
+		xw.attribute("type", type);
+		if (value != null) {
+			xw.attribute("value", value);
+		}
+		xw.closeTag("capability");
+	}*/
+	
+	//
+	// DTD pseudocommand
+	//
+	
+	private void sendDTD(HttpServletRequest req,
+			HttpServletResponse resp,
+			String dtdName)
+	throws ServletException, IOException
+	{   
+		String dtdPath = "org/biodas/das1/" + dtdName;
+		InputStream dtd = getClass().getClassLoader().getResourceAsStream(dtdPath);
+		
+		if (dtd == null) {
+			throw new ServletException("No such DTD: " + dtdName);
+		}
+		
+		resp.setContentType(XML_CONTENT_TYPE);
+		resp.setHeader("Content-Encoding", "plain");
+		OutputStream os = resp.getOutputStream();
+		
+		// reading with buffer array to  allow also sending of images
+		byte[] buffer = new byte[256];
+		int bufMax = 0;
+		while (bufMax >= 0) {
+			bufMax = dtd.read(buffer);
+			if (bufMax > 0)
+				os.write(buffer, 0, bufMax);
+		}
+		os.flush();	
+	}
+	
+	private void sendStylesheet(HttpServletRequest req,
+			HttpServletResponse resp,
+			String command) 
+	throws IOException,ServletException{
+					
+		String cssPath = "css/" + command;
+		InputStream is = getClass().getClassLoader().getResourceAsStream(cssPath);
+		
+		if (is == null) 
+			throw new ServletException("No such css: " + command);
+		
+		PrintWriter pw = resp.getWriter();
+		
+		BufferedReader br = new BufferedReader(new InputStreamReader(is));
+		String line;
+		while ((line = br.readLine()) != null) {
+			//System.out.println(line);
+			pw.println(line);
+		}
+
+    	pw.close();
+    	pw.flush();
+		
+	}
+	
+	 private void sendXSLFile(HttpServletResponse resp) 
+	    throws IOException{
+	    	
+		 	
+	    	resp.setContentType("text/xml");
+	    	PrintWriter pw = resp.getWriter();
+	    	InputStream is = getServletContext().getResourceAsStream(XSL_FILE);
+	    	if (is != null) {
+	    		BufferedReader br = new BufferedReader(new InputStreamReader(is));
+	    		String line;
+	    		while ((line = br.readLine()) != null) {
+	    			//System.out.println(line);
+	    			pw.println(line);
+	    		}
+	    	}
+	    	pw.close();
+	    	pw.flush();
+	    }
+	    
+	
+}
diff --git a/src/org/biojava/servlets/dazzle/DazzleTools.java b/src/org/biojava/servlets/dazzle/DazzleTools.java
new file mode 100644
index 0000000..cdf134d
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/DazzleTools.java
@@ -0,0 +1,181 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import java.util.*;
+
+import javax.servlet.http.*;
+
+import org.biojava.bio.seq.*;
+import org.biojava.bio.symbol.*;
+import org.biojava.servlets.dazzle.datasource.*;
+
+/**
+ * Utilities for processing DAS requests.
+ *
+ * @author Thomas Down
+ * @since 1.1
+ */
+ 
+public class DazzleTools {
+    private DazzleTools() {
+    }
+    
+    /**
+     * Generalized routine for extracting segments from a query string.
+     * @param dds DazzleDataSource
+     * @param req HttpServletRequest
+     * @param resp HttpServletResponse
+     *
+     * @return A List<Segment> giving all the valid segments specified by
+     *          the query (may be empty), or <code>null</code> is an error
+     *          occurred during processing (in which case a DAS error document
+     *          will already have been sent to the client).
+     * @throws IOException 
+     * @throws DazzleException 
+     */
+
+    public static List<Segment> getSegments(
+        DazzleDataSource dds,
+        HttpServletRequest req,
+        HttpServletResponse resp
+    )
+	    throws IOException, DazzleException
+    {
+        List<Segment> segments = new ArrayList<Segment>();
+        
+        try {
+            BiojavaFeatureSource.MatchType matchType = BiojavaFeatureSource.MATCH_EXACT;
+            {
+                String matchString = req.getParameter("match");
+                if (matchString != null) {
+                    if (matchString.equalsIgnoreCase("exact")) {
+                        matchType = BiojavaFeatureSource.MATCH_EXACT;
+                    } else if (matchString.equalsIgnoreCase("partial")) {
+                        matchType = BiojavaFeatureSource.MATCH_PARTIAL;
+                    } else {
+                        throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS);
+                    }
+                }
+            }
+            
+            //
+            // Old style
+            //
+            
+            String ref = req.getParameter("ref");
+            if (ref != null) {
+                String starts = req.getParameter("start");
+                String stops = req.getParameter("stop");
+                
+                if (starts == null) {
+                    segments.add(new Segment(ref));
+                } else {
+                    segments.add(new Segment(ref, Integer.parseInt(starts), Integer.parseInt(stops)));
+                }
+            }
+            
+            //
+            // New style...
+            //
+            
+            String[] newSegs = req.getParameterValues("segment");
+            if (newSegs != null) {
+                for (int i = 0; i < newSegs.length; ++i) {
+                    String newSeg = newSegs[i];
+                    StringTokenizer toke = new StringTokenizer(newSeg, ":,");
+                    String newRef = toke.nextToken();
+                    if (toke.hasMoreTokens()) {
+                        String starts = toke.nextToken();
+                        String stops = toke.nextToken();
+                        segments.add(new Segment(newRef, Integer.parseInt(starts), Integer.parseInt(stops)));
+                    } else {
+                        segments.add(new Segment(newRef));
+                    }
+                }
+            }
+            
+	   
+	    
+	    if (dds instanceof BiojavaFeatureSource) {
+		BiojavaFeatureSource bjdds = (BiojavaFeatureSource) dds ;
+		
+		String[] featureSegs = req.getParameterValues("feature_id");
+		if (featureSegs != null) {
+		    for (int i = 0; i < featureSegs.length; ++i) {
+			String featureID = featureSegs[i];
+			FeatureHolder featureInstances = bjdds.getFeaturesByID(featureID, matchType);
+			for (Iterator<Feature> fi = featureInstances.features(); fi.hasNext(); ) {
+			    Feature f = (Feature) fi.next();
+			    segments.add(new Segment(f.getSequence().getName(), f.getLocation().getMin(), f.getLocation().getMax()));
+			}
+		    }
+		}
+		
+		String[] groupSegs = req.getParameterValues("group_id");
+		if (groupSegs != null) {
+		    Map<String, List<Location>> locsBySeqName = new HashMap<String, List<Location>>();
+		    for (int i = 0; i < groupSegs.length; ++i) {
+			String groupID = groupSegs[i];
+			FeatureHolder groupInstances = bjdds.getFeaturesByGroup(groupID, matchType);
+			for (Iterator<Feature> fi = groupInstances.features(); fi.hasNext(); ) {
+			    Feature f = (Feature) fi.next();
+			    String seqName = f.getSequence().getName();
+			    List<Location> locs = (List<Location>) locsBySeqName.get(seqName);
+			    if (locs == null) {
+				locs = new ArrayList<Location>();
+				locsBySeqName.put(seqName, locs);
+			    }
+			    locs.add(f.getLocation());
+			}
+		    }
+		    for (Iterator seqi = locsBySeqName.entrySet().iterator(); seqi.hasNext(); ) {
+			Map.Entry seqme = (Map.Entry) seqi.next();
+			String seqName = (String) seqme.getKey();
+			Location locs = LocationTools.union((List) seqme.getValue());
+			segments.add(new Segment(seqName, locs.getMin(), locs.getMax()));
+		    }
+		}
+            }
+        } catch (NumberFormatException ex) {
+            throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS, ex);
+        } catch (NoSuchElementException ex) {
+            throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS, ex);
+        } catch (DataSourceException ex) {
+            throw new DazzleException(DASStatus.STATUS_SERVER_ERROR, ex);
+        }
+        
+        return segments;
+    }
+    
+    public static String fullURL(HttpServletRequest req) 
+    {
+        StringBuffer u = req.getRequestURL(); 
+        String q = req.getQueryString();
+        if (q != null) {
+            u.append('?');
+            u.append(req.getQueryString());
+        }
+        return u.toString();
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/EntryPointsHandler.java b/src/org/biojava/servlets/dazzle/EntryPointsHandler.java
new file mode 100644
index 0000000..e736cd5
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/EntryPointsHandler.java
@@ -0,0 +1,98 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import java.util.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.biojava.bio.seq.*;
+import org.biojava.utils.xml.*;
+import org.biojava.servlets.dazzle.datasource.*;
+
+/**
+ * Handler which implements the DAS entry_points command.
+ *
+ * @author Thomas Down
+ * @since 1.1
+ */
+
+public class EntryPointsHandler extends AbstractDazzleHandler {
+    public EntryPointsHandler() {
+        super(
+            DazzleReferenceSource.class,
+            new String[] {"entry_points"},
+            new String[] {"entry_points/1.0"}
+        );
+    }
+    
+    public void run(
+        DazzleServlet dazzle,
+        DazzleDataSource dds,
+        String cmd,
+        HttpServletRequest req,
+        DazzleResponse resp
+    )
+        throws IOException, DataSourceException, ServletException, DazzleException
+    {
+        DazzleReferenceSource drs = (DazzleReferenceSource) dds;
+        
+        XMLWriter xw = resp.startDasXML("DASEP", "dasep.dtd");
+        
+        try {
+            xw.openTag("DASEP");
+            xw.openTag("ENTRY_POINTS");
+            xw.attribute("href", DazzleTools.fullURL(req));
+            xw.attribute("version", drs.getVersion());
+            
+            Set entryPoints = drs.getEntryPoints();
+            for (Iterator i = entryPoints.iterator(); i.hasNext(); ) {
+                String ep = (String) i.next();
+                xw.openTag("SEGMENT");
+                xw.attribute("id", ep);
+                xw.attribute("size", "" + drs.getLandmarkLength(ep));
+                xw.attribute("subparts", hasSubparts(ep, drs) ? "yes" : "no");
+                xw.closeTag("SEGMENT");
+            }
+            
+            xw.closeTag("ENTRY_POINTS");
+            xw.closeTag("DASEP");
+            xw.close();
+        } catch (Exception ex) {
+        	ex.printStackTrace();
+            throw new DazzleException(ex, "Error writing ENTRY_POINTS document");
+        }
+    }
+
+    private boolean hasSubparts(String ref, DazzleReferenceSource drs) 
+        throws DataSourceException, NoSuchElementException
+    {
+    	
+    		Sequence seq = drs.getSequence(ref);
+    		if ( seq == null)
+    			return false;
+    		
+        return (seq.filter(new FeatureFilter.ByClass(ComponentFeature.class), false).countFeatures() > 0);
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/FeaturesHandler.java b/src/org/biojava/servlets/dazzle/FeaturesHandler.java
new file mode 100644
index 0000000..09869ef
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/FeaturesHandler.java
@@ -0,0 +1,902 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.biojava.bio.*;
+import org.biojava.bio.seq.*;
+import org.biojava.bio.symbol.*;
+import org.biojava.bio.program.xff.*;
+
+import org.biojava.utils.xml.*;
+
+import org.biojava.servlets.dazzle.datasource.*;
+
+import java.util.regex.Pattern;
+
+/**
+ * Handler which implements the DAS features and types commands.
+ *
+ * @author Thomas Down
+ * @since 1.1
+ */
+
+public class FeaturesHandler extends AbstractDazzleHandler {
+	private static final String DASGFF_VERSION = "1.0";
+
+	public FeaturesHandler() {
+		super(
+				BiojavaFeatureSource.class,
+				new String[] {"features", "types"},
+				new String[] {"types/1.0", "features/1.0", "encoding-dasgff/1.0", "encoding-xff/1.0", "feature-by-id/1.0", "group-by-id/1.0", "component/1.0"}
+		);
+	}
+
+	private final static String[] EMPTY_STRING_ARRAY = new String[0];
+	
+    public String[] capabilities(DazzleDataSource dds) {
+    	String[] caps = super.capabilities(dds);
+    	if (dds instanceof TilingFeatureSource) {
+    		List l = new ArrayList(Arrays.asList(caps));
+    		l.add("maxbins/1.0");
+    		caps = (String[]) l.toArray(EMPTY_STRING_ARRAY);
+    	}
+        return caps;
+    }
+	
+	public void run(
+			DazzleServlet dazzle, 
+			DazzleDataSource dds,
+			String cmd,
+			HttpServletRequest req,
+			DazzleResponse resp
+	)
+	throws IOException, DataSourceException, ServletException, DazzleException
+	{
+
+		if ( ! (dds instanceof BiojavaFeatureSource) ) {
+			System.err.println("got DataSource that is not a BiojavaFeaturesource!");
+		}
+
+		if("types".equals(cmd)) {
+			BiojavaFeatureSource bjfs = (BiojavaFeatureSource) dds ;
+			typesCommand(dazzle, req, resp, bjfs);
+		} else {
+			BiojavaFeatureSource bjfs = (BiojavaFeatureSource) dds ;
+			featuresCommand(dazzle, req, resp, bjfs);
+		}
+	}
+
+	private void featuresCommand(
+			DazzleServlet dazzle,
+			HttpServletRequest req,
+			DazzleResponse resp,
+			BiojavaFeatureSource dds
+	)
+	throws IOException, ServletException, DazzleException, DataSourceException
+	{
+		List segments = DazzleTools.getSegments(dds, req, resp);
+
+		String[] type = req.getParameterValues("type");
+		String[] category = req.getParameterValues("category");
+		String encoding = req.getParameter("encoding");
+		if (encoding == null) {
+			encoding = "dasgff";
+		}
+		boolean categorize = ("yes".equals(req.getParameter("categorize"))); // WHY WHY WHY?
+		int maxbins = -1;
+		{
+			String sMaxbins = req.getParameter("maxbins");
+			if (sMaxbins != null) {
+				maxbins = Integer.parseInt(sMaxbins);
+			}
+		}
+		FeatureFilter generalFilter = null;
+		try {
+			generalFilter = featuresOutput_buildGeneralFilter(dds, type, category);
+		} catch (PatternSyntaxException ex) {
+			throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS, ex);
+		}
+
+		// Fetch and validate the requests.
+
+		Map segmentResults = new HashMap();
+		for (Iterator i = segments.iterator(); i.hasNext(); ) {
+			Segment seg = (Segment) i.next();
+
+			try {
+				int length = dds.getLandmarkLength(seg.getReference());
+				if (seg.isBounded() && (seg.getMin() < 1 || seg.getMax() > length)) {
+					segmentResults.put(seg, "Segment " + seg.toString() + " doesn't fit sequence of length " + length);
+				} else {
+					FeatureHolder features;
+					if (dds instanceof TilingFeatureSource && maxbins >= 0) {
+						features = ((TilingFeatureSource) dds).getFeatures(seg.getReference(), maxbins);
+					} else {
+						features = dds.getFeatures(seg.getReference());
+					}
+					segmentResults.put(seg, features);
+				}
+				
+
+			} catch (NoSuchElementException ex) {
+				if (DazzleServlet.TOLERATE_MISSING_SEGMENTS) {
+					dazzle.log("Ugh, requested segment " + seg.getReference() + " was missing, but we're just going to ignore it.  Heigh ho");
+				} else {
+					segmentResults.put(seg, "Segment " + seg.getReference() + " was not found.");
+				}
+			} catch (DataSourceException ex) {
+				throw new DazzleException(DASStatus.STATUS_SERVER_ERROR, ex);
+			}
+		}
+
+		//
+		// Looks okay -- generate the response document
+		//
+
+		if (encoding.equalsIgnoreCase("dasgff")) {
+			featuresOutput_dasgff(req, resp, dds, segmentResults, generalFilter, categorize);
+		} else if (encoding.equalsIgnoreCase("xff")) {
+			featuresOutput_xff(req, resp, dds, segmentResults, generalFilter, categorize);
+		} else {
+			throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS, "Bad features encoding: " + encoding);
+		}
+	}
+
+	private FeatureFilter featuresOutput_buildSegmentFilter(FeatureFilter ff,
+			Segment seg)
+	{
+		if (seg.isBounded()) {
+			FeatureFilter newff = new FeatureFilter.ShadowOverlapsLocation(new RangeLocation(seg.getMin(),
+					seg.getMax()));
+			if (ff != FeatureFilter.all) {
+				ff = new FeatureFilter.And(ff, newff);
+			} else {
+				ff = newff;
+			}
+		}
+
+		return ff;
+	}
+
+	private FeatureFilter featuresOutput_buildGeneralFilter(DazzleDataSource dds,
+			String[] type,
+			String[] category) 
+	throws PatternSyntaxException
+	{
+		FeatureFilter ff = FeatureFilter.all;
+		Set allTypes = dds.getAllTypes();
+
+		if (type != null) {
+			Set types = new HashSet();
+			for (int t = 0; t < type.length; ++t) {
+
+				// if all types are requested, return all of them...
+				// this is to support otter...
+				if (type[t].equals("any") || type[t].equals("all")){
+					ff = FeatureFilter.all;
+					return ff;
+				}
+				if (DazzleServlet.REGEXP_SUPPORT) {
+
+					boolean added = false;
+					Pattern typesRE = Pattern.compile(type[t]);
+					for (Iterator i = allTypes.iterator(); i.hasNext(); ) {
+						String aType = (String) i.next();
+						if (typesRE.matcher(aType).matches()) {
+							types.add(aType);
+							added = true;
+						}
+					}
+
+					if (!added) {
+						types.add(type[t]);
+					}
+				} else {
+
+					types.add(type[t]);
+				}
+			}
+
+
+			for (Iterator i = types.iterator(); i.hasNext(); ) {
+				FeatureFilter newff = new FeatureFilter.ByType((String) i.next());
+				if (ff == FeatureFilter.all) {
+					ff = newff;
+				} else {
+					ff = new FeatureFilter.Or(ff, newff);
+				}
+			}
+		}
+		if (category != null) {
+			for (int t = 0; t < category.length; ++t) {
+				if ("component".equals(category[t])) {
+					FeatureFilter newff = new FeatureFilter.ByClass(ComponentFeature.class);
+					if (ff != FeatureFilter.all) {
+						ff = new FeatureFilter.Or(ff, newff);
+					} else {
+						ff = newff;
+					}
+				} else {
+					if (ff == FeatureFilter.all) {
+						ff = FeatureFilter.none;
+					}
+				}
+			}
+		}
+
+		// 
+		// Ensure that we don't descend past components (this required quite recent BioJava)
+		//
+
+		boolean descendThroughComponents = false;
+
+		if (!descendThroughComponents) {
+			FeatureFilter notComponentDescendants = new FeatureFilter.Not(
+					new FeatureFilter.ByAncestor(
+							new FeatureFilter.ByClass(ComponentFeature.class)
+					)
+			);
+			if (ff == FeatureFilter.all) {
+				ff = notComponentDescendants;
+			} else {
+				ff = new FeatureFilter.And(ff, notComponentDescendants);
+			}
+		}
+
+		return ff;
+	}
+
+	/**
+	 * Actual FEATURES document emitter for DASGFF.
+	 */
+
+	private void writeDasgffFeature(BiojavaFeatureSource dds, 
+			XMLWriter xw,
+			Feature feature,
+			List groups,
+			Location forcedLocation,
+			String forcedID,
+			boolean categorize)
+	throws IOException, ServletException
+	{
+
+
+		xw.openTag("FEATURE");
+		if (forcedID == null) {
+			xw.attribute("id", dds.getFeatureID(feature));
+		} else {
+			xw.attribute("id", forcedID);
+		}
+		String label = dds.getFeatureLabel(feature);
+		if (label != null) {
+			xw.attribute("label", label);
+		}
+
+		xw.openTag("TYPE");
+		xw.attribute("id", feature.getType());
+		if (feature instanceof ComponentFeature) {
+			if (categorize) {
+				xw.attribute("category", "component");
+			}
+			xw.attribute("reference", "yes");
+
+
+			boolean subParts = (feature.filter(new FeatureFilter.ByClass(ComponentFeature.class), false).countFeatures() > 0);
+			xw.attribute("subparts", subParts ? "yes" : "no");
+		} else {
+			if (categorize) {
+				xw.attribute("category", "default");
+			}
+		}
+		String description = dds.getTypeDescription(feature.getType());
+		if (description == null) {
+			description = feature.getType();
+		}
+		xw.print(description);  // todo: map this nicely
+		xw.closeTag("TYPE");
+
+		xw.openTag("METHOD");
+		xw.attribute("id", feature.getSource());
+		xw.print(feature.getSource());
+		xw.closeTag("METHOD");
+
+		{
+			Location loc = forcedLocation;
+			if (loc == null) {
+				loc = feature.getLocation();
+			}
+
+			xw.openTag("START");
+			xw.print("" + loc.getMin());
+			xw.closeTag("START");
+
+			xw.openTag("END");
+			xw.print("" + loc.getMax());
+			xw.closeTag("END");
+		}
+
+		xw.openTag("SCORE");
+		String score = dds.getScore(feature);
+		if (score != null) {
+			xw.print(score);
+		} else {
+			xw.print("-");
+		}
+		xw.closeTag("SCORE");
+
+		xw.openTag("ORIENTATION");
+		// System.err.print("Doing feature of type " + feature.getClass().toString() + ": ");
+		StrandedFeature.Strand strand = StrandedFeature.UNKNOWN;
+		if (feature instanceof StrandedFeature) {
+			strand = ((StrandedFeature) feature).getStrand();
+		} else if (feature.getParent() instanceof StrandedFeature) {
+			strand = ((StrandedFeature) feature.getParent()).getStrand();
+		}
+		// System.err.println(strand.toString());
+
+		if (strand == StrandedFeature.POSITIVE) {
+			xw.print("+");
+		} else if (strand == StrandedFeature.NEGATIVE) {
+			xw.print("-");
+		} else {
+			xw.print("0");
+		}
+		xw.closeTag("ORIENTATION");
+
+		xw.openTag("PHASE");
+		FramedFeature.ReadingFrame phase = dds.getPhase(feature);
+		if (phase == null) {
+			xw.print("-");
+		} else {
+			xw.print("" + phase.getFrame());
+		}
+		xw.closeTag("PHASE");
+
+
+		List notes = dds.getFeatureNotes(feature);
+		for (Iterator ni = notes.iterator(); ni.hasNext(); ) {
+			String note = ni.next().toString();
+			xw.openTag("NOTE");
+			xw.print(note);
+			xw.closeTag("NOTE");
+		}
+
+		if (feature instanceof ComponentFeature) {
+			ComponentFeature cf = (ComponentFeature) feature;
+			Location cfl = cf.getComponentLocation();
+
+			xw.openTag("TARGET");
+			xw.attribute("id", cf.getComponentSequence().getName());
+			xw.attribute("start", "" + cfl.getMin());
+			xw.attribute("stop", "" + cfl.getMax());
+			xw.closeTag("TARGET");
+		}
+
+		// Now generate DAS-0.999 linkouts.
+
+		if (forcedID == null) {
+			Map linkouts = dds.getLinkouts(feature);
+			if (linkouts != null && linkouts.size() > 0) {
+				for (Iterator li = linkouts.entrySet().iterator(); li.hasNext(); ) {
+					Map.Entry link = (Map.Entry) li.next();
+					String linkRole = (String) link.getKey();
+					String linkURI = (String) link.getValue();
+
+					xw.openTag("LINK");
+					xw.attribute("href", linkURI);
+					xw.print(linkRole);
+					xw.closeTag("LINK");
+				} 
+			}
+		} else {
+			// We don't really have an identity ourselves, so should just be linked via the group.
+		}
+
+		for (Iterator gi = groups.iterator(); gi.hasNext(); ) {
+			Object groupingObject = gi.next();
+			String gid;
+			String type;
+			String glabel;
+			Map links;
+			List groupNotes;
+			if (groupingObject instanceof Feature) {
+				Feature parentF = (Feature) groupingObject;
+				gid = dds.getFeatureID(parentF);
+				if (gid == null) {
+					gid = "" + parentF.hashCode();
+				}
+				type = parentF.getType();
+				links = dds.getLinkouts(parentF);
+				glabel = dds.getFeatureLabel(parentF);
+				groupNotes = Collections.EMPTY_LIST;
+			} else if (groupingObject instanceof DASGFFGroup) {
+				DASGFFGroup group = (DASGFFGroup) groupingObject;
+				gid = group.getGID();
+				type = group.getType();
+				links = group.getLinkMap();
+				glabel = group.getLabel();
+				groupNotes = group.getNotes();
+			} else {
+				throw new BioRuntimeException("Bad grouping object " + groupingObject.toString());
+			}
+
+			xw.openTag("GROUP");
+			xw.attribute("id", /* feature.getType() + "-" + */ gid);
+			xw.attribute("type", type);
+			if (glabel != null) {
+				xw.attribute("label", glabel);
+			}
+			if (links != null && links.size() > 0) {
+				for (Iterator li = links.entrySet().iterator(); li.hasNext(); ) {
+					Map.Entry link = (Map.Entry) li.next();
+					String linkRole = (String) link.getKey();
+					String linkURI = (String) link.getValue();
+
+					xw.openTag("LINK");
+					xw.attribute("href", linkURI);
+					xw.print(linkRole);
+					xw.closeTag("LINK");
+				}
+				for (Iterator ni = groupNotes.iterator(); ni.hasNext(); ) {
+					xw.openTag("NOTE");
+					xw.print((String) ni.next());
+					xw.closeTag("NOTE");
+				}
+			}
+			xw.closeTag("GROUP");
+		}
+
+		xw.closeTag("FEATURE");	
+	}
+
+
+	private void featuresOutput_dasgff(
+			HttpServletRequest req,
+			DazzleResponse resp,
+			BiojavaFeatureSource dds,
+			Map segmentResults,
+			FeatureFilter generalFilter,
+			boolean categorize)
+	throws IOException, ServletException, DazzleException
+	{
+
+		XMLWriter xw = resp.startDasXML("DASGFF", "dasgff.dtd");
+
+		try {
+			xw.openTag("DASGFF");
+			xw.openTag("GFF");
+			xw.attribute("version", DASGFF_VERSION);
+			xw.attribute("href", DazzleTools.fullURL(req));
+
+			for (Iterator i = segmentResults.entrySet().iterator(); i.hasNext(); ) {
+				Map.Entry me = (Map.Entry) i.next();
+				Segment seg = (Segment) me.getKey();
+				Object segv = me.getValue();
+				if (segv instanceof FeatureHolder) {
+					FeatureHolder features = (FeatureHolder) segv;
+
+					xw.openTag("SEGMENT");
+					xw.attribute("id", seg.getReference());
+					xw.attribute("version", dds.getLandmarkVersion(seg.getReference()));
+					if (seg.isBounded()) {
+						xw.attribute("start", "" + seg.getStart());
+						xw.attribute("stop", "" + seg.getStop());
+					} else {
+						xw.attribute("start", "1");
+						xw.attribute("stop", "" + dds.getLandmarkLength(seg.getReference()));
+					}
+					// TODO: Labels here?
+
+					FeatureFilter ff = featuresOutput_buildSegmentFilter(generalFilter, seg);
+					features = features.filter(ff, true);
+
+					List nullList = Collections.nCopies(1, null);
+
+					for (Iterator fi = features.features(); fi.hasNext(); ) {
+						Feature feature = (Feature) fi.next();
+
+						if (dds.getShatterFeature(feature)) {
+							int idSeed = 1;
+							String baseID = dds.getFeatureID(feature);
+							List baseGroupList = dds.getGroups(feature);
+							for (Iterator bi = feature.getLocation().blockIterator(); bi.hasNext(); ) {
+								Location shatterSpan = (Location) bi.next();
+								List groupList = new ArrayList();
+								groupList.add(feature);
+								groupList.addAll(baseGroupList);
+								writeDasgffFeature(dds, xw, feature, groupList, shatterSpan, baseID + "-" + (idSeed++), categorize);
+							}
+						} else {
+							List groups = dds.getGroups(feature);
+							writeDasgffFeature(dds, xw, feature, groups, null, null, categorize);
+						}
+					}
+
+					xw.closeTag("SEGMENT");
+				} else if (segv instanceof String) {
+					xw.openTag("ERRORSEGMENT");
+					xw.attribute("id", seg.getReference());
+					if (seg.isBounded()) {
+						xw.attribute("start", "" + seg.getStart());
+						xw.attribute("stop", "" + seg.getStop());
+					} 
+					xw.closeTag("ERRORSEGMENT");
+				} else if (segv == null) {
+					xw.openTag("UNKNOWNSEGMENT");
+					xw.attribute("id", seg.getReference());
+					xw.closeTag("UNKNOWNSEGMENT");
+				}
+			}
+
+			xw.closeTag("GFF");
+			xw.closeTag("DASGFF");
+			xw.close();
+		} catch (Exception ex) {
+			throw new DazzleException(ex, "Error writing DASGFF FEATURES document");
+		}
+	}
+
+	/**
+	 * Wrapper for the standard XFF-writing code
+	 */
+
+	private void featuresOutput_xff(HttpServletRequest req,
+			DazzleResponse resp,
+			BiojavaFeatureSource dds,
+			Map segmentResults,
+			FeatureFilter generalFilter,
+			boolean categorize)
+	throws IOException, ServletException, DazzleException
+	{
+
+		XMLWriter xw = resp.startDasXML();
+
+		XFFWriter xffw = new XFFWriter(new DataSourceXFFHelper(dds));
+		try {
+			xw.openTag("DASFEATURES");
+
+			for (Iterator i = segmentResults.entrySet().iterator(); i.hasNext(); ) {
+				Map.Entry me = (Map.Entry) i.next();
+				Segment seg = (Segment) me.getKey();
+				Object segv = me.getValue();
+				if (segv instanceof FeatureHolder) {
+					FeatureHolder features = (FeatureHolder) segv;
+
+					xw.openTag("SEGMENT");
+					xw.attribute("id", seg.getReference());
+					xw.attribute("version", dds.getLandmarkVersion(seg.getReference()));
+					if (seg.isBounded()) {
+						xw.attribute("start", "" + seg.getStart());
+						xw.attribute("stop", "" + seg.getStop());
+					} else {
+						xw.attribute("start", "1");
+						xw.attribute("stop", "" + dds.getLandmarkLength(seg.getReference()));
+					}
+					// TODO: Labels here?
+
+					FeatureFilter ff = featuresOutput_buildSegmentFilter(generalFilter, seg);
+					features = features.filter(ff, false); // FIXME!
+
+					xffw.writeFeatureSet(features, xw);
+
+					xw.closeTag("SEGMENT");
+				} else if (segv instanceof String) {
+					xw.openTag("ERRORSEGMENT");
+					xw.attribute("id", seg.getReference());
+					if (seg.isBounded()) {
+						xw.attribute("start", "" + seg.getStart());
+						xw.attribute("stop", "" + seg.getStop());
+					} 
+					xw.closeTag("ERRORSEGMENT");
+				} else if (segv == null) {
+					xw.openTag("UNKNOWNSEGMENT");
+					xw.attribute("id", seg.getReference());
+					xw.closeTag("UNKNOWNSEGMENT");
+				}
+			}
+
+			xw.closeTag("DASFEATURES");
+			xw.close();
+		} catch (Exception ex) {
+			throw new DazzleException(ex, "Error writing XFF FEATURES document");
+		}
+	}
+
+	private class DataSourceXFFHelper implements XFFHelper {
+		private BiojavaFeatureSource dds;
+
+		DataSourceXFFHelper(BiojavaFeatureSource dds) {
+			this.dds = dds;
+		}
+
+		public String getFeatureID(Feature f) {
+			return dds.getFeatureID(f);
+		}
+
+		public void writeDetails(XMLWriter xw, Feature f)
+		throws IOException
+		{
+			// General annotation-writing from Dazzle 0.08.  Is this a good idea?
+
+					Annotation a = f.getAnnotation();
+					for (Iterator ai = a.keys().iterator(); ai.hasNext(); ) {
+						Object key =  ai.next();
+						if (! (key instanceof String))
+							continue;
+						Object value = a.getProperty(key);
+						if (! (value instanceof String))
+							continue;
+
+
+						xw.openTag("biojava:prop");
+						xw.attribute("key", (String) key);
+						xw.print((String) value);
+						xw.closeTag("biojava:prop");
+					}
+
+					// Link-writing.  Since 0.93, this is no longer the datasource's responsibility
+
+					Map linkouts = dds.getLinkouts(f);
+					if (linkouts != null && linkouts.size() > 0) {
+						xw.openTag("das:links");
+						xw.attribute("xmlns:das", "http://www.biojava.org/dazzle");
+						xw.attribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
+						for (Iterator li = linkouts.entrySet().iterator(); li.hasNext(); ) {
+							Map.Entry link = (Map.Entry) li.next();
+							String linkRole = (String) link.getKey();
+							String linkURI = (String) link.getValue();
+
+							xw.openTag("das:link");
+							xw.attribute("xlink:role", linkRole);
+							xw.attribute("xlink:href", linkURI);
+							xw.closeTag("das:link");
+						} 
+						xw.closeTag("das:links");
+					}
+
+					// Any other stuff the datasource wants
+
+					dds.writeXFFDetails(xw, f);
+		}
+	}
+
+	//
+	// TYPES command
+	//
+
+	private void typesCommand(
+			DazzleServlet dazzle,
+			HttpServletRequest req,
+			DazzleResponse resp,
+			BiojavaFeatureSource dds
+	)
+	throws IOException, ServletException, DazzleException, DataSourceException
+	{
+		List segments = DazzleTools.getSegments(dds, req, resp);
+
+		String[] type = req.getParameterValues("type");
+		String[] category = req.getParameterValues("category");
+
+		// Fetch and validate the requests.
+
+		Map segmentResults = new HashMap();
+		for (Iterator i = segments.iterator(); i.hasNext(); ) {
+			Segment seg = (Segment) i.next();
+
+			try {
+				int length = dds.getLandmarkLength(seg.getReference());
+				if (seg.isBounded() && (seg.getMin() < 1 || seg.getMax() > length)) {
+					segmentResults.put(seg, "Segment " + seg.toString() + " doesn't fit sequence of length " + length);
+				} else {
+					Map typeCounts = new HashMap();
+					String[] typesToCalculate;
+
+					if (category == null) {
+						String[] _types = type;
+						List unhandledTypes = new ArrayList();
+						if (_types == null) {
+							_types = (String[]) dds.getAllTypes().toArray(new String[0]);
+						}
+						for (int t = 0; t < _types.length; ++t) {
+							String _type = _types[t];
+							int cntValue;
+							if (seg.isBounded()) {
+								cntValue = dds.countFeatures(seg.getReference(),
+										seg.getMin(),
+										seg.getMax(),
+										_type);
+							} else {
+								cntValue = dds.countFeatures(seg.getReference(), _type);
+							}
+
+							if (cntValue != BiojavaFeatureSource.COUNT_CALCULATE) {
+								if (cntValue >= 0) {
+									typeCounts.put(_type, new Integer(cntValue));
+								} else {
+									typeCounts.put(_type, null);
+								}
+							} else {
+								unhandledTypes.add(_type);
+							}
+						}
+
+						if (typeCounts.size() == 0) {
+							typesToCalculate = type;
+						} else {
+							typesToCalculate = (String[]) unhandledTypes.toArray(new String[0]);
+						}
+					} else {
+						typesToCalculate = type;
+					}
+
+					if (/* typesToCalculate == null || typesToCalculate.length > 0 */ typesToCalculate != null && typesToCalculate.length > 0) {
+						FeatureFilter generalFilter = null;
+						try {
+							generalFilter = featuresOutput_buildGeneralFilter(dds, typesToCalculate, category);
+						} catch (PatternSyntaxException ex) {
+							throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS, ex);
+						}
+
+						FeatureHolder features = dds.getFeatures(seg.getReference());
+						FeatureFilter ff = featuresOutput_buildSegmentFilter(generalFilter, seg);
+						for (Iterator fi = features.filter(ff, true).features(); fi.hasNext(); ) {
+							Feature feature = (Feature) fi.next();
+							String t = feature.getType();
+							Integer cnt = (Integer) typeCounts.get(t);
+							if (cnt != null) {
+								typeCounts.put(t, new Integer(cnt.intValue() + 1));
+							} else {
+								typeCounts.put(t, new Integer(1));
+							}
+						}
+					}
+
+					segmentResults.put(seg, typeCounts);
+				}
+			} catch (NoSuchElementException ex) {
+				if (DazzleServlet.TOLERATE_MISSING_SEGMENTS) {
+					dazzle.log("Ugh, requested segment " + seg.getReference() + " was missing, but we're just going to ignore it.  Heigh ho");
+				} else {
+					segmentResults.put(seg, "Couldn't find segment " + seg.getReference());
+				}
+			} catch (DataSourceException ex) {
+				throw new DazzleException(DASStatus.STATUS_SERVER_ERROR, ex);
+			}
+		}
+
+		//
+		// Looks okay -- generate the response document
+		//
+
+		XMLWriter xw = resp.startDasXML("DASTYPES", "dastypes.dtd");
+
+		try {
+			xw.openTag("DASTYPES");
+			xw.openTag("GFF");
+			xw.attribute("version", DASGFF_VERSION);
+			xw.attribute("href", DazzleTools.fullURL(req));
+
+			if (segmentResults.size() > 0) {
+				for (Iterator si = segmentResults.entrySet().iterator(); si.hasNext(); ) {
+					Map.Entry me = (Map.Entry) si.next();
+					Segment seg = (Segment) me.getKey();
+					Object segv = me.getValue();
+					if (segv instanceof Map) {
+						Map types = (Map) segv;
+						typesCommand_writeSegment(xw, dds, seg, types);
+					} else if (segv instanceof String) {
+						xw.openTag("ERRORSEGMENT");
+						xw.attribute("id", seg.getReference());
+						if (seg.isBounded()) {
+							xw.attribute("start", "" + seg.getStart());
+							xw.attribute("stop", "" + seg.getStop());
+						} 
+						xw.closeTag("ERRORSEGMENT");
+					} else if (segv == null) {
+						xw.openTag("UNKNOWNSEGMENT");
+						xw.attribute("id", seg.getReference());
+						xw.closeTag("UNKNOWNSEGMENT");
+					}	
+				}
+			} else {
+				Map types = new HashMap();
+				for (Iterator i = dds.getAllTypes().iterator(); i.hasNext(); ) {
+					String t = (String) i.next();
+					types.put(t, null);
+				}
+				typesCommand_writeSegment(xw, dds, null, types);
+			}
+
+			xw.closeTag("GFF");
+			xw.closeTag("DASTYPES");
+			xw.close();
+		} catch (Exception ex) {
+			throw new DazzleException(ex, "Error writing DASGFF TYPES document");
+		}
+	}
+
+	private void typesCommand_writeSegment(XMLWriter xw,
+			DazzleDataSource dds,
+			Segment seg,
+			Map types)
+	throws IOException, DataSourceException
+	{
+		xw.openTag("SEGMENT");
+		if (seg != null) {
+			xw.attribute("id", seg.getReference());
+			xw.attribute("version", dds.getLandmarkVersion(seg.getReference()));
+			if (seg.isBounded()) {
+				xw.attribute("start", "" + seg.getStart());
+				xw.attribute("stop", "" + seg.getStop());
+			} else {
+				xw.attribute("start", "1");
+				xw.attribute("stop", "" + dds.getLandmarkLength(seg.getReference()));
+			}
+		} else {
+			xw.attribute("version", dds.getVersion());
+		}
+
+		for (Iterator i = types.entrySet().iterator(); i.hasNext(); ) {
+			Map.Entry me = (Map.Entry) i.next();
+			String type = (String) me.getKey();
+			Integer count = (Integer) me.getValue();
+			xw.openTag("TYPE");
+			xw.attribute("id", type);
+			if (dds instanceof TypeMetadataSource) {
+				TypeMetadataSource tmds = (TypeMetadataSource) dds;
+				String tMethod = tmds.getTypeMethod(type);
+				if (tMethod != null) {
+					xw.attribute("method", tMethod);
+				}
+				String tCategory = tmds.getCategory(type);
+				if (tCategory != null) {
+					xw.attribute("category", tCategory);
+				}
+				String tDescription = tmds.getTypeDescriptionString(type);
+				if (tDescription != null) {
+					xw.attribute("description", tDescription);
+				}
+				String tEvidence = tmds.getTypeEvidenceCode(type);
+				if (tEvidence != null) {
+					xw.attribute("evidence", tEvidence);
+				}
+				String tOntology = tmds.getTypeOntology(type);
+				if (tOntology != null) {
+					xw.attribute("ontology", tOntology);
+				}
+			}
+			if (count != null) {
+				xw.print(count.toString());
+			}
+			xw.closeTag("TYPE");
+		}
+		xw.closeTag("SEGMENT");
+	}
+	
+	
+}
diff --git a/src/org/biojava/servlets/dazzle/GFFFeaturesHandler.java b/src/org/biojava/servlets/dazzle/GFFFeaturesHandler.java
new file mode 100644
index 0000000..3119139
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/GFFFeaturesHandler.java
@@ -0,0 +1,408 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.PatternSyntaxException;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.biojava.utils.xml.*;
+import org.biojava.bio.seq.Feature;
+import org.biojava.bio.seq.FeatureFilter;
+import org.biojava.bio.seq.FeatureHolder;
+import org.biojava.servlets.dazzle.datasource.*;
+
+
+/**
+ * Handler which implements the DAS features and types commands.
+ *
+ * @author Thomas Down
+ * @since 1.1
+ */
+
+public class GFFFeaturesHandler extends AbstractDazzleHandler {
+	private static final String DASGFF_VERSION = "1.0";
+
+	public GFFFeaturesHandler() {
+		super(
+				GFFFeatureSource.class,
+				new String[] {"features","types"},
+				new String[] {"features/1.0", "encoding-dasgff/1.0", "encoding-xff/1.0", "feature-by-id/1.0", "group-by-id/1.0", "component/1.0", "types/1.0"}
+		);
+	}
+
+	public void run(
+			DazzleServlet dazzle, 
+			DazzleDataSource dds,
+			String cmd,
+			HttpServletRequest req,
+			DazzleResponse resp
+	)
+	throws IOException, DataSourceException, ServletException, DazzleException
+	{
+		GFFFeatureSource newdds = (GFFFeatureSource) dds ;
+
+		//System.out.println("gfffeatureshandler got command " + cmd);
+		if("types".equals(cmd)) {
+			allTypesCommand(dazzle, req, resp, newdds);
+		} else {
+			featuresCommand(dazzle, req, resp, newdds);
+		}
+	}
+
+
+
+	//
+	// TYPES command
+	//
+
+	private void allTypesCommand(
+			DazzleServlet dazzle,
+			HttpServletRequest req,
+			DazzleResponse resp,
+			GFFFeatureSource dds
+	)
+	throws IOException, ServletException, DazzleException, DataSourceException
+	{
+		dds.getAllTypes();
+		XMLWriter xw = resp.startDasXML("DASTYPES", "dastypes.dtd");
+
+		try {
+			xw.openTag("DASTYPES");
+			xw.openTag("GFF");
+			xw.attribute("version", DASGFF_VERSION);
+			xw.attribute("href", DazzleTools.fullURL(req));
+
+			
+				Map types = new HashMap();
+				for (Iterator i = dds.getAllTypes().iterator(); i.hasNext(); ) {
+					String t = (String) i.next();
+					types.put(t, null);
+				}
+				typesCommand_writeSegment(xw, dds, null, types);
+			
+
+			xw.closeTag("GFF");
+			xw.closeTag("DASTYPES");
+			xw.close();
+		} catch (Exception ex) {
+			throw new DazzleException(ex, "Error writing DASGFF TYPES document");
+		}
+	}
+
+	private void featuresCommand(
+			DazzleServlet dazzle,
+			HttpServletRequest req,
+			DazzleResponse resp,
+			GFFFeatureSource dds
+	)
+	throws IOException, ServletException, DazzleException, DataSourceException
+	{
+		List<Segment> segments = DazzleTools.getSegments(dds, req, resp);
+
+		if ( segments.size() == 0)
+			throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS,"you did not provide a segment argument!");
+		
+		
+		String[] types = req.getParameterValues("type");
+		// if types != null filter by type!
+		
+		//System.out.println(segments);
+
+		//String[] type = req.getParameterValues("type");
+		//String[] category = req.getParameterValues("category");
+		String encoding = req.getParameter("encoding");
+		if (encoding == null) {
+			encoding = "dasgff";
+		}
+		//boolean categorize = ("yes".equals(req.getParameter("categorize"))); // WHY WHY WHY?
+
+
+		// Fetch and validate the requests.
+
+		Map<Segment,GFFFeature[]> segmentResults = new HashMap<Segment, GFFFeature[]>();
+		for (Iterator<Segment> i = segments.iterator(); i.hasNext(); ) {
+			Segment seg = (Segment) i.next();
+			GFFFeature[] features = null ;
+			try {
+				features = dds.getFeatures(seg,types);
+
+				//System.out.println("Handler got " + features.length + " features");
+				
+				//int length = dds.getLandmarkLength(seg.getReference());
+				segmentResults.put(seg, features);
+
+			} 
+
+			catch (DataSourceException ex) {
+				// by AP;
+				ex.printStackTrace();
+				throw new DazzleException(DASStatus.STATUS_SERVER_ERROR, ex);
+			}
+		}
+
+		//
+		// Looks okay -- generate the response document
+		//
+
+		writeDASResponse(req, resp, segmentResults, dds);
+	}
+	
+	
+		protected void writeDASResponse(
+				HttpServletRequest req,
+				DazzleResponse resp, 
+				Map segmentResults,
+				GFFFeatureSource dds) throws IOException, DazzleException{
+		XMLWriter xw = resp.startDasXML("DASGFF", "dasgff.dtd");
+		try {
+			xw.openTag("DASGFF");
+			xw.openTag("GFF");
+			xw.attribute("version", DASGFF_VERSION);
+			xw.attribute("href", DazzleTools.fullURL(req));
+
+			for (Iterator i = segmentResults.entrySet().iterator(); i.hasNext(); ) {
+				Map.Entry me = (Map.Entry) i.next();
+				Segment seg = (Segment) me.getKey();
+
+				xw.openTag("SEGMENT");
+				xw.attribute("id", seg.getReference());
+				xw.attribute("version", dds.getLandmarkVersion(seg.getReference()));
+				if (seg.isBounded()) {
+					xw.attribute("start", "" + seg.getStart());
+					xw.attribute("stop", "" + seg.getStop());
+				} else {
+					xw.attribute("start", "1");
+					xw.attribute("stop", "" + dds.getLandmarkLength(seg.getReference()));
+				}
+
+				GFFFeature[] features = (GFFFeature[])  me.getValue();
+				for ( int f = 0 ; f < features.length; f++ ) {
+					GFFFeature feature = features[f];
+					//System.out.println(feature);
+					xw.openTag("FEATURE");
+					xw.attribute("id",dds.getFeatureID(feature));
+					String label = feature.getLabel();
+					if (label != null) {
+						xw.attribute("label", label);
+					}
+					xw.openTag("TYPE");
+					if ( feature.getTypeId() != null)
+					   xw.attribute("id", feature.getTypeId());					   
+					else
+					   xw.attribute("id", feature.getType());
+					
+					if ( feature.getTypeCategory() != null) {
+                       xw.attribute("category", feature.getTypeCategory());
+                    }
+					String description = dds.getTypeDescription(feature.getType());
+					if (description == null) {
+						description = feature.getType();
+					}
+					xw.print(description);  // now ontology compliant
+					xw.closeTag("TYPE");
+					xw.openTag("METHOD");
+					xw.attribute("id", feature.getMethod());
+					xw.print(feature.getMethod());
+					xw.closeTag("METHOD");
+					
+					
+					
+					xw.openTag("START");
+					xw.print(feature.getStart());
+					xw.closeTag("START");
+
+
+					xw.openTag("END");
+					xw.print(feature.getEnd());
+					xw.closeTag("END");
+
+					xw.openTag("SCORE");
+					String score = feature.getScore();
+					if (score != null) {
+						xw.print(score);
+					} else {
+						xw.print("-");
+					}
+					xw.closeTag("SCORE");
+
+
+					String note = feature.getNote();
+					if ( note != null ) {
+						xw.openTag("NOTE");
+						// System.err.print("Doing feature of type " + feature.getClass().toString() + ": ");
+						xw.print(note);
+						xw.closeTag("NOTE");
+					}
+
+					String orient = feature.getOrientation();
+					if ( orient != null ) {
+						xw.openTag("ORIENTATION");
+						// System.err.print("Doing feature of type " + feature.getClass().toString() + ": ");
+						xw.print(orient);
+						xw.closeTag("ORIENTATION");
+					}
+
+
+					String phase = feature.getPhase();
+					if (phase != null) {
+
+						xw.openTag("PHASE");
+						xw.print(phase);			 
+						xw.closeTag("PHASE");
+					}
+
+					// LINK
+					String link = feature.getLink();
+					if ( link != null ) {
+						xw.openTag("LINK");
+						xw.attribute("href", link);
+						xw.print(link);
+						xw.closeTag("LINK");
+					}
+
+
+					// GROUP
+					if ( feature.getGroup() != null ){
+						printGroup(feature,xw);
+					}
+
+					xw.closeTag("FEATURE");
+				}
+				xw.closeTag("SEGMENT");
+			}
+
+
+			xw.closeTag("GFF");
+			xw.closeTag("DASGFF");
+			xw.close();
+
+
+		} catch (Exception ex) {
+		
+			ex.printStackTrace();
+			throw new DazzleException(ex, "Error writing DASGFF FEATURES document");
+		}
+	}
+
+
+	private void printGroup(GFFFeature feature, XMLWriter xw) throws IOException{
+
+		DASGFFGroup group = feature.getGroup();
+		String gid = group.getGID();
+		String gtype = group.getType();
+		Map links = group.getLinkMap();
+		String glabel = group.getLabel();
+		List<String> groupNotes = group.getNotes();
+		
+		xw.openTag("GROUP");
+            xw.attribute("id", /* feature.getType() + "-" + */ gid);
+            xw.attribute("type", gtype);
+            if (glabel != null) {
+                xw.attribute("label", glabel);
+            }
+            if (links != null && links.size() > 0) {
+                for (Iterator li = links.entrySet().iterator(); li.hasNext(); ) {
+                    Map.Entry glink = (Map.Entry) li.next();
+                    String linkRole = (String) glink.getKey();
+                    String linkURI = (String) glink.getValue();
+                    
+                    xw.openTag("LINK");
+                    xw.attribute("href", linkURI);
+                    xw.print(linkRole);
+                    xw.closeTag("LINK");
+                }
+                for (Iterator<String> ni = groupNotes.iterator(); ni.hasNext(); ) {
+                    xw.openTag("NOTE");
+                    xw.print((String) ni.next());
+                    xw.closeTag("NOTE");
+                }
+            }
+            xw.closeTag("GROUP");
+
+	}
+
+	
+	private void typesCommand_writeSegment(XMLWriter xw,
+			DazzleDataSource dds,
+			Segment seg,
+			Map types)
+	throws IOException, DataSourceException
+	{
+		xw.openTag("SEGMENT");
+		if (seg != null) {
+			xw.attribute("id", seg.getReference());
+			xw.attribute("version", dds.getLandmarkVersion(seg.getReference()));
+			if (seg.isBounded()) {
+				xw.attribute("start", "" + seg.getStart());
+				xw.attribute("stop", "" + seg.getStop());
+			} else {
+				xw.attribute("start", "1");
+				xw.attribute("stop", "" + dds.getLandmarkLength(seg.getReference()));
+			}
+		} else {
+			xw.attribute("version", dds.getVersion());
+		}
+
+		for (Iterator i = types.entrySet().iterator(); i.hasNext(); ) {
+			Map.Entry me = (Map.Entry) i.next();
+			String type = (String) me.getKey();
+			Integer count = (Integer) me.getValue();
+			xw.openTag("TYPE");
+			xw.attribute("id", type);
+			if (dds instanceof TypeMetadataSource) {
+				TypeMetadataSource tmds = (TypeMetadataSource) dds;
+				String tMethod = tmds.getTypeMethod(type);
+				if (tMethod != null) {
+					xw.attribute("method", tMethod);
+				}
+				String tCategory = tmds.getCategory(type);
+				if (tCategory != null) {
+					xw.attribute("category", tCategory);
+				}
+				String tDescription = tmds.getTypeDescriptionString(type);
+				if (tDescription != null) {
+					xw.attribute("description", tDescription);
+				}
+				String tEvidence = tmds.getTypeEvidenceCode(type);
+				if (tEvidence != null) {
+					xw.attribute("evidence", tEvidence);
+				}
+				String tOntology = tmds.getTypeOntology(type);
+				if (tOntology != null) {
+					xw.attribute("ontology", tOntology);
+				}
+			}
+			if (count != null) {
+				xw.print(count.toString());
+			}
+			xw.closeTag("TYPE");
+		}
+		xw.closeTag("SEGMENT");
+	}
+	
+
+
+}
diff --git a/src/org/biojava/servlets/dazzle/HydraGFFFeaturesHandler.java b/src/org/biojava/servlets/dazzle/HydraGFFFeaturesHandler.java
new file mode 100644
index 0000000..7db1dde
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/HydraGFFFeaturesHandler.java
@@ -0,0 +1,352 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import java.util.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.biojava.utils.xml.*;
+import org.biojava.servlets.dazzle.datasource.*;
+
+
+/**
+ * A Handler that speaks to multiple database backends at the same time.
+ * Uses the GFFFeature object for data representation.
+ *
+ * @author Andreas Prlic
+ * @since 1.1
+ */
+
+public class HydraGFFFeaturesHandler 
+extends AbstractDazzleHandler
+{
+	private static final String DASGFF_VERSION = "1.0";
+
+
+
+	public HydraGFFFeaturesHandler() {
+		super(
+				HydraGFFFeatureSource.class,
+				new String[] {"features"},
+				new String[] {"features/1.0", "encoding-dasgff/1.0", "encoding-xff/1.0", "feature-by-id/1.0", "group-by-id/1.0", "component/1.0"}
+		);
+	}
+
+
+	public void run(
+			DazzleServlet dazzle, 
+			DazzleDataSource dds,
+			String cmd,
+			HttpServletRequest req,
+			DazzleResponse resp
+	)
+	throws IOException, DataSourceException, ServletException, DazzleException
+	{
+		GFFFeatureSource newdds = (GFFFeatureSource) dds ;
+
+		System.out.println("hydragfffeatureshandler got command " + cmd);
+		if("types".equals(cmd)) {
+			System.out.println("not implemented... types" );
+		} else {
+			featuresCommand(dazzle, req, resp, newdds);
+		}
+	}
+
+	/** parse the DAS source name from the Request and pass it as an argument to the DasSource backend
+	 * 
+	 * @param dazzle
+	 * @param req
+	 * @param resp
+	 * @param dds
+	 * @throws IOException
+	 * @throws ServletException
+	 * @throws DazzleException
+	 * @throws DataSourceException
+	 */
+	private void featuresCommand(
+			DazzleServlet dazzle,
+			HttpServletRequest req,
+			DazzleResponse resp,
+			GFFFeatureSource dds
+	)
+	throws IOException, ServletException, DazzleException, DataSourceException
+	{
+		List segments = DazzleTools.getSegments(dds, req, resp);
+
+		System.out.println(segments);
+
+		//String[] type = req.getParameterValues("type");
+		//String[] category = req.getParameterValues("category");
+		String encoding = req.getParameter("encoding");
+		if (encoding == null) {
+			encoding = "dasgff";
+		}
+		//boolean categorize = ("yes".equals(req.getParameter("categorize"))); // WHY WHY WHY?
+		
+		
+		// if types != null filter by type!	
+		String[] types = req.getParameterValues("type");
+		
+		
+
+		// Fetch and validate the requests.
+
+		Map segmentResults = new HashMap();
+		for (Iterator i = segments.iterator(); i.hasNext(); ) {
+			Segment seg = (Segment) i.next();
+			GFFFeature[] features = null ;
+			try {
+				features = dds.getFeatures(seg,types);
+
+				//int length = dds.getLandmarkLength(seg.getReference());
+				segmentResults.put(seg, features);
+
+			} 
+
+			catch (DataSourceException ex) {
+				// by AP;
+				ex.printStackTrace();
+				throw new DazzleException(DASStatus.STATUS_SERVER_ERROR, ex);
+			}
+		}
+
+		//
+		// Looks okay -- generate the response document
+		//
+		writeDASResponse(req, resp, segmentResults, dds);
+
+	}
+	
+	
+	//
+	//TODO: remove dedundancy in the code below to GFFFeaturesHandler!!!
+	// everything is copied from there below:
+	
+	protected void writeDASResponse(
+			HttpServletRequest req,
+			DazzleResponse resp, 
+			Map segmentResults,
+			GFFFeatureSource dds) throws IOException, DazzleException{
+		XMLWriter xw = resp.startDasXML("DASGFF", "dasgff.dtd");
+		try {
+			xw.openTag("DASGFF");
+			xw.openTag("GFF");
+			xw.attribute("version", DASGFF_VERSION);
+			xw.attribute("href", DazzleTools.fullURL(req));
+
+			for (Iterator i = segmentResults.entrySet().iterator(); i.hasNext(); ) {
+				Map.Entry me = (Map.Entry) i.next();
+				Segment seg = (Segment) me.getKey();
+
+				xw.openTag("SEGMENT");
+				xw.attribute("id", seg.getReference());
+				xw.attribute("version", dds.getLandmarkVersion(seg.getReference()));
+				if (seg.isBounded()) {
+					xw.attribute("start", "" + seg.getStart());
+					xw.attribute("stop", "" + seg.getStop());
+				} else {
+					xw.attribute("start", "1");
+					xw.attribute("stop", "" + dds.getLandmarkLength(seg.getReference()));
+				}
+
+				GFFFeature[] features = (GFFFeature[])  me.getValue();
+				for ( int f = 0 ; f < features.length; f++ ) {
+					GFFFeature feature = features[f];
+					//System.out.println(feature);
+					xw.openTag("FEATURE");
+					xw.attribute("id",getFeatureID(feature));
+					String label = feature.getLabel();
+					if (label != null) {
+						xw.attribute("label", label);
+					}
+					xw.openTag("TYPE");
+					xw.attribute("id", feature.getType());
+					String description = dds.getTypeDescription(feature.getType());
+					if (description == null) {
+						description = feature.getType();
+					}
+					xw.print(description);  // todo: map this nicely
+					xw.closeTag("TYPE");
+					xw.openTag("METHOD");
+					xw.attribute("id", feature.getMethod());
+					xw.print(feature.getMethod());
+					xw.closeTag("METHOD");
+					xw.openTag("START");
+					xw.print(feature.getStart());
+					xw.closeTag("START");
+
+
+					xw.openTag("END");
+					xw.print(feature.getEnd());
+					xw.closeTag("END");
+
+					xw.openTag("SCORE");
+					String score = feature.getScore();
+					if (score != null) {
+						xw.print(score);
+					} else {
+						xw.print("-");
+					}
+					xw.closeTag("SCORE");
+
+
+					String note = feature.getNote();
+					if ( note != null ) {
+						xw.openTag("NOTE");
+						// System.err.print("Doing feature of type " + feature.getClass().toString() + ": ");
+						xw.print(note);
+						xw.closeTag("NOTE");
+					}
+
+					String orient = feature.getOrientation();
+					if ( orient != null ) {
+						xw.openTag("ORIENTATION");
+						// System.err.print("Doing feature of type " + feature.getClass().toString() + ": ");
+						xw.print(orient);
+						xw.closeTag("ORIENTATION");
+					}
+
+
+					String phase = feature.getPhase();
+					if (phase != null) {
+
+						xw.openTag("PHASE");
+						xw.print(phase);			 
+						xw.closeTag("PHASE");
+					}
+
+					// LINK
+					String link = feature.getLink();
+					if ( link != null ) {
+						xw.openTag("LINK");
+						xw.attribute("href", link);
+						xw.print(link);
+						xw.closeTag("LINK");
+					}
+
+
+					// GROUP
+					if ( feature.getGroup() != null ){
+						printGroup(feature,xw);
+					}
+
+					xw.closeTag("FEATURE");
+				}
+				xw.closeTag("SEGMENT");
+			}
+
+
+			xw.closeTag("GFF");
+			xw.closeTag("DASGFF");
+			xw.close();
+
+
+		} catch (Exception ex) {
+
+			ex.printStackTrace();
+			throw new DazzleException(ex, "Error writing DASGFF FEATURES document");
+		}
+	}
+
+	/**
+	 * Default implementation which returns an autogenerated ID.  This
+	 * takes the form __dazzle__<type>_<refseq>_<start>_<stop&gt.
+	 * This method should be overriden whereever possible, but it provides a useful
+	 * fallback for features which don't have a natural ID.
+	 * @param f the feature
+	 * @return returns the name of the faeture
+	 */
+
+	public String getFeatureID(GFFFeature f) {
+		//return f.getName() ;
+		
+
+        StringBuffer sb = new StringBuffer();
+        sb.append("__dazzle__");
+        sb.append(pack(f.getType()));
+        sb.append('_');
+        sb.append(pack(f.getName()));
+        sb.append('_');
+        sb.append(f.getStart());
+        sb.append('_');
+        sb.append(f.getEnd());
+        return sb.toString();
+		 
+	}
+
+	private String pack(String s) {
+		if (s.indexOf('_') < 0) {
+			return s;
+		} else {
+			StringBuffer sb = new StringBuffer();
+			for (int i = 0; i < s.length(); ++i) {
+				char c = s.charAt(i);
+				if (c != '_') {
+					sb.append(c);
+				} else {
+					sb.append("__");
+				}
+			}
+			return sb.toString();
+		}
+	}
+	
+	private void printGroup(GFFFeature feature, XMLWriter xw) throws IOException{
+
+		DASGFFGroup group = feature.getGroup();
+		String gid = group.getGID();
+		String gtype = group.getType();
+		Map links = group.getLinkMap();
+		String glabel = group.getLabel();
+		List groupNotes = group.getNotes();
+		
+		xw.openTag("GROUP");
+            xw.attribute("id", /* feature.getType() + "-" + */ gid);
+            xw.attribute("type", gtype);
+            if (glabel != null) {
+                xw.attribute("label", glabel);
+            }
+            if (links != null && links.size() > 0) {
+                for (Iterator li = links.entrySet().iterator(); li.hasNext(); ) {
+                    Map.Entry glink = (Map.Entry) li.next();
+                    String linkRole = (String) glink.getKey();
+                    String linkURI = (String) glink.getValue();
+                    
+                    xw.openTag("LINK");
+                    xw.attribute("href", linkURI);
+                    xw.print(linkRole);
+                    xw.closeTag("LINK");
+                }
+                for (Iterator ni = groupNotes.iterator(); ni.hasNext(); ) {
+                    xw.openTag("NOTE");
+                    xw.print((String) ni.next());
+                    xw.closeTag("NOTE");
+                }
+            }
+            xw.closeTag("GROUP");
+
+	}
+
+}
diff --git a/src/org/biojava/servlets/dazzle/InteractionHandler.java b/src/org/biojava/servlets/dazzle/InteractionHandler.java
new file mode 100644
index 0000000..5e7748b
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/InteractionHandler.java
@@ -0,0 +1,318 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+package org.biojava.servlets.dazzle;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.biojava.utils.xml.XMLWriter;
+import org.biojava.servlets.dazzle.datasource.InteractionReferenceSource;
+import org.biojava.servlets.dazzle.datasource.DazzleDataSource;
+import org.biojava.servlets.dazzle.datasource.DataSourceException;
+
+import de.mpg.mpiinf.ag3.dasmi.model.Interaction;
+import de.mpg.mpiinf.ag3.dasmi.model.Participant;
+import de.mpg.mpiinf.ag3.dasmi.model.Interactor;
+import de.mpg.mpiinf.ag3.dasmi.model.Detail;
+import de.mpg.mpiinf.ag3.dasmi.model.Range;
+
+
+/**
+ * Handler implementing the DAS 1.53E interaction command
+ * @author Hagen Blankenburg, Max Planck Institute for Informatics
+ */
+public class InteractionHandler extends AbstractDazzleHandler {
+	
+	//private static final String XMLNS = "http://www.w3.org/1999/xhtml";
+	private static final String XSI = "http://www.w3.org/2001/XMLSchema-instance";
+	private static final String SCHEMA_LOC = "http://dasmi.de/dasint";
+
+	
+	/**
+	 * Constructur, sets some configuration strings
+	 */
+    public InteractionHandler() {
+        super(InteractionReferenceSource.class,
+            new String[] {"interaction"},
+            new String[] {"interaction/1.0"});
+    }
+    
+    /**
+     * To be called from the Dazzle servlet in response to a request
+     * @param req Servlet request
+     * @param resp Servlet resonse
+     * @param dds Dazzle data source to be used 
+     */
+    public void run(DazzleServlet dazzle, DazzleDataSource dds,
+    		String cmd, HttpServletRequest req, DazzleResponse resp)
+        throws IOException, DataSourceException, ServletException, DazzleException{
+    	if("interaction".equals(cmd)) {
+        	interactionCommand(req, resp, dds);
+        }
+    }
+    
+   /**
+    * 
+    * @param req Servlet request
+    * @param resp Servlet resonse
+    * @param dds Dazzle data source to be used 
+    * @throws IOException
+    * @throws DataSourceException
+    * @throws ServletException
+    * @throws DazzleException
+    */
+    private void interactionCommand(HttpServletRequest req, DazzleResponse resp, DazzleDataSource dds)
+	    throws IOException, DataSourceException, ServletException, DazzleException {
+    	String[] queryInteractors = null;
+    	String[] tmpQueryDetails = null;
+    	String[] tmpQueryOperation = null;
+    	String[][] queryDetails = null;
+    	
+    	Map<String,Interactor> interactors = new HashMap<String,Interactor>();  //map for all interactors
+    	InteractionReferenceSource irs = (InteractionReferenceSource) dds; // convert the datasource to an interaction source
+    	
+    	String queryOperation = "INTERSECTION"; // if no operation parameter is used we will use the intersection
+    	// first get all parameters from the servlet request
+    	// start with the mandaroty interactor
+    	try{
+    		queryInteractors = req.getParameterValues("interactor") ;
+    	} catch (Exception e){
+    		throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS, "No interaction partners specified for interaction command");
+    	}
+    	// if no interactor was specified (actually wouldn't happen because dazzle would fail before)
+        if (queryInteractors != null && queryInteractors.length == 0) {
+            throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS, "No interaction partners specified for interaction command");
+        }
+        
+    	// now try optional details
+    	try{
+    		tmpQueryDetails = req.getParameterValues("detail") ;
+    	}catch(Exception e){
+    		// can be left out
+    	}
+    	
+    	// and try the optional operation parameter. 
+    	try{
+    		tmpQueryOperation = req.getParameterValues("operation") ;
+    	}catch(Exception e){
+    		//if none is provided, we will stick with the intersection
+       	}
+    	
+    	
+    	// process the detail parameters, i.e., extract property value combinations
+    	// details can have the form detail=property:aproperty or detail=property:aproperty,value:avalue
+    	if (tmpQueryDetails!= null){
+    		List<String[]> details = new ArrayList<String[]>();
+    		// iterate over all details
+    		for (int i = 0; i < tmpQueryDetails.length; i++){
+    			// split property and value part that is separated by a comma
+    			String[] bigParts = tmpQueryDetails[i].split(",");
+    			String[] props = null;
+    			String[] vals = null;
+    			String[] detail = new String[2];
+    			// split the property part
+    			props = bigParts[0].split(":");
+    			if (props.length > 1 && props[1] != null && props[0].equalsIgnoreCase("property")){
+    				detail[0] = props[1];
+    			}
+    			// some problem with the detail property, e.g. a missing sepeartor, try the next one
+				// TODO alternatively throw DazzleException
+    			else{
+    				continue;
+    			}
+    			// a specific value has been assigned to the property, extract it as well
+    			if (bigParts.length > 1 && bigParts[1] != null){
+    				vals = bigParts[1].split(":");
+    				if (vals.length > 1 && vals[1] != null && vals[0].equalsIgnoreCase("value")){
+    					detail[1] = vals[1];
+    					for (int g = 2; g < vals.length; g++ ){
+    						detail[1] += ":"+vals[g];
+    					}
+    				}
+    			}
+    			details.add(detail); 
+    		}
+    		// convert our temporary detail list into an array
+    		Iterator<String[]> it = details.iterator();
+    		queryDetails = new String[details.size()][2];
+    		int i = 0;
+    		while (it.hasNext()){
+    			queryDetails[i]= it.next();
+    			//System.out.println("Detail: " + queryDetails[i][0] + queryDetails[i][1]);
+    			i++;
+    		}
+    		// if there have only been faulty detail parameters, use none 
+    		// TODO alternatively throw a DazzleException
+    		if (i == 0){
+    			queryDetails = null;
+    		}
+    	} // end of detail parsing stuff ...
+    	
+    	
+    	// set the operation, default is intersection
+    	if (tmpQueryOperation != null){
+    		if (tmpQueryOperation[0].equalsIgnoreCase("union") || tmpQueryOperation[0].equalsIgnoreCase("and")){
+    			queryOperation = "UNION";
+    		}else if (tmpQueryOperation[0].equalsIgnoreCase("intersection") || tmpQueryOperation[0].equalsIgnoreCase("or")){
+    			queryOperation = "INTERSECTION";
+    		}
+    	} 
+    	
+    	// now request the intercations with our given parameters from the data source
+        List<Interaction> interactionResults = new ArrayList<Interaction>();
+        try {
+            Interaction[] interactions = irs.getInteractions(queryInteractors, queryDetails, queryOperation);
+            // if there are any interactions
+            if (interactions != null){
+            	// for each interaction add the interaction and store the particiapting interactors
+            	for (int j = 0; j < interactions.length; j++) {
+	           		Interaction interaction = interactions[j];
+	           		interactionResults.add(interaction);
+	           		for (Iterator<Participant> partIt = interaction.getParticipants().iterator(); partIt.hasNext();){
+	           			// needed to print all the interactors at teh beginning of the xml
+	           			Interactor inter = partIt.next().getInteractor();
+	           			interactors.put(inter.hashify(), inter); 
+	           		}
+	          	}
+            }
+           
+        }catch (NoSuchElementException ex) {
+        	throw new DazzleException(DASStatus.STATUS_BAD_REFERENCE, ex);
+        }
+
+
+        // start the response xml, currently without stylesheet support
+        XMLWriter xw = resp.startDasXML(false);
+        try {
+        	xw.openTag("DASINT");
+        	xw.attribute("xmlns", SCHEMA_LOC);
+            xw.attribute("xmlns:xsi", XSI);
+            xw.attribute("xsi:schemaLocation", SCHEMA_LOC+".xsd");
+        	
+            // TODO do some better error handling and tell teh user, why there are no results
+            if (interactionResults.size() < 1){
+            
+            }else{
+            	// firstly print all the interactors 
+            	for (Iterator<String> interactorIt = interactors.keySet().iterator(); interactorIt.hasNext();){
+            		String hashKey = (String) interactorIt.next();
+            		Interactor interactor = (Interactor)interactors.get(hashKey);
+            		xw.openTag("INTERACTOR");
+                  	xw.attribute("intId", hashKey);
+                	xw.attribute("shortLabel", interactor.getName());
+                	xw.attribute("dbSource", interactor.getDbSource());
+                	if (interactor.getDbSourceCvId().trim().length() > 0){
+                		xw.attribute("dbSourceCvId", interactor.getDbSourceCvId());
+                	}
+                	xw.attribute("dbVersion", interactor.getDbVersion());
+                	xw.attribute("dbAccessionId", interactor.getDbAccessionId());
+                	xw.attribute("dbCoordSys", interactor.getDbCoordSys());
+
+                	// then write all all the interactor details
+                	writeDetails(xw, interactor.getDetails().iterator());
+                	xw.closeTag("INTERACTOR");
+            	}
+            	
+            	// new print all the interactions 
+            	for (Iterator<Interaction> i = interactionResults.iterator(); i.hasNext(); ) {
+            		Interaction interaction = (Interaction) i.next();
+	                xw.openTag("INTERACTION");
+	                xw.attribute("name", interaction.getName());
+	                xw.attribute("dbSource", interaction.getDbSource());
+	                if (interaction.getDbSourceCvId() != null){
+	                	xw.attribute("dbSourceCvId", interaction.getDbSourceCvId());
+	                }
+	                xw.attribute("dbVersion", interaction.getDbVersion());
+	                xw.attribute("dbAccessionId", interaction.getDbAccessionId());
+	                // add the interaction details  	  
+	                writeDetails(xw, interaction.getDetails().iterator());
+	                
+	                // and add the participants
+	                List<Participant> participants = interaction.getParticipants();
+	                for (Iterator<Participant> j = participants.iterator(); j.hasNext();) {
+	                	Participant participant = (Participant)j.next();
+	                	xw.openTag("PARTICIPANT");
+	                	xw.attribute("intId", participant.getInteractor().hashify());
+	                	// write details for participants
+	                  	writeDetails(xw,participant.getDetails().iterator());
+	                  	xw.closeTag("PARTICIPANT");
+	                }
+	                xw.closeTag("INTERACTION");
+	            }
+            }
+            xw.closeTag("DASINT");
+            xw.close(); // thats it
+        } catch (Exception ex) {
+            throw new DazzleException(ex, "Error writing interaction document");
+        }
+    }
+    
+    
+    /**
+     * Writs all the details contained in the iterator to the passed xml writer. 
+     * @param xw xml output stream writer for interaction respnse
+     * @param it Iterator over details, can belong to interactions, interactors, or participants
+     * @throws IOException
+     */
+    private void writeDetails(XMLWriter xw, Iterator<Detail> it) throws IOException{
+    	while(it.hasNext()){
+        	Detail detail = (Detail) it.next();
+        	xw.openTag("DETAIL");
+        	xw.attribute("property", detail.getProperty());
+        	if(detail.getPropertyCvId().trim().length() > 0){
+        		xw.attribute("propertyCvId", detail.getPropertyCvId());
+        	}
+        	xw.attribute("value", detail.getValue());
+        	if (detail.getValueCvId().trim().length() > 0){
+        		xw.attribute("valueCvId", detail.getValueCvId());
+        	}
+        	// if ther detail has a range assigned to it, print it as well
+        	if (detail.getRange() != null){
+        		Range range = detail.getRange();
+        		xw.openTag("RANGE");
+        		xw.attribute("start", String.valueOf(range.getStart()));
+        		if (range.getStartStatus().trim().length() > 0){
+        			xw.attribute("startStatus", range.getStartStatus());
+        		}
+        		if (range.getStartStatusCvId().trim().length() > 0){
+        			xw.attribute("startStatusCvId", range.getStartStatusCvId());
+        		}
+        		xw.attribute("end", String.valueOf(range.getEnd()));
+        		if (range.getEndStatus().trim().length() > 0){
+        			xw.attribute("endStatus", range.getEndStatus());
+        		}
+        		if (range.getEndStatusCvId().trim().length() > 0){
+        			xw.attribute("endStatusCvId", range.getEndStatusCvId());
+        		}
+        		xw.closeTag("RANGE");
+        	}
+        	xw.closeTag("DETAIL");
+        }
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/LinkHandler.java b/src/org/biojava/servlets/dazzle/LinkHandler.java
new file mode 100644
index 0000000..b8f00e7
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/LinkHandler.java
@@ -0,0 +1,79 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+
+
+import org.biojava.servlets.dazzle.datasource.*;
+
+/**
+ * Handler which implements the DAS link command.
+ *
+ * @author Thomas Down
+ * @since 1.1
+ */
+
+public class LinkHandler extends  AbstractDazzleHandler {
+    public LinkHandler() {
+        super(
+            DazzleDataSource.class,
+            new String[] {"link"},
+            new String[] {"link/1.0"}
+        );
+    }
+    
+    public void run(
+        DazzleServlet dazzle, 
+        DazzleDataSource dds,
+        String cmd,
+        HttpServletRequest req,
+        DazzleResponse resp
+    )
+        throws IOException, DataSourceException, ServletException, DazzleException
+    {
+        String field = req.getParameter("field");
+        String id = req.getParameter("id");
+        if (field == null || id == null) {
+            throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS, "Missing parameter");
+        }
+        
+        try {
+            boolean response = dds.doLink(req, resp, field, id);
+            if (! response) {
+                resp.setHeader("X-DAS-Status", "200");
+                resp.setContentType("text/html");
+                PrintWriter pw = resp.getWriter();
+                pw.println("<h1>No extra information about this object</h1><p>field: " + field + "<br />id: " + id + "</p>");
+                pw.close();
+            }
+        } catch (NoSuchElementException ex) {
+            throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS, "Link failed");
+        } catch (DataSourceException ex) {
+            throw new DazzleException(DASStatus.STATUS_SERVER_ERROR, ex);
+        }
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/SangerProxyFilter.java b/src/org/biojava/servlets/dazzle/SangerProxyFilter.java
new file mode 100644
index 0000000..db60637
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/SangerProxyFilter.java
@@ -0,0 +1,116 @@
+
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * @author Thomas Down
+ *
+ */
+package org.biojava.servlets.dazzle;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.io.IOException;
+
+/**
+ * Filter object for use at the sanger that rewrites inbound HTTP requests with modified dasroot
+ *  Typical usage is in situations where a back-end
+ * servlet container is running behind an HTTP proxy, but the servlets need
+ * to know their externally-visible root dir rather than the name of the
+ * internal servlet-running root dir.
+ *
+ * @author Jonathan Warren
+ */
+public class SangerProxyFilter implements Filter {
+    private String proxydasroot;
+    private String realdasroot;
+    
+    
+    public void init(FilterConfig config) 
+        throws ServletException
+    {
+        String pr = config.getInitParameter("proxy-das-root");
+        String rr=config.getInitParameter("real-das-root");
+       // String p = config.getInitParameter("proxy-port");
+        //System.out.println("initiating filter jw");
+        if (pr == null) {
+            throw new ServletException("Must specify proxy-das-root");
+        }
+        if (rr == null) {
+            throw new ServletException("Must specify real-das-root");
+        }
+        
+        proxydasroot = pr;
+        realdasroot=rr;
+        
+    }
+    
+    public void destroy() {
+    }
+    
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
+        throws IOException, ServletException
+    {
+        if (request instanceof HttpServletRequest) {
+        	//System.out.println("filtering jw");
+            request = new HttpServletRequestWrapper((HttpServletRequest) request) {
+            	
+            	public String getPathInfo() {
+					//System.out.println(" ServletFilter: the parent pathInfo is: " + super.getPathInfo());
+					//if ( path == null )
+						return super.getPathInfo();
+					//else 
+						//return path;
+				}
+
+				public String getRequestURI() {
+					//System.out.println(" ServletFilter: getRequestURI " + super.getRequestURI());
+					return super.getRequestURI();
+				}
+
+            	
+
+				public StringBuffer getRequestURL() {
+					//System.out.println(" ServletFilter: getRequestURL " + super.getRequestURL());
+					//todo modify requested url with the one specified by host here
+					StringBuffer originalURL=super.getRequestURL();
+					//get original
+					//replace real-das-root with the proxy-das-root dir 
+					//ie at the sanger the proxy accepts requests as /das/ but we have dazzle running behind running under dastest
+					// to seperate it from an old das dazzle installation running old ensembl das sources (Thomas Downs)
+					//but we want links to have the das root directory in web pages so users can get back through the proxy as requests with
+					// /dastest/ in them will not get through proxy. So we need to kid our servlets into thinking they are running under /das/ as root 
+					//System.out.println("real-das-root="+realdasroot);
+					//System.out.println("proxy-das-root="+proxydasroot);
+					
+					//replace realdasroot with proxydasroot
+					//System.out.println("originalURL="+originalURL);
+					String url=originalURL.toString();
+					String newUrl=url.replaceFirst(realdasroot, proxydasroot);
+					StringBuffer newURL=new StringBuffer();
+					newURL.append(newUrl);
+					//System.out.println("new url="+newURL.toString());
+					return newURL;
+					//return super.getRequestURL();
+				
+				}
+            } ;
+        }
+        chain.doFilter(request, response);
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/Segment.java b/src/org/biojava/servlets/dazzle/Segment.java
new file mode 100644
index 0000000..05a2c1f
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/Segment.java
@@ -0,0 +1,106 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+/**
+ * Memento for a segment in a DAS request.
+ *
+ * @author Thomas Down
+ * @since 0.90
+ */
+
+public class Segment {
+    private String ref;
+    private int start;
+    private int stop;
+    
+    public Segment(String ref) {
+        this.ref = ref;
+        this.start = Integer.MIN_VALUE;
+        this.stop = Integer.MAX_VALUE;
+    }
+    
+    public Segment(String ref, int start, int stop) {
+        this.ref = ref;
+        this.start = start;
+        this.stop = stop;
+    }
+    
+    public boolean isBounded() {
+        return (start != Integer.MIN_VALUE);
+    }
+    
+    public boolean isInverted() {
+        return (start > stop);
+    }
+    
+    public String getReference() {
+        return ref;
+    }
+    
+    public int getStart() {
+        return start;
+    }
+    
+    public int getStop() {
+        return stop;
+    }
+    
+    public int getMin() {
+        return Math.min(start, stop);
+    }
+    
+    public int getMax() {
+        return Math.max(start, stop);
+    }
+    
+    public static Segment fromString(String seg)
+    		throws IllegalArgumentException
+    {
+        try {
+	        StringTokenizer toke = new StringTokenizer(seg, ":,");
+	        String newRef = toke.nextToken();
+	        if (toke.hasMoreTokens()) {
+	            String starts = toke.nextToken();
+	            String stops = toke.nextToken();
+	            return new Segment(newRef, Integer.parseInt(starts), Integer.parseInt(stops));
+	        } else {
+	            return new Segment(newRef);
+	        }
+        } catch (NumberFormatException ex) {
+            throw new IllegalArgumentException("Invalid coordinate: " + ex.getMessage());
+        } catch (NoSuchElementException ex) {
+            throw new IllegalArgumentException("Not a valid segment: " + seg);
+        }
+    }
+    
+    public String toString() {
+        if (isBounded()) {
+            return ref + ':' + start + ',' + stop;
+        } else {
+            return ref;
+        }
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/SequenceHandler.java b/src/org/biojava/servlets/dazzle/SequenceHandler.java
new file mode 100644
index 0000000..d80ede2
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/SequenceHandler.java
@@ -0,0 +1,244 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import java.util.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.biojava.bio.seq.*;
+import org.biojava.bio.symbol.*;
+import org.biojava.utils.xml.*;
+import org.biojava.servlets.dazzle.datasource.*;
+
+/**
+ * Handler which implements the DAS sequence and dna commands.
+ */
+
+public class SequenceHandler extends AbstractDazzleHandler {
+    public SequenceHandler() {
+        super(
+            DazzleReferenceSource.class,
+            new String[] {"sequence", "dna"},
+            new String[] {"sequence/1.0", "dna/1.0"}
+        );
+    }
+    
+    public void run(
+        DazzleServlet dazzle,
+        DazzleDataSource dds,
+        String cmd,
+        HttpServletRequest req,
+        DazzleResponse resp
+    )
+        throws IOException, DataSourceException, ServletException, DazzleException
+    {
+        if("dna".equals(cmd)) {
+            dnaCommand(req, resp, dds);
+        } else {
+            sequenceCommand(req, resp, dds);
+        }
+    }
+    
+    private void dnaCommand(
+        HttpServletRequest req,
+        DazzleResponse resp,
+        DazzleDataSource dds
+    )
+	    throws IOException, DataSourceException, ServletException, DazzleException
+    {
+
+        DazzleReferenceSource drs = (DazzleReferenceSource) dds;
+        
+        List segments = DazzleTools.getSegments(dds, req, resp);
+        if (segments.size() == 0) {
+            throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS, "No segments specified for dna command");
+        }
+        
+        // Fetch and validate the requests.
+        
+        Map segmentResults = new HashMap();
+        for (Iterator i = segments.iterator(); i.hasNext(); ) {
+            Segment seg = (Segment) i.next();
+            
+            try {
+                Sequence seq = drs.getSequence(seg.getReference());
+                if (seq.getAlphabet() != DNATools.getDNA()) {
+                    throw new DazzleException(DASStatus.STATUS_SERVER_ERROR, "Sequence " + seg.toString() + " is not in the DNA alphabet");
+                }
+                if (seg.isBounded()) {
+                    if (seg.getMin() < 1 || seg.getMax() > seq.length()) {
+                        throw new DazzleException(DASStatus.STATUS_BAD_COORDS, "Segment " + seg.toString() + " doesn't fit sequence of length " + seq.length());
+                    }
+                }
+                segmentResults.put(seg, seq);
+            } catch (NoSuchElementException ex) {
+                throw new DazzleException(DASStatus.STATUS_BAD_REFERENCE, ex);
+            } catch (DataSourceException ex) {
+                throw new DazzleException(DASStatus.STATUS_SERVER_ERROR, ex);
+            }
+        }
+        
+        //
+        // Looks okay -- generate the response document
+        //
+        
+        
+        XMLWriter xw = resp.startDasXML("DASDNA", "dasdna.dtd");
+        
+        try {
+            xw.openTag("DASDNA");
+            for (Iterator i = segmentResults.entrySet().iterator(); i.hasNext(); ) {
+                Map.Entry me = (Map.Entry) i.next();
+                Segment seg = (Segment) me.getKey();
+                Sequence seq = (Sequence) me.getValue();
+                
+                xw.openTag("SEQUENCE");
+                xw.attribute("id", seg.getReference());
+                xw.attribute("version", drs.getLandmarkVersion(seg.getReference()));
+                if (seg.isBounded()) {
+                    xw.attribute("start", "" + seg.getStart());
+                    xw.attribute("stop", "" + seg.getStop());
+                } else {
+                    xw.attribute("start", "" + 1);
+                    xw.attribute("stop", "" + seq.length());
+                }
+                
+                SymbolList syms = seq;
+                if (seg.isBounded()) {
+                    syms = syms.subList(seg.getMin(), seg.getMax());
+                }
+                if (seg.isInverted()) {
+                    syms = DNATools.reverseComplement(syms);
+                }
+                
+                xw.openTag("DNA");
+                xw.attribute("length", "" + syms.length());
+                
+                for (int pos = 1; pos <= syms.length(); pos += 60) {
+                    int maxPos = Math.min(syms.length(), pos + 59);
+                    xw.println(syms.subStr(pos, maxPos));
+                }
+                
+                xw.closeTag("DNA");
+                xw.closeTag("SEQUENCE");
+            }
+            xw.closeTag("DASDNA");
+            xw.close();
+        } catch (Exception ex) {
+            throw new DazzleException(ex, "Error writing DNA document");
+        }
+    }
+
+    //
+    // Sequence command
+    //
+
+    private void sequenceCommand(HttpServletRequest req,
+			                     DazzleResponse resp,
+                                 DazzleDataSource dds)
+	    throws IOException, ServletException, DataSourceException, DazzleException
+    {
+        DazzleReferenceSource drs = (DazzleReferenceSource) dds;
+        
+        List segments = DazzleTools.getSegments(dds, req, resp);
+        if (segments.size() == 0) {
+            throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS, "No segments specified for sequence command");
+        }
+        
+        // Fetch and validate the requests.
+        
+        Map segmentResults = new HashMap();
+        for (Iterator i = segments.iterator(); i.hasNext(); ) {
+            Segment seg = (Segment) i.next();
+            
+            try {
+                Sequence seq = drs.getSequence(seg.getReference());
+                if (seg.isBounded()) {
+                    if (seg.getMin() < 1 || seg.getMax() > seq.length()) {
+                        throw new DazzleException(DASStatus.STATUS_BAD_COORDS, "Segment " + seg.toString() + " doesn't fit sequence of length " + seq.length());
+                    }
+                }
+                segmentResults.put(seg, seq);
+            } catch (NoSuchElementException ex) {
+                throw new DazzleException(DASStatus.STATUS_BAD_REFERENCE, ex);
+            } catch (DataSourceException ex) {
+                throw new DazzleException(DASStatus.STATUS_SERVER_ERROR, ex);
+            }
+        }
+        
+        //
+        // Looks okay -- generate the response document
+        //
+        
+        XMLWriter xw = resp.startDasXML("DASSEQUENCE", "dassequence.dtd");
+        
+        try {
+            xw.openTag("DASSEQUENCE");
+            for (Iterator i = segmentResults.entrySet().iterator(); i.hasNext(); ) {
+                Map.Entry me = (Map.Entry) i.next();
+                Segment seg = (Segment) me.getKey();
+                Sequence seq = (Sequence) me.getValue();
+                
+                xw.openTag("SEQUENCE");
+                xw.attribute("id", seg.getReference());
+                xw.attribute("version", drs.getLandmarkVersion(seg.getReference()));
+                if (seg.isBounded()) {
+                    xw.attribute("start", "" + seg.getStart());
+                    xw.attribute("stop", "" + seg.getStop());
+                } else {
+                    xw.attribute("start", "" + 1);
+                    xw.attribute("stop", "" + seq.length());
+                }
+                String molType = seq.getAlphabet().getName();
+                if (seq.getAlphabet() == DNATools.getDNA()) {
+                    molType = "DNA";
+                } else if (seq.getAlphabet() == RNATools.getRNA()) {
+                    molType = "ssRNA";
+                } else if (seq.getAlphabet() == ProteinTools.getAlphabet() || seq.getAlphabet() == ProteinTools.getTAlphabet()) {
+                    molType = "Protein";
+                }
+                xw.attribute("moltype", molType);
+                
+                SymbolList syms = seq;
+                if (seg.isBounded()) {
+                    syms = syms.subList(seg.getMin(), seg.getMax());
+                }
+                if (seg.isInverted()) {
+                    syms = DNATools.reverseComplement(syms);
+                }
+                
+                for (int pos = 1; pos <= syms.length(); pos += 60) {
+                    int maxPos = Math.min(syms.length(), pos + 59);
+                    xw.println(syms.subStr(pos, maxPos));
+                }
+                xw.closeTag("SEQUENCE");
+            }
+            xw.closeTag("DASSEQUENCE");
+            xw.close();
+        } catch (Exception ex) {
+            throw new DazzleException(ex, "Error writing DNA document");
+        }
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/StructureHandler.java b/src/org/biojava/servlets/dazzle/StructureHandler.java
new file mode 100644
index 0000000..8da155b
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/StructureHandler.java
@@ -0,0 +1,403 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.biojava.utils.xml.*;
+import org.biojava.servlets.dazzle.datasource.*;
+import org.biojava.bio.structure.io.StructureIO;
+import org.biojava.bio.structure.io.FileConvert;
+import org.biojava.bio.structure.*;
+
+
+/**
+ * Handler which implements the DAS STRUCTURE command.
+ *
+ *
+ * structures can be stored as
+ *  - PDB files
+ *  - XML files
+ *  - in a local database 
+ *  - etc.
+ * we need an interface to this io
+ * configure in dazzlecfg.xml WHICH one to use...
+ *
+ * @author Andreas Prlic
+ */
+
+public class StructureHandler extends AbstractDazzleHandler {
+
+	public StructureHandler() {
+		super(
+				DazzleReferenceSource.class,
+				new String[] {"structure"},
+				new String[] {"structure/1.0"}
+		);
+	}
+	public void run(
+			DazzleServlet dazzle,
+			DazzleDataSource dds,
+			String cmd,
+			HttpServletRequest req,
+			DazzleResponse resp
+	)
+	throws IOException, DataSourceException, ServletException, DazzleException
+	{
+
+		StructureSource stru_dds = (StructureSource)dds;
+
+		// get Structure data from StructureInterface.
+		// which pdb reader to use can be defined in dazzlecfg.xml
+
+		// pdbIo is initiated in StructureSource, which knows where to get data from
+		// here we just care to get the structure ...
+		//System.out.println("get pdbio"+getTimeStamp());
+		StructureIO pdbio = stru_dds.getPdbIo() ;
+
+		try {
+			
+			String queries[] = req.getParameterValues("query") ;
+			String modelnr   = req.getParameter("model");
+			String chains[]  = req.getParameterValues("chain");
+			String ranges[]  = req.getParameterValues("range");
+
+			boolean responseStarted = false;
+			XMLWriter xw = null;
+			
+			if (queries == null){
+				throw new DazzleException(DASStatus.STATUS_BAD_COMMAND_ARGUMENTS,"did not provide the mandatory argument >query<");
+			}
+			
+			for (int i = 0; i<queries.length;i++) {
+				String query=queries[i];
+
+				Structure pdb = null ;
+				boolean problem = false;
+
+				try {
+					pdb = pdbio.getStructureById(query);
+
+				} catch ( Exception e) {
+					// could not get structure
+					throw new DazzleException(DASStatus.STATUS_SERVER_ERROR,e.getMessage());
+				}
+
+				if ( pdb == null ) {
+					throw new DazzleException(DASStatus.STATUS_BAD_REFERENCE,"no PDB file found for query " + query);
+				}
+
+				if ( problem ){
+					throw new DazzleException(DASStatus.STATUS_SERVER_ERROR);
+
+				}
+							
+				// if requested, return just one model...
+				if ( modelnr != null) 
+					pdb = getStructureForModel(pdb,modelnr);                   
+
+
+				if (( chains != null) && (chains.length >=1 ) )                
+					pdb = getStructureForChains(pdb, chains);
+
+
+				if ( (ranges != null) && ( ranges.length >= 1))                 
+					pdb =  getStructureForRanges(pdb,ranges);
+
+				if (pdb == null) {   
+					throw new DazzleException(DASStatus.STATUS_SERVER_ERROR);
+					
+				}
+
+
+				// check for existing PDB code, if none exists, set to query...
+				String idCode = pdb.getPDBCode();
+				if ( idCode == null)
+					pdb.setPDBCode(query);
+
+				
+				if ( ! responseStarted ){					
+//					 do not show the stylesheet currently
+					xw = resp.startDasXML(false) ;
+
+					String strudtd = "http://www.efamily.org.uk/xml/das/2004/06/17/dasstructure.xsd" ;
+
+					xw.openTag("dasstructure");
+
+					xw.attribute("xmlns",strudtd);
+					xw.attribute("xmlns:data","http://www.efamily.org.uk/xml/data/2004/06/17/dataTypes.xsd");
+					xw.attribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
+					xw.attribute("xsi:schemaLocation",strudtd + " " + strudtd);
+
+					responseStarted = true;
+				}
+				
+				
+
+				FileConvert conv = new FileConvert(pdb);
+				try {
+					conv.toDASStructure(xw);
+				} catch (Exception e) {
+
+					e.printStackTrace();
+					problem = true;
+
+				}                
+			}
+
+
+			xw.closeTag("dasstructure");
+			xw.close();
+
+			pdbio = null;
+
+		}
+		catch (IOException e) {
+			e.printStackTrace();
+			throw new DazzleException("Error creating Structure document");
+			
+
+		}               
+	}    
+
+	private Structure getStructureForModel(Structure pdb, String modelnr){
+
+		Structure npdb = new StructureImpl();
+
+		try {
+			int m = Integer.parseInt(modelnr) ;
+			//System.out.println("requested model nr " + m);
+			if ( m == 0 ) { m=1;}
+			List model = pdb.getModel(m-1);
+			Map h = pdb.getHeader();
+
+			npdb.setHeader(h);
+			npdb.addModel(model);
+			npdb.setNmr(pdb.isNmr());
+			npdb.setPDBCode(pdb.getPDBCode());
+			npdb.setName(pdb.getName());
+			npdb.setConnections(pdb.getConnections());
+
+
+		} catch (Exception e) {
+			// most likely user requested non existing model,
+			// return the whole structure
+			e.printStackTrace();
+
+			return pdb;
+		}
+
+		return npdb;
+
+	}
+
+	private Structure getStructureForChains(Structure pdb, String[] chains){
+
+		Structure npdb = new StructureImpl();
+		npdb.setHeader(pdb.getHeader());
+		npdb.setPDBCode(pdb.getPDBCode());
+		npdb.setName(pdb.getName());
+
+		if ( chains == null)
+			return pdb;
+
+		for (int c=0; c < chains.length;c++){
+			try {
+				Chain ch= pdb.getChainByPDB(chains[c]);
+				npdb.addChain(ch);
+			} catch (StructureException e){
+				// the user requested a non -existing chain. ignore
+			}
+		}
+
+		return npdb;
+	}
+
+
+	private Structure getStructureForRanges(Structure complete, String[] ranges){
+
+		Structure npdb = new StructureImpl();
+		npdb.setHeader(complete.getHeader());
+		npdb.setPDBCode(complete.getPDBCode());
+		npdb.setName(complete.getName());
+
+		List rangesLst = new ArrayList(); 
+		for ( int r=0;r<ranges.length;r++){
+			// split the ranges up into bits and get the correpsonding coords
+			String range = ranges[r];
+			//System.out.println("range" + range);
+			String[] spl = range.split(":");
+			if (spl.length != 2)
+				continue;
+			RangeRequest rstart = new RangeRequest(spl[0]);
+			RangeRequest rend   = new RangeRequest(spl[1]);
+			Map m = new HashMap();
+			m.put("start",rstart);
+			m.put("end",rend);
+			rangesLst.add(m);
+
+		}
+
+
+		boolean start = false;
+		boolean first = true;
+		boolean foundSomething = false;
+		String oldchain = "";
+		GroupIterator iter = new GroupIterator(complete);
+		Chain newChain = new ChainImpl();
+
+		// go over all groups and see if they are in one of the ranges ...
+		// if yes add them to the new structure ...
+		while(iter.hasNext()){
+			Group g = (Group)iter.next();
+			Chain curr = iter.getCurrentChain();
+			String chainId = curr.getName();
+			//System.out.println(start + " " + chainId + " " +  g);
+
+			if ( ! start) {
+				Iterator riter = rangesLst.iterator();
+				while (riter.hasNext()){
+					Map m = (Map)riter.next();
+					RangeRequest rstart = (RangeRequest) m.get("start");
+
+					String pdbStart = rstart.getPosition()+rstart.getInsertionCode();
+
+					String startId  = rstart.getChainId();                    
+					//System.out.println(start + " " + startId + " " + chainId + " " + pdbStart + " " + g.getPDBCode());
+					if ( chainId.equals(startId) && g.getPDBCode().equals(pdbStart)){
+						start = true;
+						foundSomething = true;
+						break;
+					}
+				}
+			}
+
+			if ( start) {
+				if (! (chainId.equals(oldchain)) ){
+					if (! first)
+						npdb.addChain(newChain);
+					// we found a new chain.
+					newChain = new ChainImpl();
+					newChain.setName(chainId);
+				}
+				first =false;
+				newChain.addGroup(g);
+			}
+
+			if ( start) {
+				Iterator riter = rangesLst.iterator();
+				while (riter.hasNext()){
+					Map m = (Map) riter.next();
+					//RangeRequest rstart = (RangeRequest) m.get("start");
+					RangeRequest rend   = (RangeRequest) m.get("end");
+
+					String pdbEnd   = rend.getPosition()+rend.getInsertionCode();           
+					String endId    = rend.getChainId();
+
+					//System.out.println(start + " >" + endId + "< >" + chainId + "< " + pdbEnd + " " + g.getPDBCode() + " " + rend.getInsertionCode());
+					if ( chainId.equals(endId) && g.getPDBCode().equals(pdbEnd)){ 
+						start = false;
+						newChain.setName(endId);
+						break;
+					}
+				}
+			}
+
+			oldchain = chainId ;
+
+		}
+		
+		// the current chain has not been added, yet ...
+		if ( foundSomething)
+			npdb.addChain(newChain);
+
+		return npdb;
+	}
+
+
+
+}
+
+class RangeRequest  {
+	int position;
+	String insertionCode;
+	String chainId;
+
+
+	public RangeRequest(String rangeStr){
+		super();
+		chainId = " ";
+		insertionCode = "";
+		position = -1;
+
+		int icPos = rangeStr.indexOf("_");
+		int chainPos = rangeStr.indexOf(".");
+		//System.out.println(chainPos);
+		try {
+			position = Integer.parseInt(rangeStr);
+		} catch (Exception e) {}
+
+		if ( chainPos > -1) {
+			if (chainPos+2 > rangeStr.length()) {
+				// user left chainId empty ...
+				chainId = " ";
+			}
+			else
+				chainId  = rangeStr.substring(chainPos+1,chainPos+2);
+
+			try {
+				//System.out.println(rangeStr.substring(0,chainPos));
+				position = Integer.parseInt(rangeStr.substring(0,chainPos));
+			} catch (Exception e) { // there can be still an insertion code...
+			}
+		}
+
+		if (icPos > -1) {
+			insertionCode = rangeStr.substring(icPos+1,icPos+2);
+			position = Integer.parseInt(rangeStr.substring(0,icPos));
+		}
+
+		//System.out.println(toString());
+
+	}
+
+	public String toString() {
+		String txt = position + " >"+insertionCode+"< >" + chainId +"<";
+		return txt;
+	}
+	public int getPosition(){
+		return position;
+	}
+	public String getInsertionCode(){
+		return insertionCode;
+	}
+	public String getChainId(){
+		return chainId;
+	}
+
+}
+
+
+
diff --git a/src/org/biojava/servlets/dazzle/StylesheetHandler.java b/src/org/biojava/servlets/dazzle/StylesheetHandler.java
new file mode 100644
index 0000000..407e4b4
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/StylesheetHandler.java
@@ -0,0 +1,75 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle;
+
+import java.io.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.biojava.servlets.dazzle.datasource.*;
+
+/**
+ * Handler which implements the DAS stylesheet command.
+ */
+
+public class StylesheetHandler extends AbstractDazzleHandler {
+    public StylesheetHandler() {
+        super(
+            DazzleDataSource.class,
+            new String[] {"stylesheet"},
+            new String[] {"stylesheet/1.0"}
+        );
+    }
+    
+    public void run(
+        DazzleServlet dazzle,
+        DazzleDataSource dds,
+        String cmd,
+        HttpServletRequest req,
+        DazzleResponse resp
+    )
+        throws IOException, DataSourceException, ServletException, DazzleException
+    {
+        String stylesheetPath = dds.getStylesheet();
+        InputStream styleSheet = null;
+        
+        if (stylesheetPath == null) {
+            stylesheetPath = DazzleServlet.DEFAULT_STYLESHEET;
+        }
+        styleSheet = dazzle.getServletContext().getResourceAsStream(stylesheetPath);
+        if (styleSheet == null) {
+            throw new DazzleException(DASStatus.STATUS_BAD_STYLESHEET, "Couldn't find stylesheet");
+        }   
+        
+        resp.setDasStatus(DASStatus.STATUS_OKAY);
+        resp.setContentType(DazzleServlet.XML_CONTENT_TYPE);
+        resp.setHeader("Content-Encoding", "plain");
+        OutputStream os = resp.getOutputStream();
+        byte[] buffer = new byte[256];
+        int bufMax = 0;
+        while (bufMax >= 0) {
+            bufMax = styleSheet.read(buffer);
+            if (bufMax > 0)
+                os.write(buffer, 0, bufMax);
+        }
+        os.flush();
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/AbstractBiojavaFeatureSource.java b/src/org/biojava/servlets/dazzle/datasource/AbstractBiojavaFeatureSource.java
new file mode 100644
index 0000000..8685ccd
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/AbstractBiojavaFeatureSource.java
@@ -0,0 +1,362 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import javax.servlet.*;
+import java.util.*;
+import java.io.*;
+import org.biojava.bio.seq.*;
+import org.biojava.bio.symbol.*;
+import org.biojava.utils.xml.*;
+
+/**
+ * Abstract DazzleDataSource implementation which provides default implementations
+ * for many methods.  This is a useful starting point for writing many
+ * data source implementations.
+ *
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+public abstract class AbstractBiojavaFeatureSource 
+    extends    AbstractDazzleDataSource
+    implements BiojavaFeatureSource 
+
+
+{
+    private ServletContext context;
+    /**
+     * Basic implementation of the <code>init</code> method, which just records
+     * the ServletContext.  Subclasses will normally want to provide their
+     * own init method, but this should be chained onto <code>super.init</code>
+     * so that the <code>log</code> and <code>getServletContext</code> methods
+     * work correctly.
+     */
+    
+    public void init(ServletContext ctx)
+        throws DataSourceException
+    {
+        this.context = ctx;
+    }
+    
+    
+    /**
+     * Return the <code>ServletContext</code> which was attached when this datasource
+     * was initialized.
+     */
+    
+    public ServletContext getServletContext() {
+        return context;
+    }
+
+
+    /**
+     * Log a message via the attached ServletContext.
+     */
+    
+    public void log(String msg) {
+        getServletContext().log(msg);
+    }
+    
+    /**
+     * Log a message and exception via the attached ServletContext.
+     */
+    
+    public void log(String msg, Throwable t) {
+        getServletContext().log(msg, t);
+    }
+      
+    /**
+     * Get the specified sequence.  This is used by the AbstractDataSource <code>getFeatures</code>,
+     * <code>getLandmarkLength</code>, and <code>getFeaturesByID</code>
+     * methods, and is a required part of the interface for DazzleReferenceSources.
+     */
+    
+    public abstract Sequence getSequence(String ref)
+        throws DataSourceException, NoSuchElementException;
+    
+    /**
+     * Return all the features on the requested sequence
+     */
+
+    public FeatureHolder getFeatures(String ref)
+        throws DataSourceException, NoSuchElementException
+    {
+        return getSequence(ref);
+    }
+
+    /**
+     * Return the length of the requested sequence
+     */
+
+    public int getLandmarkLength(String ref)
+        throws DataSourceException, NoSuchElementException
+    {
+        Sequence seq = getSequence(ref);
+        if (seq != null) {
+            return seq.length();
+        } else {
+            return -1;
+        }
+    }
+
+    
+
+    /**
+     * Default implementation which returns an autogenerated ID.  This
+     * takes the form __dazzle__<type>_<refseq>_<start>_<stop&gt.
+     * This method should be overriden whereever possible, but it provides a useful
+     * fallback for features which don't have a natural ID.
+     */
+    
+    public String getFeatureID(Feature f) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("__dazzle__");
+        sb.append(pack(f.getType()));
+        sb.append('_');
+        sb.append(pack(f.getSequence().getName()));
+        sb.append('_');
+        sb.append(f.getLocation().getMin());
+        sb.append('_');
+        sb.append(f.getLocation().getMax());
+        return sb.toString();
+    }
+    
+    private String pack(String s) {
+        if (s.indexOf('_') < 0) {
+            return s;
+        } else {
+            StringBuffer sb = new StringBuffer();
+            for (int i = 0; i < s.length(); ++i) {
+                char c = s.charAt(i);
+                if (c != '_') {
+                    sb.append(c);
+                } else {
+                    sb.append("__");
+                }
+            }
+            return sb.toString();
+        }
+    }
+     
+    /**
+     * Default implementation which returns null
+     */
+     
+    public String getFeatureLabel(Feature f) {
+        return getFeatureID(f);
+    }
+
+    /**
+     * Default implementation which returns null
+     */
+    
+    public String getScore(Feature f) {
+        return null;
+    }
+
+    /**
+     * Default implementation which returns the empty map
+     */
+    
+    public Map getLinkouts(Feature f) {
+        return Collections.EMPTY_MAP;
+    }
+
+   
+    /**
+     * Default implementation does nothing
+     */
+    
+    public void writeXFFDetails(XMLWriter xw, Feature f)
+        throws IOException
+    {
+    }
+
+    /**
+     * Default implementation which returns COUNT_CALCULATE
+     */
+
+    public int countFeatures(
+        String reference,
+		String type
+    )
+	    throws DataSourceException, NoSuchElementException
+    {
+        return COUNT_CALCULATE;
+    }
+
+    /**
+     * Default implementation which returns COUNT_CALCULATE
+     */
+
+    public int countFeatures(String reference,
+			     int start,
+			     int end,
+			     String type)
+        throws DataSourceException, NoSuchElementException
+    {
+        return COUNT_CALCULATE;
+    }
+
+    /**
+     * Default implementation which groups by BioJava feature hierarchy.  If the
+     * parent is a FEATURE instance it defines a group, otherwise no groups are
+     * provided.
+     */
+        
+    public List getGroups(Feature f) {
+        FeatureHolder parent = f.getParent();
+        if (parent instanceof Feature) {
+            Feature fParent = (Feature) parent;
+            return Collections.singletonList(
+                new DASGFFGroup(
+                    getFeatureID(f),
+                    f.getType(),
+                    getFeatureLabel(f),
+                    getLinkouts(f)
+                )
+            );
+        }
+                    
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Default implementation which returns <code>false</code>. for all features
+     */
+    
+    public boolean getShatterFeature(Feature f) {
+        return false;
+    }
+    
+    /**
+     * Default implementation which returns the ReadingFrame of FramedFeatures, otherwise <code>null</code>.
+     */
+     
+    public FramedFeature.ReadingFrame getPhase(Feature f) {
+        if (f instanceof FramedFeature) {
+            return ((FramedFeature) f).getReadingFrame();
+        }
+        return null;
+    }
+    
+    /**
+     * Default implementation which returns the empty list
+     */
+    
+    public List getFeatureNotes(Feature f) {
+        return Collections.EMPTY_LIST;
+    }
+    
+    /**
+     * Decodes IDs generated by the defauld getFeatureID method.  Implementations
+     * which provide proper features IDs should definitely override this.
+     */
+    
+    public FeatureHolder getFeaturesByID(String id, MatchType matchType)
+        throws DataSourceException
+    {
+        log("Decoding id " + id);
+        if (id.startsWith("__dazzle__")) {
+            try {
+                String did = id.substring(10);
+            
+                String type = null;
+                String seq = null;
+            
+                int pos = 0;
+                while (type == null) {
+                    pos = did.indexOf('_', pos);
+                    if (did.charAt(pos + 1) != '_' || did.charAt(pos + 2) == '_') {
+                        type = unpack(did.substring(0, pos));
+                        pos = pos + 1;
+                    } else {
+                        pos = pos + 2;
+                    }
+                }
+                int pos2 = pos;
+                while (seq == null) {
+                    pos2 = did.indexOf('_', pos2);
+                    if (did.charAt(pos + 1) != '_' || did.charAt(pos + 2) == '_') {
+                        seq = unpack(did.substring(pos, pos2));
+                        pos2 = pos2 + 1;
+                    } else {
+                        pos2 = pos2 + 2;
+                    }
+                }
+                int upos = did.indexOf('_', pos2);
+                int start = Integer.parseInt(did.substring(pos2, upos));
+                int end = Integer.parseInt(did.substring(upos + 1));
+                
+                log("Decoded.  type=" + type + "   seq=" + seq + "     start=" + start);
+                
+                FeatureHolder posFeatures = getFeatures(seq);
+                return posFeatures.filter(
+                    new FeatureFilter.And(
+                        new FeatureFilter.ByType(type),
+                        new FeatureFilter.ContainedByLocation(
+                            new RangeLocation(start, end)
+                        )
+                    )
+                );
+            } catch (DataSourceException ex) {
+                throw ex;
+            } catch (Exception ex) {
+                log("Error fetching ID " + id, ex);
+                return FeatureHolder.EMPTY_FEATURE_HOLDER;
+            }
+        } else {
+            return FeatureHolder.EMPTY_FEATURE_HOLDER;
+        }
+    }
+    
+    private String unpack(String s) {
+        if (s.indexOf('_') < 0) {
+            return s;
+        } else {
+            StringBuffer sb = new StringBuffer();
+            boolean escaped = false;
+            for (int i = 0; i < s.length(); ++i) {
+                char c = s.charAt(i);
+                if (c == '_' && !escaped) {
+                    escaped = true;
+                } else {
+                    sb.append(c);
+                    escaped = false;
+                }
+            }
+            return sb.toString();
+        }
+    }
+    
+    /**
+     * Default implementation which returns the empty set.
+     */
+    
+    public FeatureHolder getFeaturesByGroup(String id, MatchType matchType)
+        throws DataSourceException
+    {
+        return FeatureHolder.EMPTY_FEATURE_HOLDER;
+    }
+}
+
diff --git a/src/org/biojava/servlets/dazzle/datasource/AbstractDataSource.java b/src/org/biojava/servlets/dazzle/datasource/AbstractDataSource.java
new file mode 100644
index 0000000..c458ed8
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/AbstractDataSource.java
@@ -0,0 +1,366 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import javax.servlet.*;
+import java.util.*;
+import java.io.*;
+import org.biojava.bio.seq.*;
+import org.biojava.bio.symbol.*;
+import org.biojava.utils.xml.*;
+
+/**
+ * Abstract DazzleDataSource implementation which provides default implementations
+ * for many methods.  This is a useful starting point for writing many
+ * data source implementations.
+ *
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+public abstract class AbstractDataSource 
+    extends    AbstractDazzleDataSource
+    implements BiojavaFeatureSource 
+
+
+{
+    private ServletContext context;
+    /**
+     * Basic implementation of the <code>init</code> method, which just records
+     * the ServletContext.  Subclasses will normally want to provide their
+     * own init method, but this should be chained onto <code>super.init</code>
+     * so that the <code>log</code> and <code>getServletContext</code> methods
+     * work correctly.
+     */
+    
+    public void init(ServletContext ctx)
+        throws DataSourceException
+    {
+        this.context = ctx;
+    }
+    
+    
+    /**
+     * Return the <code>ServletContext</code> which was attached when this datasource
+     * was initialized.
+     */
+    
+    public ServletContext getServletContext() {
+        return context;
+    }
+
+
+    /**
+     * Log a message via the attached ServletContext.
+     */
+    
+    public void log(String msg) {
+        getServletContext().log(msg);
+    }
+    
+    /**
+     * Log a message and exception via the attached ServletContext.
+     */
+    
+    public void log(String msg, Throwable t) {
+        getServletContext().log(msg, t);
+    }
+      
+    /**
+     * Get the specified sequence.  This is used by the AbstractDataSource <code>getFeatures</code>,
+     * <code>getLandmarkLength</code>, and <code>getFeaturesByID</code>
+     * methods, and is a required part of the interface for DazzleReferenceSources.
+     */
+    
+    public abstract Sequence getSequence(String ref)
+        throws DataSourceException, NoSuchElementException;
+    
+    /**
+     * Return all the features on the requested sequence
+     */
+
+    public FeatureHolder getFeatures(String ref)
+        throws DataSourceException, NoSuchElementException
+    {
+        return getSequence(ref);
+    }
+
+    /**
+     * Return the length of the requested sequence
+     */
+
+    public int getLandmarkLength(String ref)
+        throws DataSourceException, NoSuchElementException
+    {
+        Sequence seq = getSequence(ref);
+        if (seq != null) {
+            return seq.length();
+        } else {
+            return -1;
+        }
+    }
+
+    
+
+    /**
+     * Default implementation which returns an autogenerated ID.  This
+     * takes the form __dazzle__<type>_<refseq>_<start>_<stop&gt.
+     * This method should be overriden whereever possible, but it provides a useful
+     * fallback for features which don't have a natural ID.
+     */
+    
+    public String getFeatureID(Feature f) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("__dazzle__");
+        sb.append(pack(f.getType()));
+        sb.append('_');
+        sb.append(pack(f.getSequence().getName()));
+        sb.append('_');
+        sb.append(f.getLocation().getMin());
+        sb.append('_');
+        sb.append(f.getLocation().getMax());
+        return sb.toString();
+    }
+    
+    private String pack(String s) {
+    	if (s == null) {
+    		s = "null";
+    	}
+    	
+        if (s.indexOf('_') < 0) {
+            return s;
+        } else {
+            StringBuffer sb = new StringBuffer();
+            for (int i = 0; i < s.length(); ++i) {
+                char c = s.charAt(i);
+                if (c != '_') {
+                    sb.append(c);
+                } else {
+                    sb.append("__");
+                }
+            }
+            return sb.toString();
+        }
+    }
+     
+    /**
+     * Default implementation which returns null
+     */
+     
+    public String getFeatureLabel(Feature f) {
+        return getFeatureID(f);
+    }
+
+    /**
+     * Default implementation which returns null
+     */
+    
+    public String getScore(Feature f) {
+        return null;
+    }
+
+    /**
+     * Default implementation which returns the empty map
+     */
+    
+    public Map getLinkouts(Feature f) {
+        return Collections.EMPTY_MAP;
+    }
+
+   
+    /**
+     * Default implementation does nothing
+     */
+    
+    public void writeXFFDetails(XMLWriter xw, Feature f)
+        throws IOException
+    {
+    }
+
+    /**
+     * Default implementation which returns COUNT_CALCULATE
+     */
+
+    public int countFeatures(
+        String reference,
+		String type
+    )
+	    throws DataSourceException, NoSuchElementException
+    {
+        return COUNT_CALCULATE;
+    }
+
+    /**
+     * Default implementation which returns COUNT_CALCULATE
+     */
+
+    public int countFeatures(String reference,
+			     int start,
+			     int end,
+			     String type)
+        throws DataSourceException, NoSuchElementException
+    {
+        return COUNT_CALCULATE;
+    }
+
+    /**
+     * Default implementation which groups by BioJava feature hierarchy.  If the
+     * parent is a FEATURE instance it defines a group, otherwise no groups are
+     * provided.
+     */
+        
+    public List getGroups(Feature f) {
+        FeatureHolder parent = f.getParent();
+        if (parent instanceof Feature) {
+            Feature fParent = (Feature) parent;
+            return Collections.singletonList(
+                new DASGFFGroup(
+                    getFeatureID(fParent),
+                    fParent.getType(),
+                    getFeatureLabel(fParent),
+                    getLinkouts(fParent)
+                )
+            );
+        }
+                    
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Default implementation which returns <code>false</code>. for all features
+     */
+    
+    public boolean getShatterFeature(Feature f) {
+        return false;
+    }
+    
+    /**
+     * Default implementation which returns the ReadingFrame of FramedFeatures, otherwise <code>null</code>.
+     */
+     
+    public FramedFeature.ReadingFrame getPhase(Feature f) {
+        if (f instanceof FramedFeature) {
+            return ((FramedFeature) f).getReadingFrame();
+        }
+        return null;
+    }
+    
+    /**
+     * Default implementation which returns the empty list
+     */
+    
+    public List getFeatureNotes(Feature f) {
+        return Collections.EMPTY_LIST;
+    }
+    
+    /**
+     * Decodes IDs generated by the defauld getFeatureID method.  Implementations
+     * which provide proper features IDs should definitely override this.
+     */
+    
+    public FeatureHolder getFeaturesByID(String id, MatchType matchType)
+        throws DataSourceException
+    {
+        log("Decoding id " + id);
+        if (id.startsWith("__dazzle__")) {
+            try {
+                String did = id.substring(10);
+            
+                String type = null;
+                String seq = null;
+            
+                int pos = 0;
+                while (type == null) {
+                    pos = did.indexOf('_', pos);
+                    if (did.charAt(pos + 1) != '_' || did.charAt(pos + 2) == '_') {
+                        type = unpack(did.substring(0, pos));
+                        pos = pos + 1;
+                    } else {
+                        pos = pos + 2;
+                    }
+                }
+                int pos2 = pos;
+                while (seq == null) {
+                    pos2 = did.indexOf('_', pos2);
+                    if (did.charAt(pos + 1) != '_' || did.charAt(pos + 2) == '_') {
+                        seq = unpack(did.substring(pos, pos2));
+                        pos2 = pos2 + 1;
+                    } else {
+                        pos2 = pos2 + 2;
+                    }
+                }
+                int upos = did.indexOf('_', pos2);
+                int start = Integer.parseInt(did.substring(pos2, upos));
+                int end = Integer.parseInt(did.substring(upos + 1));
+                
+                log("Decoded.  type=" + type + "   seq=" + seq + "     start=" + start);
+                
+                FeatureHolder posFeatures = getFeatures(seq);
+                return posFeatures.filter(
+                    new FeatureFilter.And(
+                        new FeatureFilter.ByType(type),
+                        new FeatureFilter.ContainedByLocation(
+                            new RangeLocation(start, end)
+                        )
+                    )
+                );
+            } catch (DataSourceException ex) {
+                throw ex;
+            } catch (Exception ex) {
+                log("Error fetching ID " + id, ex);
+                return FeatureHolder.EMPTY_FEATURE_HOLDER;
+            }
+        } else {
+            return FeatureHolder.EMPTY_FEATURE_HOLDER;
+        }
+    }
+    
+    private String unpack(String s) {
+        if (s.indexOf('_') < 0) {
+            return s;
+        } else {
+            StringBuffer sb = new StringBuffer();
+            boolean escaped = false;
+            for (int i = 0; i < s.length(); ++i) {
+                char c = s.charAt(i);
+                if (c == '_' && !escaped) {
+                    escaped = true;
+                } else {
+                    sb.append(c);
+                    escaped = false;
+                }
+            }
+            return sb.toString();
+        }
+    }
+    
+    /**
+     * Default implementation which returns the empty set.
+     */
+    
+    public FeatureHolder getFeaturesByGroup(String id, MatchType matchType)
+        throws DataSourceException
+    {
+        return FeatureHolder.EMPTY_FEATURE_HOLDER;
+    }
+}
+
diff --git a/src/org/biojava/servlets/dazzle/datasource/AbstractDazzleDataSource.java b/src/org/biojava/servlets/dazzle/datasource/AbstractDazzleDataSource.java
new file mode 100644
index 0000000..95ed745
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/AbstractDazzleDataSource.java
@@ -0,0 +1,136 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.*;
+
+
+/**
+ * Abstract DazzleDataSource implementation which provides default implementations
+ * for many methods.  This is a useful starting point for writing many
+ * data source implementations.
+ *
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+public abstract class AbstractDazzleDataSource 
+    implements DazzleDataSource    
+{
+    
+    private String name;
+    private String description;
+    private String version;
+    private String stylesheet;
+  
+    
+   
+    /**
+     * Default destroy method does nothing.
+     */
+    
+    public void destroy() {
+    }
+    
+    
+    /**
+     * Set the datasource's name string
+     */
+    
+    public void setName(String s) {
+        this.name = s;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    /**
+     * Set the datasource's description string
+     */
+    
+    public void setDescription(String s) {
+        this.description = s;
+    }
+    
+    public String getDescription() {
+        return description;
+    }
+    
+    /**
+     * Set the datasource's version string
+     */
+    
+    public void setVersion(String s) {
+        this.version = s;
+    }
+    
+    public String getVersion() {
+        return version;
+    }
+    
+    /**
+     * Set the datasource's name stylesheet path
+     */
+    
+    public void setStylesheet(String s) {
+        this.stylesheet = s;
+    }
+
+    public String getStylesheet() {
+        return stylesheet;
+    }
+    
+  
+
+   
+
+    /**
+     * Return a description string for a given type.  May be null (indicating
+     * that the description is the same as the type ID).
+     */
+
+    public String getTypeDescription(String type) {
+        return type;
+    }
+
+   
+  
+    /**
+     * Default implementation does nothing and returns <code>false</code>.
+     */
+    
+    public boolean doLink(HttpServletRequest req,
+		       HttpServletResponse resp,
+		       String field,
+		       String id)
+	    throws ServletException, IOException, DataSourceException, NoSuchElementException
+    {
+        return false;
+    }
+
+
+}
+
diff --git a/src/org/biojava/servlets/dazzle/datasource/AbstractGFFFeatureSource.java b/src/org/biojava/servlets/dazzle/datasource/AbstractGFFFeatureSource.java
new file mode 100644
index 0000000..72697b0
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/AbstractGFFFeatureSource.java
@@ -0,0 +1,273 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 28.10.2004
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.*;
+
+
+
+/** an abstract class to provide a SimpleFeatureSource. Users have to
+ * implement the getFeatures method.*/
+
+public abstract class AbstractGFFFeatureSource 
+    extends AbstractDazzleDataSource implements GFFFeatureSource
+   
+{ 
+    private String name;
+    private String description;
+    private String version;
+    private String stylesheet;
+    private ServletContext context;
+    
+    /**
+     * Basic implementation of the <code>init</code> method, which just records
+     * the ServletContext.  Subclasses will normally want to provide their
+     * own init method, but this should be chained onto <code>super.init</code>
+     * so that the <code>log</code> and <code>getServletContext</code> methods
+     * work correctly.
+     */
+    
+    public void init(ServletContext ctx)
+        throws DataSourceException
+    {
+        this.context = ctx;
+    }
+    
+
+    /** get all features for a given regference
+     * @param ref an identifier describing the reference of the
+     * features, eg. a sequence identifier or a protein structure
+     * @return a list of Feature objects
+    */
+    
+    public GFFFeature[] getFeatures(String ref) 
+	throws DataSourceException
+    {
+	// do something
+	return null ;
+    }
+
+    /**
+	 * Default implementation which returns an autogenerated ID.  This
+	 * takes the form __dazzle__<type>_<refseq>_<start>_<stop&gt.
+	 * This method should be overriden whereever possible, but it provides a useful
+	 * fallback for features which don't have a natural ID.
+	 * @param f the feature
+	 * @return returns the name of the faeture
+	 */
+
+	public String getFeatureID(GFFFeature f) {
+		//return f.getName() ;
+		
+
+        StringBuffer sb = new StringBuffer();
+        sb.append("__dazzle__");
+        sb.append(pack(f.getType()));
+        sb.append('_');
+        sb.append(pack(f.getName()));
+        sb.append('_');
+        sb.append(f.getStart());
+        sb.append('_');
+        sb.append(f.getEnd());
+        return sb.toString();
+		 
+	}
+	
+
+	private String pack(String s) {
+		if (s.indexOf('_') < 0) {
+			return s;
+		} else {
+			StringBuffer sb = new StringBuffer();
+			for (int i = 0; i < s.length(); ++i) {
+				char c = s.charAt(i);
+				if (c != '_') {
+					sb.append(c);
+				} else {
+					sb.append("__");
+				}
+			}
+			return sb.toString();
+		}
+	}
+	
+    
+
+    
+    /**
+     * Return the <code>ServletContext</code> which was attached when this datasource
+     * was initialized.
+     */
+    
+    public ServletContext getServletContext() {
+        return context;
+    }
+
+
+    /**
+     * Log a message via the attached ServletContext.
+     */
+    
+    public void log(String msg) {
+        getServletContext().log(msg);
+    }
+    
+    /**
+     * Log a message and exception via the attached ServletContext.
+     */
+    
+    public void log(String msg, Throwable t) {
+        getServletContext().log(msg, t);
+    }
+      
+    
+    /**
+     * Default destroy method does nothing.
+     */
+    
+    public void destroy() {
+    }
+    
+    
+    /**
+     * Set the datasource's name string
+     */
+    
+    public void setName(String s) {
+        this.name = s;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    /**
+     * Set the datasource's description string
+     */
+    
+    public void setDescription(String s) {
+        this.description = s;
+    }
+    
+    public String getDescription() {
+        return description;
+    }
+    
+    /**
+     * Set the datasource's version string
+     */
+    
+    public void setVersion(String s) {
+        this.version = s;
+    }
+    
+    public String getVersion() {
+        return version;
+    }
+    
+    /**
+     * Set the datasource's name stylesheet path
+     */
+    
+    public void setStylesheet(String s) {
+        this.stylesheet = s;
+    }
+
+    public String getStylesheet() {
+        return stylesheet;
+    }
+    
+    public String getDataSourceVersion(){
+	return version ;
+    }
+
+    public String getDataSourceType(){
+	return name ;
+    }
+
+
+    /**
+     * Return the set of all type IDs served by this datasource.  This is used
+     * by the no-args version of the <code>types</code> DAS command.
+     */
+    public Set getAllTypes(){
+	return null ;
+    }
+
+    /**
+     * Return the length of the requested sequence
+     */
+
+    public int getLandmarkLength(String ref)
+        throws DataSourceException, NoSuchElementException
+    {
+	return -1 ;
+    }
+
+    public String getLandmarkVersion(String ref)
+        throws DataSourceException, NoSuchElementException 
+    {
+	return "" ;
+	
+    }
+
+
+    public String getMapMaster() {
+	return "" ;
+    }
+    
+    
+
+
+    /**
+     * Return a description string for a given type.  May be null (indicating
+     * that the description is the same as the type ID).
+     */
+
+    public String getTypeDescription(String type) {
+        return type;
+    }
+
+   
+  
+    /**
+     * Default implementation does nothing and returns <code>false</code>.
+     */
+    
+    public boolean doLink(HttpServletRequest req,
+		       HttpServletResponse resp,
+		       String field,
+		       String id)
+	    throws ServletException, IOException, DataSourceException, NoSuchElementException
+    {
+        return false;
+    }
+
+  
+
+
+}
+
diff --git a/src/org/biojava/servlets/dazzle/datasource/AlignmentSource.java b/src/org/biojava/servlets/dazzle/datasource/AlignmentSource.java
new file mode 100644
index 0000000..e845f86
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/AlignmentSource.java
@@ -0,0 +1,82 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 10.5.2004
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+//import java.util.*;
+//import java.io.*;
+//import java.lang.String.* ;
+
+//import javax.servlet.*;
+//import javax.servlet.http.*;
+
+//import org.biojava.utils.xml.*;
+
+//import org.biojava.bio.structure.io.*;
+import org.biojava.bio.program.das.dasalignment.* ;
+
+
+
+/** 
+ * Interface for Alignment sources
+ * called by  AlignmentHandler 
+ *
+ * @author Andreas Prlic
+ * @version 1.01
+ */
+
+public interface  AlignmentSource extends DazzleDataSource {
+    
+    /** get alignments for a query (can be several) only the ID of the
+     * query is mandatory, all other arguments are optional and can be
+     * null.  This also depends on the type of data the alignment
+     * source is providing.  e.g. for a UniProt PDB alignment source
+     * the typical entry would be query=1a4a. It would return a list
+     * of all alignments against UniProt sequences. Since we do not
+     * know in advance against this PDB code is aligned the subject is
+     * null and the two coordinate systems also are set to null.
+     * 
+     * @param query (mandatory) the ID of the query e.g. 22 for
+     * chromosome 22
+     * @param queryCoordSys (optional, can be null) the coordinate
+     * system of the query.  e.g. human26 for assembly 26 of human
+     * @param subject (optional, can be null) the ID of the
+     * subject. e.g. 3 for chromosome 3
+     * @param subjectCoordSys (optional,can be null) the coordinate
+     * system of the subject.  e.g. mouse 20 for assembly 20 of mouse.
+     *
+     *
+ */
+    public Alignment[] getAlignments(String query,
+				     String queryCoordSys,
+				     String subject,
+				     String subjectCoordSys)  
+	throws DataSourceException       ;
+
+     
+    /** get and set the Alignment Type - is part of the XML response */
+    public  void        setAlignmentType(String aliType);
+
+    /** get and set the Alignment Type - is part of the XML response */
+    public  String      getAlignmentType();
+
+ }
diff --git a/src/org/biojava/servlets/dazzle/datasource/AlignmentTools.java b/src/org/biojava/servlets/dazzle/datasource/AlignmentTools.java
new file mode 100644
index 0000000..f667ff4
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/AlignmentTools.java
@@ -0,0 +1,126 @@
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+import org.biojava.bio.Annotation;
+import org.biojava.bio.program.das.dasalignment.Alignment;
+import org.biojava.bio.program.das.dasalignment.DASException;
+import org.biojava.bio.program.ssbind.AnnotationFactory;
+import org.biojava.bio.structure.Atom;
+import org.biojava.bio.structure.jama.Matrix;
+
+/** a class that helps in creating Alignment objects
+ * 
+ * @author Andreas Prlic 
+ *
+ */
+public class AlignmentTools {
+	
+	/** add a new object to an alignment
+	 * 
+	 * @param ali the alignment to which the new object should be attached to
+	 * @param accessionCode
+	 * @param intObjectId
+	 * @param objectVersion
+	 * @param type
+	 * @param dbSource
+	 * @param dbVersion
+	 * @param dbCoordSys
+	 * @param details a list of detail annotation as created with getObjectDetails. Can be null or size 0.
+	 * @throws DASException
+	 */
+	public static void addObject(Alignment ali,
+						String accessionCode, 
+						String intObjectId, 
+						String objectVersion, 
+						String type, 
+						String dbSource, 
+						String dbVersion, 
+						String dbCoordSys,
+						List details)
+	throws DASException{
+		
+		HashMap info = new HashMap();
+		info.put("dbAccessionId",accessionCode);
+		info.put("intObjectId",intObjectId);
+		info.put("objectVersion",objectVersion);
+		info.put("type", type);
+		info.put("dbSource", dbSource);
+		info.put("dbVersion", dbVersion);
+		info.put("dbCoordSys", dbCoordSys);
+		
+		if ( details != null) {
+			if ( details.size() > 0 ){
+				info.put("details",details);
+			}
+		}
+		
+		Annotation anno = AnnotationFactory.makeAnnotation(info);
+		
+		ali.addObject(anno);
+		
+	}
+	
+	/** returns an annotation representing an object detail -
+	 * as can be attached to the addObject calls
+	 * @param property
+	 * @param dbSource
+	 * @param detail
+	 * @return
+	 */
+	public static Annotation getObjectDetails(String property, String dbSource, String detail){
+		
+		Map m = new HashMap();
+		m.put("property", property);
+		m.put("dbSource",dbSource);
+		m.put("detail",detail);
+		Annotation anno = AnnotationFactory.makeAnnotation(m);
+		return anno;
+		
+	}
+	
+	
+	/** add a shift vector to an alignment
+	 * 
+	 * @param ali
+	 * @param intObjectId
+	 * @param atom
+	 * @throws DASException
+	 */
+	 public static void addVector(Alignment ali, String intObjectId, Atom atom) 
+	 throws DASException {
+	        Map anno = new HashMap();
+	        anno.put("intObjectId",intObjectId);	        
+	        anno.put("vector",atom);
+	        Annotation a = AnnotationFactory.makeAnnotation(anno);
+	        ali.addVector(a);
+	    }
+
+	
+	/** add a Matrix to an object
+	 * 
+	 * @param ali
+	 * @param ac
+	 * @param matrix
+	 * @throws DASException
+	 */
+	public static void addMatrix(Alignment ali, String intObjectId, Matrix matrix)
+	throws DASException{
+        Map anno = new HashMap();
+        anno.put("intObjectId",intObjectId);
+
+        for (int x=0;x<3;x++){
+            for (int y=0;y<3;y++){
+                String key = "mat"+(x+1)+(y+1);
+                anno.put(key,matrix.get(x,y)+"");
+            }
+        }
+        Annotation a = AnnotationFactory.makeAnnotation(anno);
+        ali.addMatrix(a);
+    }
+
+	
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/BasicDazzleInstallation.java b/src/org/biojava/servlets/dazzle/datasource/BasicDazzleInstallation.java
new file mode 100644
index 0000000..e8cb2f9
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/BasicDazzleInstallation.java
@@ -0,0 +1,321 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.io.*;
+import java.util.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.biojava.utils.xml.*;
+import org.w3c.dom.*;
+import org.xml.sax.*;
+import javax.xml.parsers.*;
+
+/**
+ * General purpose DAS server installation gateway.  Provides a flat
+ * namespace containing an arbitrary set of datasources configured
+ * via an XMLBeans file.
+ *
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+public class BasicDazzleInstallation implements DazzleInstallation {
+	
+	public static final String CONFIG_FILE = "/dazzlecfg.xml";
+	
+	private class DataSourceHolder {
+		private final Element config;
+		private final String id;
+		private DazzleDataSource source;
+		
+		public DataSourceHolder(String id, Element config) {
+			this.id = id;
+			this.config = config;
+		}
+		
+		public String getID() {
+			return id;
+		}
+		
+		public Element getConfigXML() {
+			return config;
+		}
+		
+		public synchronized DazzleDataSource getDataSource() 
+		throws DataSourceException
+		{
+			if (source == null) {
+				source = initDataSource(config, id);
+			}
+			return source;
+		}
+		
+		public synchronized void destroy() {
+			if (source != null) {
+				source.destroy();
+				source = null;
+			}
+		}
+	}
+	
+	private ServletContext ctx;
+	
+	private Map<String,DataSourceHolder> dataSources;
+	private Map<String,String> aliases;
+	private Map<String,Gate> gates;
+	
+	{
+		dataSources = new HashMap<String, DataSourceHolder>();
+		aliases = new HashMap<String, String>();
+		gates = new HashMap<String, Gate>();
+	}
+	
+	private void parseConfigFile(InputSource is)
+	throws DataSourceException
+	{
+		try {
+			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+			Element cfgDoc = parser.parse(is).getDocumentElement();
+			
+			Node chld = cfgDoc.getFirstChild();
+			while (chld != null) {
+				if (chld instanceof Element) {
+					Element echld = (Element) chld;
+					if (echld.getTagName().equals("datasource")) {
+						// System.out.println("Found a datasource");
+						String id = echld.getAttribute("id");
+						if (id == null) {
+							throw new ServletException("Datasource has no ID attribute");
+						}
+						
+						dataSources.put(id, new DataSourceHolder(id, echld));
+					} else if (echld.getTagName().equals("resource")) {
+						String id = echld.getAttribute("id");
+						Object o = initResource(echld, id);
+						ctx.setAttribute(id, o);
+					} else if (echld.getTagName().equals("alias")) {
+						String id = echld.getAttribute("id");
+						if (id == null || id.length() == 0) {
+							throw new ServletException("Alias has no ID attribute");
+						}
+						String target = echld.getAttribute("target");
+						if (target == null || target.length() == 0) {
+							throw new ServletException("Alias " + id + " has no target attribute");
+						}
+						
+						aliases.put(id, target);
+					} else if (echld.getTagName().equals("ipgate")) {
+						String id = echld.getAttribute("target");
+						if (id == null || id.length() == 0) {
+							throw new ServletException("ipgate has no `target' attribute");
+						}
+						Gate g = parseGate(echld);
+						
+						StringTokenizer toke = new StringTokenizer(id, ", ");
+						while (toke.hasMoreTokens()) {
+							gates.put(toke.nextToken(), g);
+						}
+					} else if (echld.getTagName().equals("include")) {
+						String href = echld.getAttribute("href");
+						if (href == null || href.length() == 0) {
+							throw new ServletException("include has no `href' attribute");
+						}
+						InputSource is2 = new InputSource(ctx.getResourceAsStream(href));
+						parseConfigFile(is2);
+					}
+				}
+				chld = chld.getNextSibling();
+			}
+		} catch (IOException ex) {
+			throw new DataSourceException(ex, "Couldn't load DAS config");
+		} catch (SAXException ex) {
+			throw new DataSourceException(ex, "Couldn't parse DAS config");
+		} catch (Throwable t) {
+			throw new DataSourceException(t);
+		}
+	}
+	
+	public void init(ServletConfig conf)
+	throws DataSourceException
+	{
+		this.ctx = conf.getServletContext();
+		InputSource is = new InputSource(ctx.getResourceAsStream(CONFIG_FILE));
+		parseConfigFile(is);
+	}
+	
+	public void destroy() {
+		for (Iterator dsi = dataSources.values().iterator(); dsi.hasNext(); ) {
+		   
+		   Object o = dsi.next();
+		   
+		   if ( o instanceof DazzleDataSource) {
+		   
+		      DazzleDataSource dds = (DazzleDataSource) o;
+		      System.out.println("destroying  DazzleDataSource" + dds.getName());
+		      dds.destroy();
+		   } else if ( o instanceof DataSourceHolder ) {
+		      System.out.println("destroying DataSourceHolder ");
+		      DataSourceHolder holder = (DataSourceHolder) o;
+		      holder.destroy();
+		   }
+		}
+	}
+	
+	private Gate parseGate(Element el)
+	throws ServletException
+	{
+		Gate g = new Gate();
+		Node chld = el.getFirstChild();
+		while (chld != null) {
+			if (chld instanceof Element) {
+				Element echld = (Element) chld;
+				if (echld.getTagName().equals("accept")) {
+					String addr = echld.getAttribute("address");
+					if (addr == null || addr.length() == 0) {
+						throw new ServletException("ipgate.accept has no `address' attribute");
+					}
+					g.addAddress(addr);
+				}
+			}
+			chld = chld.getNextSibling();
+		}
+		return g;
+	}
+	
+	private DazzleDataSource initDataSource(Element e, String id) 
+	throws DataSourceException
+	{
+		
+		try {
+			// check if DataSource has a no arguments constructor			
+			
+			DazzleDataSource dds = (DazzleDataSource) XMLBeans.INSTANCE.instantiateBean(
+					e,
+					getClass().getClassLoader(),
+					new HashMap()
+			);
+			dds.init(ctx);
+			return dds;
+		} catch (DataSourceException ex) {
+			throw ex;
+		} catch (AppException ex) {			
+			throw new DataSourceException(ex, "Couldn't instantiate datasource " + id + " ; failed at element " + e);
+		} catch (ClassCastException ex) {
+			throw new DataSourceException(ex, "Bean " + id + " is not a valid data source");
+		} catch (Throwable t) {
+			throw new DataSourceException(t);
+		}
+	}
+	
+	private Object initResource(Element e, String id)
+	throws DataSourceException
+	{
+		try {
+			Object o = XMLBeans.INSTANCE.instantiateBean(
+					e,
+					getClass().getClassLoader(),
+					new HashMap()
+			);
+			return o;
+		} catch (AppException ex) {
+			throw new DataSourceException("Couldn't instantiate datasource " + id + " ; failed at element " + e);
+		} catch (Throwable t) {
+			throw new DataSourceException(t);
+		}
+	}
+	
+	public DazzleDataSource getDataSource(List nameComponents, HttpServletRequest req)
+	throws DataSourceException
+	{
+		if (nameComponents.size() != 1) {
+			throw new DataSourceException("Basic installation only covers flat namespace of data-sources");
+		}
+		String id = (String) nameComponents.get(0);
+		Gate g = (Gate) gates.get(id);
+		if (g != null && !g.accept(req)) {
+			throw new DataSourceException("No such datasource " + id);
+		}
+		
+		String realID = id;
+		if (aliases.containsKey(id)) {
+			realID = (String) aliases.get(id);
+		}
+		
+		DataSourceHolder ddsh = (DataSourceHolder) dataSources.get(realID);
+		if (ddsh == null) {
+			throw new DataSourceException("No such datasource " + id);
+		} else {
+			try {
+				return ddsh.getDataSource();
+			} catch (DataSourceException ex) {
+				ctx.log("Couldn't initialize datasource " + realID, ex);
+				dataSources.remove(realID);
+				throw ex;
+			}
+		}
+	}
+	
+	public Set getDataSourceIDs(List nameComponents, HttpServletRequest req)
+	throws DataSourceException
+	{
+		// System.err.println("Address: " + req.getRemoteAddr());
+		// System.err.println("Host: " + req.getRemoteHost());
+		
+		if (nameComponents.size() != 0) {
+			throw new DataSourceException("Basic installation only covers flat namespace of data-sources");
+		}
+		
+		Set<String> _names = new HashSet<String>();
+		_names.addAll(dataSources.keySet());
+		_names.addAll(aliases.keySet());
+		
+		Set<String> names = new TreeSet<String>();
+		for (Iterator<String> i = _names.iterator(); i.hasNext(); ) {
+			String n =  i.next();
+			boolean accept = true;
+			Gate g = (Gate) gates.get(n);
+			if (g != null) {
+				accept = g.accept(req);
+			}
+			if (accept) {
+				names.add(n);
+			}
+		}
+		
+		return names;
+	}
+	
+	private class Gate {
+		private Set<String> addresses = new HashSet<String>();
+		
+		public void addAddress(String addr) {
+			addresses.add(addr);
+		}
+		
+		public boolean accept(HttpServletRequest req) {
+			return addresses.contains(req.getRemoteAddr());
+		}
+	}
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/BioSQLDataSource.java b/src/org/biojava/servlets/dazzle/datasource/BioSQLDataSource.java
new file mode 100644
index 0000000..341c7e2
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/BioSQLDataSource.java
@@ -0,0 +1,225 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.*;
+import java.net.*;
+
+
+import javax.servlet.*;
+import org.biojava.bio.*;
+import org.biojava.bio.seq.*;
+import org.biojava.bio.seq.db.*;
+import org.biojava.bio.seq.db.biosql.*;
+
+import org.biojava.bio.program.das.*;
+
+/**
+ * Annotation datasource backed by a BioSQL database
+ *
+ * @author Thomas Down, Benjamin Schuster-Boeckler
+ * @version 0.1
+ */
+
+public class BioSQLDataSource extends AbstractDataSource implements DazzleDataSource {
+    static {
+        try {
+            BioSQLDataSource.class.getClassLoader().loadClass("org.postgresql.Driver").newInstance();
+        } catch (Exception ex) {
+        }
+        try {
+            BioSQLDataSource.class.getClassLoader().loadClass("org.gjt.mm.mysql.Driver").newInstance();
+        } catch (Exception ex) {
+        }
+    }
+
+    private SequenceDBLite reference;
+
+    private String mapMaster;
+    private String stylesheet;
+
+    private String dbURL;
+    private String dbUser;
+    private String dbPass;
+    private String biodatabase;
+    private String driver;
+    
+    private BioSQLSequenceDB sdb;
+    private Set              allTypes;
+
+    public String getDataSourceType() {
+        return "biosql";
+    }
+    
+    public String getDataSourceVersion() {
+        return "0.1";
+    }
+    
+    public void setMapMaster(String s) {
+        this.mapMaster = s;
+    }
+    
+    public String getMapMaster() {
+        return mapMaster;
+    }
+
+    public void setDbURL(String s) {
+        dbURL = s;
+    }
+    
+    public void setDbUser(String s) {
+        dbUser = s;
+    }
+    
+    public void setDbPass(String s) {
+        dbPass = s;
+    }
+    
+    public void setBiodatabase(String s) {
+        biodatabase = s;
+    }
+    
+    private void setJDBCDriver(String s) {
+        driver = s;
+    }
+    
+    public void init(ServletContext ctx) 
+        throws DataSourceException
+    {
+        super.init(ctx);   
+        try {
+            reference = new DASSequenceDB(new URL(mapMaster)).allEntryPointsDB();
+            
+            sdb = new BioSQLSequenceDB(driver,
+            dbURL,
+            dbUser,
+            dbPass,
+            biodatabase,
+            false);
+            allTypes = new HashSet();
+            allTypes.add("GD_mRNA");
+            allTypes.add("GD_partial_mRNA");
+            allTypes.add("GD_ncRNA");
+            allTypes.add("Pseudogene");
+        } catch (Exception ex) {
+            throw new DataSourceException(ex, "Couldn't connect to BioSQL databse");
+        }
+    }
+    
+    public Sequence getSequence(String ref)
+        throws DataSourceException, NoSuchElementException
+    {
+        try {
+            try {
+                return sdb.getSequence(ref);
+            } catch (IllegalIDException ex) {
+                return reference.getSequence(ref);
+            }
+        } catch (IllegalIDException ex) {
+            throw new NoSuchElementException("Bad reference sequence: " + ref);
+        } catch (BioException ex) {
+            throw new DataSourceException(ex, "Error getting reference sequence");
+        } 
+    }
+
+
+    public String getLandmarkVersion(String ref) 
+	    throws DataSourceException, NoSuchElementException
+    {
+        Sequence seq = getSequence(ref);
+        try {
+            return seq.getAnnotation().getProperty(DASSequence.PROPERTY_SEQUENCEVERSION).toString();
+        } catch (NoSuchElementException ex) {
+            return "unknown";
+        }
+    }
+
+    public FeatureHolder getFeatures(String ref)
+	throws NoSuchElementException, DataSourceException
+    {
+        Sequence seq = getSequence(ref);
+        if (seq instanceof DASSequence) {
+            return FeatureHolder.EMPTY_FEATURE_HOLDER;
+        } else {
+            return seq;
+        }
+    }
+
+    public String getFeatureID(Feature f) {
+        Annotation anno = f.getAnnotation();
+        if (anno.containsProperty("id")) {
+            Object idProp = anno.getProperty("id");
+            if (idProp instanceof List) {
+                return ((List) idProp).get(0).toString();
+            } else {
+                return idProp.toString();
+            }
+        }
+        
+        return null;
+    }
+    
+
+    public Set getAllTypes() {
+        return Collections.unmodifiableSet(allTypes);
+    }
+
+    public void setStylesheet(String s) {
+	this.stylesheet = s;
+    }
+
+    public String getStylesheet() {
+	return stylesheet;
+    }
+
+    public Map getLinkouts(Feature f) {
+        Map anno = f.getAnnotation().asMap();
+        Map links = new HashMap();
+        for (Iterator i = anno.entrySet().iterator(); i.hasNext(); ) {
+            Map.Entry me = (Map.Entry) i.next();
+            String key = me.getKey().toString();
+            if (key.startsWith("href:")) {
+                Object o = me.getValue();
+                if (o instanceof List) {
+                    links.put(key.substring(5), ((List) o).get(0));
+                } else {
+                    links.put(key.substring(5), o);
+                }
+            }
+        }
+        
+        return links;
+    }
+    
+    public int countFeatures(String reference,
+    int min,
+    int max,
+    String type)
+    throws DataSourceException, NoSuchElementException
+    {
+        try {
+            sdb.getSequence(reference);
+            return 3000;
+        } catch (Exception ex) {}
+        return 0;
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/BiojavaFeatureSource.java b/src/org/biojava/servlets/dazzle/datasource/BiojavaFeatureSource.java
new file mode 100644
index 0000000..a4c5dbf
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/BiojavaFeatureSource.java
@@ -0,0 +1,213 @@
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.*;
+import java.io.*;
+import org.biojava.bio.seq.*;
+import org.biojava.utils.xml.*;
+
+/** an interface that defines which commands are provided by a Feature service
+ * <p>
+ * When implementing an annotation source, you need to provide
+ * a <code>FeatureHolder</code> containing just those extra
+ * features which you want to add to a sequence.  However, BioJava
+ * doesn't allow construction of features without an associated
+ * sequence.  The easiest approach here is to use the BioJava
+ * <code>ViewSequence</code> class, e.g.:
+ *
+ * <pre>
+ * Sequence seq = referenceDB.get(seqID);
+ * ViewSequence vseq = new ViewSequence(seq);
+ * vseq.createFeature(myFeatureTemplate);
+ * // add more features...
+ * return vseq.getAddedFeatures();;
+ * </pre>
+ */
+public interface BiojavaFeatureSource extends DazzleDataSource {
+
+	/**
+	 * Get the complete set of features for a given sequence landmark.
+	 * For large datasources, this might often be a `lazy fetch'
+	 * implementation of <code>FeatureHolder</code>
+	 *
+	 * @param ref the ID of a landmark sequence
+	 * @return A <code>FeatureHolder</code> containing all features on that
+	 *          landmark.  This might be filtered by Dazzle.
+	 * @throws DataSourceException if an error occurs accessing underlying
+	 *                             storage, or if the plugin hasn't be
+	 *                             correctly configured.
+	 * @throws NoSuchElementException if no landmark of the specified name
+	 *                                can be found.
+	 */
+
+	public FeatureHolder getFeatures(String ref) throws DataSourceException,
+			NoSuchElementException;
+
+	/**
+	 * Return an ID string for a feature.  This /may/ be <code>null</code>, but
+	 * the resulting datasource may then not comply perfectly with DAS 1.0.
+	 * @param f 
+	 * @return id
+	 */
+
+	public String getFeatureID(Feature f);
+
+	/**
+	 * Return a display label for a feature.
+	 * @param f 
+	 * @return label
+	 */
+
+	public String getFeatureLabel(Feature f);
+
+	/**
+	 * Get the NOTE string to use for the specified feature.  If no notes
+	 * are applicable, return an empty list.
+	 * @param f 
+	 * @return notes
+	 */
+
+	public List getFeatureNotes(Feature f);
+
+	/**
+	 * Get the phase for a feature
+	 * @param f 
+	 * @return phase
+	 */
+
+	public FramedFeature.ReadingFrame getPhase(Feature f);
+
+	/**
+	 * Return a score representation for this feature, or
+	 * <code>null</code> if not applicable.
+	 * @param f 
+	 * @return score
+	 *
+	 * @since 0.97
+	 */
+
+	public String getScore(Feature f);
+
+	/**
+	 * Find the features matching a given ID
+	 * @param id 
+	 * @param matchType 
+	 * @return FeatureHolder
+	 * @throws DataSourceException 
+	 */
+
+	public FeatureHolder getFeaturesByID(String id, MatchType matchType)
+			throws DataSourceException;
+
+	/**
+	 * Find the features matching a given group ID
+	 * @param id 
+	 * @param matchType 
+	 * @return FeatureHolder
+	 * @throws DataSourceException 
+	 */
+
+	public FeatureHolder getFeaturesByGroup(String id, MatchType matchType)
+			throws DataSourceException;
+
+	//
+	// Embedded links
+	//
+
+	/**
+	 * Return a set of links out from a feature.  This is a map
+	 * which can contain zero or more role -> url mappings.
+	 *
+	 * @param f A feature, which will have been obtained from this datasource
+	 * @return a <code>Map</code> of link URLs, or the empty Map.
+	 * @since 0.93
+	 */
+
+	public Map getLinkouts(Feature f);
+
+	/**
+	 * Write out additional `detail' elements in the XFF features dump.
+	 * @param xw 
+	 * @param f 
+	 * @throws IOException 
+	 */
+
+	public void writeXFFDetails(XMLWriter xw, Feature f) throws IOException;
+
+	public final static int COUNT_CALCULATE = -1;
+
+	public final static int COUNT_DONTRETURN = -2;
+
+	/**
+	 * Optional optimization of the counting of features in a given region.
+	 * Can return <code>COUNT_CALCULATE</code>, <code>COUNT_DONTRETURN</code>,
+	 * or a positive integer count.
+	 * @param reference 
+	 * @param type 
+	 * @return nr of features
+	 * @throws DataSourceException 
+	 * @throws NoSuchElementException 
+	 *
+	 * @since 0.94
+	 */
+
+	public int countFeatures(String reference, String type)
+			throws DataSourceException, NoSuchElementException;
+
+	/**
+	 * Optional optimization of the counting of features in a given region.
+	 * Can return <code>COUNT_CALCULATE</code>, <code>COUNT_DONTRETURN</code>,
+	 * or a positive integer count.
+	 * @param reference 
+	 * @param start 
+	 * @param end 
+	 * @param type 
+	 * @return nr featues
+	 * @throws DataSourceException 
+	 * @throws NoSuchElementException 
+	 *
+	 * @since 0.94
+	 */
+
+	public int countFeatures(String reference, int start, int end, String type)
+			throws DataSourceException, NoSuchElementException;
+
+	/**
+	 * Return a list of DASGFFGroup objects of which this feature is a member.
+	 * This replaces the old getSpoofedGroups method.
+	 * @param f 
+	 * @return groups
+	 *
+	 * @since 1.0
+	 */
+
+	public List getGroups(Feature f);
+
+	/**
+	 * Determine if a non-contiguous feature should be shattered into multiple blocks.
+	 * When the DASGFF generator finds a feature who's BioJava location is not
+	 * contiguous, it calls this method.  If it returns true, the BioJava feature
+	 * is shattered into multiple DAS features, one for each contiguous span
+	 * of the location.
+	 * @param f 
+	 * @return flag 
+	 */
+
+	public boolean getShatterFeature(Feature f);
+
+	public static final class MatchType {
+		private String name;
+
+		private MatchType(String name) {
+			this.name = name;
+		}
+
+		public String toString() {
+			return "MatchType(" + name + ")";
+		}
+	}
+
+	public final static MatchType MATCH_EXACT = new MatchType("exact");
+
+	public final static MatchType MATCH_PARTIAL = new MatchType("partial");
+
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/DASGFFGroup.java b/src/org/biojava/servlets/dazzle/datasource/DASGFFGroup.java
new file mode 100644
index 0000000..f5fe372
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/DASGFFGroup.java
@@ -0,0 +1,87 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+
+import java.util.*;
+
+
+/**
+ * Object for representing arbitrary groupings of DASGFF features.
+ *
+ * @author Thomas Down
+ * @version 1.00
+ * @since 0.97
+ */
+
+public class DASGFFGroup {
+    private final String gid;
+    private final String type;
+    private final String label;
+    private final Map linkMap;
+    private final List<String> notes;
+    
+    public DASGFFGroup(String gid, String type) {
+        this(gid, type, null, Collections.EMPTY_MAP, Collections.EMPTY_LIST);
+    }
+    
+    public DASGFFGroup(String gid, String type, String label) {
+        this(gid, type, label, Collections.EMPTY_MAP, Collections.EMPTY_LIST);
+    }
+    
+    public DASGFFGroup(String gid, String type, Map linkMap) {
+        this(gid, type, null, linkMap, Collections.EMPTY_LIST);
+    }
+    
+    public DASGFFGroup(String gid, String type, String label, Map linkMap) {
+        this(gid, type, label, linkMap, Collections.EMPTY_LIST);
+    }
+    
+    public DASGFFGroup(String gid, String type, String label, Map linkMap, List<String> notes) {
+        super();
+        this.gid = gid;
+        this.type = type;
+        this.linkMap = linkMap;
+        this.label = label;
+        this.notes = notes;
+    }
+    
+    public List<String> getNotes() {
+        return notes;
+    }
+    
+    public String getGID() {
+        return gid;
+    }
+    
+    public String getType() {
+        return type;
+    }
+    
+    public Map getLinkMap() {
+        return linkMap;
+    }
+    
+    public String getLabel() {
+        return label;
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/DataSourceException.java b/src/org/biojava/servlets/dazzle/datasource/DataSourceException.java
new file mode 100644
index 0000000..aea909c
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/DataSourceException.java
@@ -0,0 +1,44 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import org.biojava.bio.*;
+
+/**
+ * An exception within a DAS datasource
+ *
+ * @author Thomas Down, Benjamin Schuster-Boeckler
+ */
+
+public class DataSourceException extends BioException {
+    public DataSourceException(String s) {
+	super(s);
+    }
+
+    public DataSourceException(Throwable t, String s) {
+	super(t, s);
+    }
+
+    public DataSourceException(Throwable t) {
+	super(t);
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/DazzleDataSource.java b/src/org/biojava/servlets/dazzle/datasource/DazzleDataSource.java
new file mode 100644
index 0000000..02ebeb1
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/DazzleDataSource.java
@@ -0,0 +1,290 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.*;
+import org.biojava.bio.seq.*;
+import org.biojava.utils.xml.*;
+
+/**
+ * Interface for plugins which provide data and formatting behaviour
+ * for DazzleServer.  Basic implementations of DazzleDataSource
+ * provide annotation server functionality.  For reference servers,
+ * use the sub-interface, DazzleReferenceSource.
+ *
+ * <h3>Life-cycle</h3>
+ *
+ * <p>
+ * Dazzle may load and unload plugin objects at any time.  Standard
+ * Dazzle installations load plugins based on <code>datasource</code>
+ * elements in the <code>dazzlecfg.xml</code> file.
+ * </p>
+ *
+ * </p>
+ * In addition to implementing this interface, a typical plugin
+ * class will have several Javabeans-style setFoo(x) methods for
+ * setting plugin properties.  These methods are called to
+ * initialize the properties specified in <code>dazzlecfg.xml</code>.
+ * See the <a href="http://www.biojava.org/dazzle/deploy.html">deployment
+ * guide</a> for a list of common properties.
+ * </p>
+ *
+ * <p>
+ * Once the class has been loaded and all the properties set, the
+ * Dazzle servlet will call the <code>init</code> method.  Only once
+ * this has returned sucessfully is the plugin considered to be
+ * `in service'.  At this point, any other method may be called.
+ * </p>
+ *
+ * <h3>Writing simple annotation sources</h3>
+ *
+ * <p>
+ * In principle, a DAS annotation source just provides a set of
+ * features annotating a given landmark.  In addition, you must
+ * also provide:
+ * <ul>
+ * <li>Landmark versions, so that clients can detect version skew
+ *     between reference and annotation servers.</li>
+ * <li>Sequence lengths, allowing the server core to validate
+ *     requests.</li>
+ * </ul>
+ * Ideally, this information would only be needed for landmark
+ * sequences which this data source actually annotates.  In practice,
+ * the DAS 1.0 specification requires that this information be
+ * available for <em>all</em> landmarks specified by a given
+ * reference server.  One way to get this data is to create
+ * a <code>DASSequenceDB</code> and fetch the information directly
+ * from the reference server.  See <code>GFFAnnotationSource</code>
+ * for an example of this.
+ * </p>
+ *
+ * <p>
+ * When implementing an annotation source, you need to provide
+ * a <code>FeatureHolder</code> containing just those extra
+ * features which you want to add to a sequence.  However, BioJava
+ * doesn't allow construction of features without an associated
+ * sequence.  The easiest approach here is to use the BioJava
+ * <code>ViewSequence</code> class, e.g.:
+ *
+ * <pre>
+ * Sequence seq = referenceDB.get(seqID);
+ * ViewSequence vseq = new ViewSequence(seq);
+ * vseq.createFeature(myFeatureTemplate);
+ * // add more features...
+ * return vseq.getAddedFeatures();;
+ * </pre>
+ * 
+ *
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+
+
+public interface DazzleDataSource     
+   
+{
+
+    /**
+     * Initialize this datasource, in a given context.
+     * You may wish to record the <code>context</code> parameter,
+     * for logging or resource access.
+     *
+     * @param context the ServletContext in which this Dazzle installation is running
+     * @throws DataSourceException if for any reason the plugin cannot enter service.
+     */
+
+    public void init(ServletContext context)
+        throws DataSourceException;
+        
+    /**
+     * Called prior to taking a datasource out of service
+     */
+     
+    public void destroy();
+        
+    /**
+     * Return a type for this data source.  For example,  <code>gff</code> or
+     * <code>ensembl-ref</code>.  If this is not specified, the class name is
+     * used.
+     */
+     
+    public String getDataSourceType();
+    
+    /**
+     * Return a version string for this datasource
+     */
+     
+    public String getDataSourceVersion();
+
+    /**
+     * Return the `Map master' URL of the reference server to be annotated.  Note
+     * that this is ignored for reference servers.
+     */
+
+    public String getMapMaster();
+
+    /**
+     * Return the display name of this data source.  This may be
+     * shown by clients, but is not otherwise significant in the
+     * DAS protocol.
+     */
+
+    public String getName();
+
+    /**
+     * Return the description of this data source.  A
+     * <code>null</code> value means no description.  This may be
+     * shown by clients, but is not otherwise significant in the DAS
+     * protocol.  
+     */
+
+    public String getDescription();
+
+    /**
+     * Return the current version of this data represented by this
+     * source.  This may be shown by clients, but is not otherwise
+     * significant in the DAS protocol.  
+     */
+
+    public String getVersion();
+
+
+    /**
+     * Get a version for a given landmark.  Note that this method
+     * must return a valid version for every sequence landmark from a
+     * given reference server -- even landmarks which are not
+     * annotated.
+     *
+     * @param ref the ID of a landmark sequence
+     * @return The annotated version of this landmark
+     * @throws DataSourceException if an error occurs accessing underlying
+     *                             storage, or if the plugin hasn't be
+     *                             correctly configured.
+     * @throws NoSuchElementException if no landmark of the specified name
+     *                                can be found.
+     */
+
+    public String getLandmarkVersion(String ref)
+        throws DataSourceException, NoSuchElementException;
+
+    /**
+     * Get the length of a landmark sequence.  Note that this method
+     * must return a valid value for every sequence landmark from a
+     * given reference server -- even landmarks which are not
+     * annotated.
+     *
+     * @param ref the ID of a landmark sequence
+     * @return The length of this sequence
+     * @throws DataSourceException if an error occurs accessing underlying
+     *                             storage, or if the plugin hasn't be
+     *                             correctly configured.
+     * @throws NoSuchElementException if no landmark of the specified name
+     *                                can be found.
+     */
+
+    public int getLandmarkLength(String ref)
+        throws DataSourceException, NoSuchElementException;
+
+    //
+    // Types system
+    //
+
+    /**
+     * Return the set of all type IDs served by this datasource.  This is used
+     * by the no-args version of the <code>types</code> DAS command.
+     */
+
+    public Set getAllTypes();
+
+    /**
+     * Return a description string for a given type.  May be null (indicating
+     * that the description is the same as the type ID).
+     */
+
+    public String getTypeDescription(String type);
+
+    //
+    // Stuff to help write correct information about features
+    //
+
+   
+   
+    
+        
+    //
+    // Stylesheet support.
+    //
+
+    /**
+     * Return a path to an XML stylesheet document, relative to the
+     * the top-level of the current webapp's directory structure.  Note
+     * that so long as the file pointed to by this string exists, it
+     * is transmitted to the client without any further checcking, so
+     * use with care.
+     *
+     * @return a path to an XML DAS stylesheet document.
+     */
+
+    public String getStylesheet();
+
+    //
+    // Embedded links
+    //
+
+   
+
+    //
+    // LINK command support
+    //
+
+    /**
+     * Handle a DAS link command.  The plugin can send any data it wishes
+     * in response to this command (including HTTP redirects).  If
+     * DazzleServlet catches a DataSourceException or a NoSuchElementException
+     * it will generate standard error pages.  If the method returns <code>false</code>
+     * a pre-canned `No extra information' page will be returned.  Otherwise, it is
+     * assumed that a response has been generated.
+     *
+     * @param req The servlet request
+     * @param resp The servlet response, to which any data can be written
+     * @param field The type of entity that is being linked to.
+     * @param id The identifier of the entity linked to.
+     *
+     * @return <code>true</code> if a response has been generated.
+     */
+
+    public boolean doLink(HttpServletRequest req,
+		       HttpServletResponse resp,
+		       String field,
+		       String id)
+	throws ServletException, IOException, DataSourceException, NoSuchElementException;
+
+     
+    
+
+}
+
+
diff --git a/src/org/biojava/servlets/dazzle/datasource/DazzleInstallation.java b/src/org/biojava/servlets/dazzle/datasource/DazzleInstallation.java
new file mode 100644
index 0000000..97b2c46
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/DazzleInstallation.java
@@ -0,0 +1,47 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.util.*;
+
+/**
+ * Interface for a namespace of datasources, to be served by the Dazzle
+ * framework.
+ *
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+public interface DazzleInstallation {
+    public void init(ServletConfig ctx)
+        throws DataSourceException;
+        
+    public void destroy();    
+
+    public DazzleDataSource getDataSource(List nameComponents, HttpServletRequest req)
+        throws DataSourceException;
+
+    public Set<String> getDataSourceIDs(List nameComponents, HttpServletRequest req)
+        throws DataSourceException;
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/DazzleReferenceSource.java b/src/org/biojava/servlets/dazzle/datasource/DazzleReferenceSource.java
new file mode 100644
index 0000000..75b6b08
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/DazzleReferenceSource.java
@@ -0,0 +1,83 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.*;
+import org.biojava.bio.seq.*;
+
+/**
+ * Data source which backs a DAS reference server.  This is a sub-interface
+ * of <code>DazzleDataSource</code>, and all methods of that interface must
+ * be fully implemented (with the exception of <code>getMapMaster</code>.
+ * Please consult the javadoc for <code>DazzleDataSource</code> for more
+ * general comments on the implementation of Dazzle plugins.
+ *
+ * <p>
+ * A DAS reference source is very similar in most respects to an annotation
+ * source.  In protocol terms, the two substantive differences are:
+ * <ul>
+ * <li>Reference servers serve DNA sequence as well as features</li>
+ * <li>Reference servers offer a list of `entry points' -- the
+ * top level sequences in the database</li>
+ * </ul>
+ * The extra methods on this interface reflect the need to serve
+ * this extra data.
+ * </p>
+ *
+ * <p>
+ * In addition, reference servers may serve information about how
+ * sequence fragments (e.g. clones) are assembled into larger structures
+ * (e.g. contigs).  If present, assembly information should be
+ * communicated by including BioJava <code>ComponentFeature</code>
+ * objects in the feature table.  These are automatically translated
+ * by Dazzle into DAS category=component features.
+ * </p>
+ *
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+public interface DazzleReferenceSource extends DazzleDataSource {
+    /**
+     * This is ignored for reference servers -- a mapMaster URL
+     * is generated automatically by the Servlet.
+     */
+
+    public String getMapMaster();
+
+    /**
+     * Get the real sequence corresponding to the specified DAS ID.
+     * This is used to implement the DAS <code>dna</code> command.
+     */
+
+    public Sequence getSequence(String ref)
+        throws NoSuchElementException, DataSourceException;
+
+    /**
+     * Return a Set<String> listing all the top-level entry points
+     * provided by this server.  This might typically be the set of
+     * chromosome names.  Note than sub-entry-points are
+     * autogenerated by the server using ComponentFeatures.
+     */
+
+    public Set getEntryPoints();
+} 
diff --git a/src/org/biojava/servlets/dazzle/datasource/EmblDataSource.java b/src/org/biojava/servlets/dazzle/datasource/EmblDataSource.java
new file mode 100644
index 0000000..a5540f0
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/EmblDataSource.java
@@ -0,0 +1,163 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.*;
+import java.io.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.biojava.bio.*;
+import org.biojava.bio.seq.*;
+import org.biojava.bio.seq.io.*;
+import org.biojava.utils.xml.*;
+
+/**
+ * Simple example datasource backed by an EMBL file.
+ *
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+public class EmblDataSource extends AbstractDataSource implements DazzleReferenceSource {
+    private String fileName;
+    private Map seqs;
+    private Set allTypes;
+    
+    public String getDataSourceType() {
+        return "emblfile";
+    }
+    
+    public String getDataSourceVersion() {
+        return "1.00";
+    }
+
+    public void setFileName(String s) {
+        fileName = s;
+    }
+
+    public String getMapMaster() {
+        return null;
+    }
+
+    public void init(ServletContext ctx) 
+        throws DataSourceException
+    {
+        super.init(ctx);
+        try {
+            seqs = new HashMap();
+            allTypes = new HashSet();
+            BufferedReader br = new BufferedReader(new InputStreamReader(ctx.getResourceAsStream(fileName)));
+            SequenceBuilderFactory sbf = new EmblProcessor.Factory(new NameCatcherFactory(SimpleSequenceBuilder.FACTORY));
+            SequenceFormat sf = new EmblLikeFormat();
+            SequenceIterator si = new StreamReader(br, sf, DNATools.getDNA().getTokenization("token"), sbf);
+            while (si.hasNext()) {
+                Sequence seq = si.nextSequence();
+                seqs.put(seq.getName(), seq);
+            }
+        } catch (Exception ex) {
+            throw new DataSourceException(ex, "Couldn't load sequence file");
+        }
+    }
+
+    private class NameCatcherFactory implements SequenceBuilderFactory {
+        private SequenceBuilderFactory chain;
+        
+        NameCatcherFactory(SequenceBuilderFactory chain) {
+            this.chain = chain;
+        }
+        
+        public SequenceBuilder makeSequenceBuilder() {
+            return new NameCatcher(chain.makeSequenceBuilder());
+        }
+    }
+    
+    private class NameCatcher extends SequenceBuilderFilter {
+        NameCatcher(SequenceBuilder delegate) {
+            super(delegate);
+        }
+        
+        public void setName(String name) 
+            throws ParseException
+        {
+            // We ignore this, since biojava is currently using IDs rather than
+            // accessions.  Hopefully the accession will be caught later.
+        }
+        
+        public void addSequenceProperty(Object key, Object value)
+            throws ParseException
+        {
+            if ("AC".equals(key)) {
+                String acString = value.toString();
+                int semi = acString.indexOf(';');
+                if (semi > 0) {
+                    acString = acString.substring(0, semi);
+                }
+                getDelegate().setName(acString);
+            }
+            getDelegate().addSequenceProperty(key, value);
+        }
+        
+        public void startFeature(Feature.Template templ) 
+            throws ParseException 
+        {
+            allTypes.add(templ.type);
+            getDelegate().startFeature(templ);
+        }
+    }
+
+    public String getLandmarkVersion(String ref)
+        throws DataSourceException, NoSuchElementException
+    {
+        Annotation anno = getSequence(ref).getAnnotation();
+        if (anno.containsProperty("SV")) {
+            String sv = anno.getProperty("SV").toString();
+            int dotPos = sv.indexOf('.');
+            if (dotPos > 0) {
+                return sv.substring(dotPos + 1);
+            } else {
+                return sv;
+            }
+        }
+        
+        return getVersion();
+    }
+
+    public Sequence getSequence(String ref)
+        throws NoSuchElementException, DataSourceException
+    {
+        Sequence seq = (Sequence) seqs.get(ref);
+        if (seq == null) {
+            throw new NoSuchElementException("No sequence " + ref);
+        }
+        return seq;
+    }
+
+    public Set getAllTypes() {
+        return Collections.unmodifiableSet(allTypes);
+    }
+    
+    public Set getEntryPoints() {
+        return seqs.keySet();
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/FastaDataSource.java b/src/org/biojava/servlets/dazzle/datasource/FastaDataSource.java
new file mode 100644
index 0000000..de14be7
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/FastaDataSource.java
@@ -0,0 +1,116 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.*;
+import java.io.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+
+import org.biojava.bio.*;
+import org.biojava.bio.seq.*;
+import org.biojava.bio.seq.io.*;
+import org.biojava.utils.xml.*;
+
+/**
+ * Simple example datasource backed by an EMBL file.
+ *
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+public class FastaDataSource extends AbstractDataSource implements DazzleReferenceSource {
+    private String fileName;
+    private Map seqs;
+    
+    public String getDataSourceType() {
+        return "fasta";
+    }
+    
+    public String getDataSourceVersion() {
+        return "1.00";
+    }
+
+    public void setFileName(String s) {
+        fileName = s;
+    }
+
+    public String getMapMaster() {
+        return null;
+    }
+
+    public void init(ServletContext ctx) 
+        throws DataSourceException
+    {
+        super.init(ctx);
+        try {
+            seqs = new HashMap();
+            BufferedReader br = new BufferedReader(new InputStreamReader(ctx.getResourceAsStream(fileName)));
+            SequenceBuilderFactory sbf = SimpleSequenceBuilder.FACTORY;
+            SequenceFormat sf = new FastaFormat();
+            SequenceIterator si = new StreamReader(br, sf, DNATools.getDNA().getTokenization("token"), sbf);
+            while (si.hasNext()) {
+                Sequence seq = si.nextSequence();
+                seqs.put(seq.getName(), seq);
+            }
+        } catch (Exception ex) {
+            throw new DataSourceException(ex, "Couldn't load sequence file");
+        }
+    }
+
+
+    public String getLandmarkVersion(String ref)
+        throws DataSourceException, NoSuchElementException
+    {
+        Annotation anno = getSequence(ref).getAnnotation();
+        if (anno.containsProperty("SV")) {
+            String sv = anno.getProperty("SV").toString();
+            int dotPos = sv.indexOf('.');
+            if (dotPos > 0) {
+                return sv.substring(dotPos + 1);
+            } else {
+                return sv;
+            }
+        }
+        
+        return getVersion();
+    }
+
+    public Sequence getSequence(String ref)
+        throws NoSuchElementException, DataSourceException
+    {
+        Sequence seq = (Sequence) seqs.get(ref);
+        if (seq == null) {
+            throw new NoSuchElementException("No sequence " + ref);
+        }
+        return seq;
+    }
+
+    public Set getAllTypes() {
+        return Collections.emptySet();
+    }
+    
+    public Set getEntryPoints() {
+        return seqs.keySet();
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/GFFAnnotationSource.java b/src/org/biojava/servlets/dazzle/datasource/GFFAnnotationSource.java
new file mode 100644
index 0000000..1df2d00
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/GFFAnnotationSource.java
@@ -0,0 +1,351 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.*;
+import java.util.regex.*;
+import java.io.*;
+
+import javax.servlet.*;
+import org.biojava.utils.*;
+import org.biojava.utils.cache.*;
+import org.biojava.bio.*;
+import org.biojava.bio.seq.*;
+import org.biojava.bio.seq.impl.*;
+import org.biojava.bio.symbol.*;
+
+import org.biojava.bio.program.gff.*;
+
+import java.util.regex.Pattern;
+
+/**
+ * Annotation datasource backed by a GFF file.
+ *
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+public class GFFAnnotationSource extends AbstractDataSource implements DazzleDataSource {
+    private static final Pattern REGION_PATTERN;
+    private static final Pattern VERSION_PATTERN;
+    
+    static {
+        REGION_PATTERN = Pattern.compile("sequence-region ([^ ]+) ([0-9]+) ([0-9]+)");
+        VERSION_PATTERN = Pattern.compile("(.+)\\.([0-9]+)");
+    }
+    
+    private String mapMaster;
+    private String fileName;
+
+    private CacheMap featureSets = new FixedSizeMap(500);
+    protected Map gffSets;
+    protected Set allTypes;
+    private boolean dotVersions = false;
+    private Map sequenceLengths = new HashMap();
+    private Map aliases = new HashMap();
+    private Map versions = new HashMap();
+    
+    private String idProperty = "id";
+    private String IDProperty = "ID";
+    private String groupIdProperty = "group";
+
+    public String getDataSourceType() {
+        return "gff";
+    }
+    
+    public String getDataSourceVersion() {
+        return "1.00";
+    }
+    
+    public void setMapMaster(String s) {
+        this.mapMaster = s;
+    }
+
+    public String getMapMaster() {
+        return mapMaster;
+    }
+
+    public void setFileName(String s) {
+        fileName = s;
+    }
+    
+    public String getFileName(){
+    	return fileName;
+    }
+    
+    public void setDotVersions(boolean b) {
+        this.dotVersions = b;
+    }
+    
+    public void setIdProperty(String s) {
+        this.idProperty = s;
+    }
+    
+    public void setGroupIdProperty(String s) {
+        this.groupIdProperty = s;
+    }
+    
+    protected void registerSeq(String name) {
+        if (dotVersions) {
+            Matcher nameMatcher = VERSION_PATTERN.matcher(name);
+            if (nameMatcher.matches()) {
+                String seq = nameMatcher.group(1);
+                String version = nameMatcher.group(2);
+                aliases.put(seq, name);
+                versions.put(name, version);
+            }
+        }
+    }
+    
+    private String mapName(String ref) {
+        if (aliases.containsKey(ref)) {
+            ref = (String) aliases.get(ref);
+        }
+        return ref;
+    }
+
+    private class Handler implements GFFDocumentHandler {
+        public void startDocument(String locator) {
+        }
+        
+        public void commentLine(String comment) {
+            if (comment.charAt(0) == '#') {
+                try {
+                    Matcher regionMatcher = REGION_PATTERN.matcher(comment.substring(1));
+                    if (regionMatcher.matches()) {
+                        String seqName = regionMatcher.group(1);
+                        int length = Integer.parseInt(regionMatcher.group(3));
+                        registerSeq(seqName);
+                        if (!sequenceLengths.containsKey(seqName)) {
+                            sequenceLengths.put(seqName, new Integer(length));
+                        }
+                    }
+                } catch (Exception ex) {
+                    log("Error parsing comment", ex);
+                }
+            }
+        }
+        
+        
+        
+        public void endDocument() {    
+        }
+
+		public void recordLine(GFFRecord record) {
+			addRecordLine(record);
+		}
+    }
+    
+    public void addRecordLine(GFFRecord record) {
+        allTypes.add(record.getFeature());
+        String seq = record.getSeqName();
+        registerSeq(seq);
+        List seqGFF = (List) gffSets.get(seq);
+        if (seqGFF == null) {
+            seqGFF = new ArrayList();
+            gffSets.put(seq, seqGFF);
+        }
+        
+        seqGFF.add(record);
+    }
+    protected void initContainers(){
+        //gffSets = new HashMap();
+        //allTypes = new HashSet();
+        gffSets = new HashMap<String, List<GFFRecord>>();
+		allTypes = new HashSet<String>();
+    }
+    
+    public void init(ServletContext ctx) 
+        throws DataSourceException
+    {
+        super.init(ctx);
+        try {
+        	initContainers();
+            
+            BufferedReader br = new BufferedReader(new InputStreamReader(ctx.getResourceAsStream(fileName)));
+            GFFEntrySet gffe = new GFFEntrySet();
+            final GFFDocumentHandler adder = gffe.getAddHandler();
+            
+            GFFDocumentHandler handler = new Handler();
+            GFFParser gffp = new GFFParser();
+            gffp.parse(br, handler, fileName);
+        } catch (Exception ex) {
+            throw new DataSourceException(ex, "Couldn't load GFF");
+        }
+    }
+    
+    public Sequence getSequence(String ref)
+	    throws DataSourceException, NoSuchElementException
+    {
+        ref = mapName(ref);
+        int length = Integer.MAX_VALUE;
+        
+        if (sequenceLengths.containsKey(ref)) {
+            length = ((Integer) sequenceLengths.get(ref)).intValue();
+        }
+        return new SimpleSequence(new DummySymbolList(DNATools.getDNA(), length), ref, ref, Annotation.EMPTY_ANNOTATION);
+    }
+
+
+    public String getLandmarkVersion(String ref) 
+	    throws DataSourceException, NoSuchElementException
+    {
+        ref = mapName(ref);
+        if (versions.containsKey(ref)) {
+            return (String) versions.get(ref);
+        } else {
+            return getVersion();
+        }
+    }
+
+    protected void annotate(Sequence seq)
+        throws BioException, ChangeVetoException
+    {
+        List gff = (List) gffSets.get(seq.getName());
+        if (gff == null) {
+            return;
+        }
+        
+        for (Iterator i = gff.iterator(); i.hasNext(); ) {
+            GFFRecord record = (GFFRecord) i.next();
+            
+            StrandedFeature.Template templ = new StrandedFeature.Template();
+            templ.strand = record.getStrand();
+            templ.location = new RangeLocation(record.getStart(), record.getEnd());
+            if ( (record.getStart() == 0) || ( record.getEnd() == 0))
+            {
+            	throw new BioException("Can not create ranges starting at 0, first" +
+            			" position starts counting at 1 ( at:"+
+            			seq.getName() + " " + templ.location + ")");
+            }
+
+            templ.type = record.getFeature();
+            templ.annotation = new SmallAnnotation();
+            
+            Map group = record.getGroupAttributes();
+            for (Iterator gi = group.entrySet().iterator(); gi.hasNext(); ) {
+                Map.Entry me = (Map.Entry) gi.next();
+                templ.annotation.setProperty(me.getKey(), me.getValue());
+            }
+            
+            if (record.getScore() != GFFRecord.NO_SCORE) {
+                templ.annotation.setProperty(GFFEntrySet.PROPERTY_GFF_SCORE, new Double(record.getScore()));
+            }
+            
+            seq.createFeature(templ);
+        }
+    }
+
+    public FeatureHolder getFeatures(String ref)
+	    throws NoSuchElementException, DataSourceException
+    {
+        ref = mapName(ref);
+     
+        System.out.println("getFeatures for " + ref);
+        //System.out.println(gffSets.containsKey(ref));
+        if (!gffSets.containsKey(ref)) {
+            return null;
+        }
+        FeatureHolder features = (FeatureHolder) featureSets.get(ref);
+        if (features == null) {
+            try {
+                Sequence seq = getSequence(ref);
+                ViewSequence vseq = new ViewSequence(seq);
+                annotate(vseq);
+                
+                features = vseq.getAddedFeatures();
+                featureSets.put(ref, features);
+            } catch (BioException ex) {
+                throw new DataSourceException(ex, "Error annotating sequence " + ref);
+            } catch (ChangeVetoException ex) {
+                throw new DataSourceException("ViewSequence isn't accepting features :(");
+            }	    
+        } 
+        return features;
+    }
+
+    public String getFeatureID(Feature f) {
+        Annotation anno = f.getAnnotation();
+        if (anno.containsProperty(idProperty)) {
+            return stringifyProp(anno.getProperty(idProperty));
+        }
+        if ( anno.containsProperty(IDProperty)) {
+        	return stringifyProp(anno.getProperty(IDProperty));
+        }
+        
+        return null;
+    }
+    
+    public Set getAllTypes() {
+        return Collections.unmodifiableSet(allTypes);
+    }
+
+    public Map getLinkouts(Feature f) {
+        Map anno = f.getAnnotation().asMap();
+        Map links = new HashMap();
+        for (Iterator i = anno.entrySet().iterator(); i.hasNext(); ) {
+            Map.Entry me = (Map.Entry) i.next();
+            String key = me.getKey().toString();
+            if (key.startsWith("href:")) {
+                Object o = me.getValue();
+                if (o instanceof List) {
+                    links.put(key.substring(5), ((List) o).get(0));
+                } else {
+                    links.put(key.substring(5), o);
+                }
+            }
+        }
+        
+        return links;
+    }
+
+    public String getScore(Feature f) {
+        Annotation ann = f.getAnnotation();
+        if (ann.containsProperty(GFFEntrySet.PROPERTY_GFF_SCORE)) {
+            return ann.getProperty(GFFEntrySet.PROPERTY_GFF_SCORE).toString();
+        } else {
+            return null;
+        }
+    }
+    
+    public List getGroups(Feature f) {
+        Annotation anno = f.getAnnotation();
+        if (anno.containsProperty(groupIdProperty)) {
+            String gid = stringifyProp(anno.getProperty(groupIdProperty));
+            return Collections.singletonList(
+                    new DASGFFGroup(gid, f.getType())
+            );
+        }
+                    
+        return Collections.EMPTY_LIST;
+    }
+    
+    private String stringifyProp(Object o) {
+        if (o instanceof List) {
+            List l = (List) o;
+            if (l.size() == 1) {
+                return l.get(0).toString();
+            }
+        }
+        return o.toString();
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/GFFFeature.java b/src/org/biojava/servlets/dazzle/datasource/GFFFeature.java
new file mode 100644
index 0000000..b0ca76b
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/GFFFeature.java
@@ -0,0 +1,138 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 29.10.2004
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+
+
+/** a very simple feature container 
+ @author Andreas Prlic
+ */
+public class GFFFeature 
+implements java.lang.Cloneable {
+	String name   ;
+	String method ;
+	String type   ;
+	String note   ;
+	String link   ;
+	String source ;
+	String start  ;
+	String end    ;
+	String phase  ;
+	String orientation ;
+	String score       ;
+	String label       ;
+	String typeCategory; // support for Ontology
+	String typeId; // support for Ontology
+	DASGFFGroup group;
+
+	public GFFFeature() {
+		source = "Unknown";
+		method = "Unknown";
+		type   = "Unknown";
+		note   = "";
+		link   = "";
+		start  = "" ;
+		end    = "" ;
+		phase       = null ;
+		orientation = null ;
+		score       = null ;
+		label       = null ;
+		group 		= null;
+		typeCategory = null;
+	}
+
+	public Object clone() {
+		GFFFeature n = new GFFFeature();
+		n.setName(this.name);
+		n.setSource(this.source);
+		n.setMethod(this.method);
+		n.setType(this.type);
+		n.setNote(this.note);
+		n.setLink(this.link);
+		n.setStart(this.start);
+		n.setEnd(this.end);
+		n.setPhase(this.phase);
+		n.setOrientation(this.orientation);
+		n.setScore(this.score);
+		n.setLabel(this.label);
+		n.setGroup(this.group);
+		n.setTypeCategory(this.typeCategory);
+		return n;
+	}
+
+	public String toString() {
+		String str = "GFFFeature: method: " + method +" type: " + type + " note: "+note ;
+		str += " link: "+ link + " start:" + start + " end:" + end;
+
+		return str ;
+	}
+
+	public void setSource(String s) { source = s;}
+	public String getSource() { return source; };
+
+	public void setName(String nam) { name = nam; }
+	public String getName() { return name; }
+
+	public void setMethod(String methd) { method = methd ; }
+	public String getMethod() { return method ; }
+
+	public void setType(String typ) { type = typ ; }
+	public String getType() { return type ; }
+
+	public void setNote(String nte) { note = nte; }
+	public String getNote() { return note ; }
+
+	public void setLink(String lnk) { link = lnk;}
+	public String getLink() { return link;}
+
+	public void setStart(String s) { start = s;}
+	public String getStart() { return start;}
+
+	public void setEnd(String e) { end = e ;}
+	public String getEnd() { return end;}
+
+
+	public void setPhase(String p) { phase = p;}
+	public String getPhase() { return phase ;}
+
+	public void setOrientation(String o) { orientation = o;}
+	public String getOrientation() { return orientation ; }
+
+	public void setScore(String s) { score = s;}
+	public String getScore() { return score ;}
+
+	public void setLabel(String l) { label = l;}
+	public String getLabel() { return label ;}
+
+	public DASGFFGroup getGroup() {return group;	}
+	public void setGroup(DASGFFGroup group) {this.group = group;	}
+
+    public String getTypeCategory() { return typeCategory; }
+    public void setTypeCategory(String typeCategory) {  this.typeCategory = typeCategory; }
+
+    public String getTypeId(){ return typeId; }
+    public void setTypeId(String typeId) { this.typeId = typeId; }
+
+
+}
+
diff --git a/src/org/biojava/servlets/dazzle/datasource/GFFFeatureSource.java b/src/org/biojava/servlets/dazzle/datasource/GFFFeatureSource.java
new file mode 100644
index 0000000..57fd4de
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/GFFFeatureSource.java
@@ -0,0 +1,34 @@
+package org.biojava.servlets.dazzle.datasource;
+
+import org.biojava.servlets.dazzle.Segment;
+
+
+public interface GFFFeatureSource
+    extends DazzleDataSource
+{ 
+
+
+    /** get all features for a given regference
+     * @param seg the requested Segment. E.g. an identifier describing the reference of the
+     * features, a sequence identifier or a protein structure
+     * @param types array of user requested types to display only. null if user did not provide any types, which means response should contain all types.
+     * @return an array of GFFFeature objects
+     * @throws DataSourceException 
+    */
+    
+    public GFFFeature[] getFeatures(Segment seg, String[] types) 
+	throws DataSourceException ;
+
+    
+    /**
+     * Return an ID string for a feature.  This /may/ be <code>null</code>, but
+     * the resulting datasource may then not comply perfectly with DAS 1.0.
+     * @param f the feature id
+     * @return id for this features
+     */
+
+    public String getFeatureID(GFFFeature f);
+	
+}
+
+
diff --git a/src/org/biojava/servlets/dazzle/datasource/HydraGFFFeatureSource.java b/src/org/biojava/servlets/dazzle/datasource/HydraGFFFeatureSource.java
new file mode 100644
index 0000000..b10c6bf
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/HydraGFFFeatureSource.java
@@ -0,0 +1,58 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Aug 15, 2007
+ * 
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+/** serves as a frontend to serving features from multiple backends.
+ * E.g. the DAS / GFF uploads to ensembl, the DAS writeback server.
+ * 
+ *   The actual decision which backend to talk to is based on the dasSourceName
+ *   and is done by the implenting dataSource.
+ * 
+ */ 
+public interface HydraGFFFeatureSource 
+    extends DazzleDataSource
+{ 
+
+
+    /** serves as a frontend to serving features from multiple backends.
+     * E.g. the DAS / GFF uploads to ensembl, the DAS writeback server.
+     * 
+     *   The actual decision which backend to talk to is based on the dasSourceName
+     *   and is done by the implenting dataSource.
+     * 
+     * get all features for a given reference
+     * @param dasSourceName the name of the DAS source that has been called.
+     * @param ref an identifier describing the reference of the
+     * features, eg. a sequence identifier or a protein structure
+     * @return an array of GFFFeature objects
+     * @throws DataSourceException 
+    */
+    
+    public GFFFeature[] getFeatures(String dasSourceName, String ref) 
+	throws DataSourceException ;
+
+	
+}
+
+
diff --git a/src/org/biojava/servlets/dazzle/datasource/InteractionReferenceSource.java b/src/org/biojava/servlets/dazzle/datasource/InteractionReferenceSource.java
new file mode 100644
index 0000000..ec93de0
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/InteractionReferenceSource.java
@@ -0,0 +1,42 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import de.mpg.mpiinf.ag3.dasmi.model.Interaction;
+
+/**
+ * Interface of an interaction reference source
+ * @author Hagen Blankenburg, Max Planck Institute for Informatics
+ *
+ */
+public interface InteractionReferenceSource extends DazzleReferenceSource {
+   
+	/**
+	 * Request interactions from the data source
+	 * @param queries string representations of the query interactors
+	 * @param details property/value combinations of details, null otherwise
+	 * @param operation union or interections, if null intersection will be used
+	 * @return the interactions
+	 */
+	public Interaction[] getInteractions(String[] queries, String[][] details, String operation);
+   
+} 
diff --git a/src/org/biojava/servlets/dazzle/datasource/LdasDataSource.java b/src/org/biojava/servlets/dazzle/datasource/LdasDataSource.java
new file mode 100644
index 0000000..f37b65b
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/LdasDataSource.java
@@ -0,0 +1,572 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.*;
+import java.io.*;
+import java.sql.*;
+import java.net.*;
+import javax.sql.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.biojava.bio.*;
+import org.biojava.bio.symbol.*;
+import org.biojava.bio.seq.*;
+import org.biojava.bio.seq.impl.*;
+import org.biojava.bio.seq.io.*;
+import org.biojava.bio.seq.db.*;
+import org.biojava.utils.*;
+import org.biojava.utils.xml.*;
+import org.biojava.utils.cache.*;
+
+/**
+ * Datasource for pulling annotation out of LDAS tables.
+ * 
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+public class LdasDataSource extends AbstractDataSource implements DazzleDataSource {
+    private static final int TILE_THRESHOLD = 5000;
+    private static final int TILE_SIZE = 200000;
+    private String mapMaster;
+    private String dbURL;
+    private String dbUser;
+    private String dbPass;
+    private String linkoutPrefix;
+
+    private DataSource connectionPool;
+    private CacheMap featureSets = new FixedSizeMap(30);
+    private Cache tileCache = new FixedSizeCache(30);
+
+    private Map typesByID = null;
+    private Map sourcesByID = null;
+
+    private SequenceDBLite reference;
+    
+    public Sequence getSequence(String ref)
+        throws DataSourceException, NoSuchElementException
+    {
+        try {
+            Sequence seq = reference.getSequence(ref);
+            int dummy = seq.length();  // ensure fetching...
+            return seq;
+        } catch (IllegalIDException ex) {
+            return null;
+        } catch (Exception ex) {
+            throw new NoSuchElementException("Bad reference sequence: " + ref);
+        }
+    }
+    
+    public String getLandmarkVersion(String ref) 
+        throws DataSourceException, NoSuchElementException
+    {
+        if (getSequence(ref) != null) {
+            return "unknown";
+        } else {
+            return null;
+        }
+    }
+    
+    public String getDataSourceType() {
+        return "ldas";
+    }
+    
+    public String getDataSourceVersion() {
+        return "1.00";
+    }
+    
+    public void setDbURL(String s) {
+        this.dbURL = s;
+    }
+
+    public String getDbURL() {
+        return this.dbURL;
+    }
+  
+    public void setDbUser(String s) {
+        dbUser = s;
+    }
+  
+    public String getDbUser() {
+        return this.dbUser;
+    }
+  
+    public void setDbPass(String s) {
+        dbPass = s;
+    }
+
+    public void setMapMaster(String s) {
+        this.mapMaster = s;
+    }
+
+    public String getMapMaster() {
+        return mapMaster;
+    }
+    
+    public void setLinkoutPrefix(String s) {
+        this.linkoutPrefix = s;
+    }
+
+    public void init(ServletContext ctx) 
+        throws DataSourceException
+    {
+        super.init(ctx);
+        
+        try {
+            connectionPool = JDBCPooledDataSource.getDataSource(
+                "org.gjt.mm.mysql.Driver",
+                dbURL,
+                dbUser,
+                dbPass
+            );
+            
+            SequenceDB refSeqs = new HashSequenceDB();
+            
+            Connection con = connectionPool.getConnection();
+            PreparedStatement get_components = con.prepareStatement(
+                "select fref, fstart, fstop from fdata, ftype where ftype.ftypeid = fdata.ftypeid and ftype.fmethod = 'Component'"
+            );
+            ResultSet rs = get_components.executeQuery();
+            while (rs.next()) {
+                String fref = rs.getString(1);
+                int fstart = rs.getInt(2);
+                int fstop = rs.getInt(3);
+                refSeqs.addSequence(
+                    new SimpleSequence(
+                        new DummySymbolList(DNATools.getDNA(), fstop),
+                        fref,
+                        fref,
+                        Annotation.EMPTY_ANNOTATION
+                    )
+                );
+            }
+            rs.close();
+            get_components.close();
+            con.close();
+            
+            reference = refSeqs;
+        } catch (Exception e) {
+            throw new DataSourceException(e, "Coundn't initialize LDAS datasource");
+        }
+    }
+
+
+    protected Map getTypesByID() {
+        if (typesByID == null) {
+            initTypes();
+        }
+        return typesByID;
+    }
+    
+    protected Map getSourcesByID() {
+        if (sourcesByID == null) {
+            initTypes();
+        }
+        return sourcesByID;
+    }
+    
+    private void initTypes() {
+        Map _types = new HashMap();
+        Map _sources = new HashMap();
+        try {
+            Connection conn = connectionPool.getConnection();
+            PreparedStatement get_types = conn.prepareStatement(
+                "select ftypeid, fmethod, fsource " +
+                "  from ftype"
+            );
+            ResultSet rs = get_types.executeQuery();
+            while (rs.next()) {
+                int type = rs.getInt(1);
+                String method = rs.getString(2);
+                String source = rs.getString(3);
+                Integer typeKey = new Integer(type);
+                _types.put(typeKey, method + ':' + source);
+                _sources.put(typeKey, method);
+            }
+            rs.close();
+            get_types.close();
+            conn.close();
+        } catch (SQLException ex) {
+            log("Couldn't fetch types from LDAS", ex);
+        }
+        typesByID = _types;
+        sourcesByID = _sources;
+    }
+    
+    public FeatureHolder getFeatures(String ref)
+	    throws DataSourceException, NoSuchElementException
+    {
+        FeatureHolder features = (FeatureHolder) featureSets.get(ref);
+        if (features != null) {
+            return features;
+        }
+        
+        Sequence rawSeq = getSequence(ref);
+        if (rawSeq == null) {
+            return null;
+        }
+        
+        int count = 0;
+        
+        try {
+            Connection con = connectionPool.getConnection();
+            Statement st = con.createStatement();
+            ResultSet rs = st.executeQuery("select count(*) from fdata where fref = '" + ref + "'");
+            if (rs.next()) {
+                count = rs.getInt(1);
+            }
+            rs.close();
+            st.close();
+            con.close();
+        } catch (SQLException ex) {
+            throw new DataSourceException(ex, "Couldn't check features in database");
+        }
+        
+        if (count == 0) {
+            features = FeatureHolder.EMPTY_FEATURE_HOLDER;
+        } else if (count < TILE_THRESHOLD) {
+            ViewSequence vs = new ViewSequence(rawSeq);
+            try {
+                fetchFeatures(vs, ref, -1, -1);
+            } catch (Exception ex) {
+                throw new DataSourceException(ex, "Exception fetching features");
+            }
+            features = vs.getAddedFeatures();
+        } else {
+            features = new TiledFeatures(rawSeq, TILE_SIZE); 
+        }
+        
+        featureSets.put(ref, features);
+        return features;
+    }
+
+    public String getFeatureID(Feature f) {
+        if (f instanceof ComponentFeature) {
+            return ((ComponentFeature) f).getComponentSequence().getName();
+        } else {
+            Annotation ann = f.getAnnotation();
+            StringBuffer sb = new StringBuffer();
+            if (ann.keys().contains("group_class")) {
+                sb.append(ann.getProperty("group_class"));
+                sb.append(':');
+            }
+            if (ann.keys().contains("group_name")) {
+                sb.append(ann.getProperty("group_name"));
+                sb.append('/');
+            }
+            if (ann.keys().contains("id")) {
+                sb.append(ann.getProperty("id"));
+            }
+            return sb.toString();
+        }
+    }
+    
+    public String getFeatureLabel(Feature f) {
+        Annotation ann = f.getAnnotation();
+        if (ann.containsProperty("group_name")) {
+            return (String) ann.getProperty("group_name");
+        } else {
+            return null;
+        }
+    }
+
+    public Set getAllTypes() 
+    {
+        return new HashSet(getTypesByID().values());
+    }
+
+    public String getTypeDescription(String type) {
+        return null;
+    }
+    
+    public Map getLinkouts(Feature f) {
+        Map links = new SmallMap();
+        if (linkoutPrefix != null && f.getAnnotation().containsProperty("group_name")) {
+            String group_name = (String) f.getAnnotation().getProperty("group_name");
+            links.put(group_name, linkoutPrefix + group_name);
+        }
+        return links;
+    }
+    
+    public List getGroups(Feature f) {
+        String group_class = null;
+        String group_name = null;
+        Annotation ann = f.getAnnotation();
+        if (ann.containsProperty("group_class")) {
+            group_class = (String) ann.getProperty("group_class");
+        }
+        if (ann.containsProperty("group_name")) {
+            group_name = (String) ann.getProperty("group_name");
+        }
+        if (group_name != null) {
+            return Collections.singletonList(
+                new DASGFFGroup(group_class + ':' + group_name, group_class)
+            );
+        } else {
+            return Collections.EMPTY_LIST;
+        }
+    }
+    
+    public String getScore(Feature f) {
+        Annotation ann = f.getAnnotation();
+        if (ann.containsProperty("score")) {
+            return ann.getProperty("score").toString();
+        } else {
+            return null;
+        }
+    }
+
+    public void fetchFeatures(FeatureHolder seq, String ref, int min, int max)
+	    throws BioException, ChangeVetoException
+    {
+        // System.err.println("Fetching features from " + min + " to " + max);
+        
+        try {
+            String featureQuery =
+                "select " +
+                "  fdata.fid, fdata.fref, fdata.fstart, fdata.fstop, fdata.ftypeid, fdata.fscore, fdata.fstrand, fdata.fphase, fgroup.gclass, fgroup.gname" +
+                "  from fdata, fgroup " +
+                " where fref = '" + ref + "' and fgroup.gid = fdata.gid";
+
+            if (min >= 0) {
+                // Fetch by position
+                featureQuery = featureQuery + " and fstart <= '" + max +"' and fstop >= '" + min + "'";
+            }
+	    
+            Connection con = connectionPool.getConnection();
+	        Statement state = con.createStatement();
+            ResultSet rs = state.executeQuery(featureQuery);
+	    
+            StrandedFeature.Template templ = new StrandedFeature.Template();
+	    
+            while(rs.next()) {
+                int id = rs.getInt(1);
+                String seqName = rs.getString(2);
+                int fmin = rs.getInt(3);
+                int fmax = rs.getInt(4);
+                Integer typeKey = new Integer(rs.getInt(5));
+                String score = rs.getString(6);
+                String strand = rs.getString(7);
+                String phase = rs.getString(8);
+                String gclass = rs.getString(9);
+                String gname = rs.getString(10);
+            
+                templ.location = new RangeLocation(fmin, fmax);
+            
+                StrandedFeature.Strand strandObj = null;
+                if (strand == null) {
+                    strandObj = StrandedFeature.UNKNOWN;
+                } else if ("+".equals(strand)) {
+                    strandObj = StrandedFeature.POSITIVE;
+                } else if ("-".equals(strand)) {
+                    strandObj = StrandedFeature.NEGATIVE;
+                }
+                
+                templ.strand = strandObj;
+                templ.type = (String) getTypesByID().get(typeKey);
+                templ.source = (String) getSourcesByID().get(typeKey);
+                Annotation ann = new SmallAnnotation();
+                ann.setProperty("id", new Integer(id));
+                if (score != null && score.length() > 0) {
+                    ann.setProperty("score", score);
+                }
+                if (phase != null && phase.length() > 0) {
+                    ann.setProperty("phase", new Integer(phase));
+                }
+                ann.setProperty("group_class", gclass);
+                ann.setProperty("group_name", gname);
+                templ.annotation = ann;
+                
+                if (templ.source.equalsIgnoreCase("Component")) {
+                    // This is a magic feature which we don't want to serve up...
+                } else {
+                    seq.createFeature(templ);
+                }
+            }
+            rs.close();
+            state.close();
+            con.close();
+        } catch (SQLException sqle) {
+            throw new BioException(
+                sqle,
+                "Database access failed when reading generic features for "
+                + ref
+            );
+        } 
+    }
+
+    private class TiledFeatures implements FeatureHolder {
+        private CacheReference[] featureSets;
+        private Location[] tileSpans;
+        private SimpleFeatureHolder spanningFeatures = new SimpleFeatureHolder();
+        private MergeFeatureHolder allFeatures;
+        private Sequence refSeq;
+
+    
+        public FeatureFilter getSchema() {
+            return new FeatureFilter.And(FeatureFilter.top_level, FeatureFilter.leaf);
+        }
+    
+	    TiledFeatures(Sequence refSeq, int tileSize) {
+            this.refSeq = refSeq;
+            int numTiles = (int) Math.ceil((1.0 * refSeq.length()) / tileSize);
+            featureSets = new CacheReference[numTiles];
+            tileSpans = new Location[numTiles];
+            
+            allFeatures = new MergeFeatureHolder();
+            try {
+                for (int i = 0; i < numTiles; ++i) {
+                    tileSpans[i] = new RangeLocation(i * tileSize + 1, 
+                    Math.min(refSeq.length(), (i + 1) * tileSize));
+                    allFeatures.addFeatureHolder(new Tile(i));
+                }
+                allFeatures.addFeatureHolder(spanningFeatures);
+            } catch (ChangeVetoException ex) {
+                throw new BioError(ex, "Assertion failure: couldn't modify MargeFeatureHolder");
+            }
+        }
+
+        public Iterator features() {
+            return allFeatures.features();
+        }
+
+        public FeatureHolder filter(FeatureFilter ff) {
+            // System.err.println("Filtering: " + ff);
+            return allFeatures.filter(ff);
+        }
+    
+	    public FeatureHolder filter(FeatureFilter ff, boolean recurse) {
+            // System.err.println("Filtering: " + ff);
+            return allFeatures.filter(ff, recurse);
+        }
+
+        public int countFeatures() {
+            return allFeatures.countFeatures();
+        }
+
+        public boolean containsFeature(Feature f) {
+            return allFeatures.containsFeature(f);
+        }
+
+        public Feature createFeature(Feature.Template templ)
+	        throws ChangeVetoException
+        {
+            throw new ChangeVetoException("NO");
+        }
+
+        public void removeFeature(Feature f) 
+	        throws ChangeVetoException
+        {
+            throw new ChangeVetoException("NO");
+        }
+
+        public void addChangeListener(ChangeListener cl) {}
+        public void addChangeListener(ChangeListener cl, ChangeType ct) {}
+        public void removeChangeListener(ChangeListener cl) {}
+        public void removeChangeListener(ChangeListener cl, ChangeType ct) {}
+        public boolean isUnchanging(ChangeType ct) { return true; }
+	
+	    private class Tile implements FeatureHolder {
+            private int tileNum;
+
+            public FeatureFilter getSchema() {
+                return new FeatureFilter.And(
+                    new FeatureFilter.ContainedByLocation(tileSpans[tileNum]),
+                    new FeatureFilter.And(FeatureFilter.top_level, FeatureFilter.leaf)
+                );
+            }
+        
+	        Tile(int tileNum) {
+                this.tileNum = tileNum;
+            }
+
+            private synchronized SimpleFeatureHolder getFeatures() {
+                if (featureSets[tileNum] != null) {
+                    SimpleFeatureHolder fh = (SimpleFeatureHolder) featureSets[tileNum].get();
+                    if (fh != null) {
+                        return fh;
+                    }
+                }
+
+                // System.err.println("Fetching tile: " + tileNum);
+
+                SimpleFeatureHolder fh = new SimpleFeatureHolder();
+                featureSets[tileNum] = tileCache.makeReference(fh);
+                try {
+                    fetchFeatures(this, refSeq.getName(), tileSpans[tileNum].getMin(), tileSpans[tileNum].getMax());
+                } catch (Exception ex) {
+                    throw new BioRuntimeException(ex);
+                }
+                return fh;
+            }
+
+            public Iterator features() {
+                return getFeatures().features();
+            }
+        
+            public FeatureHolder filter(FeatureFilter ff) {
+                return getFeatures().filter(ff);
+            }
+
+            public FeatureHolder filter(FeatureFilter ff, boolean recurse) {
+                return getFeatures().filter(ff, recurse);
+            }
+
+            public int countFeatures() {
+                return getFeatures().countFeatures();
+            }
+
+            public boolean containsFeature(Feature f) {
+                return getFeatures().containsFeature(f);
+            }
+
+            public Feature createFeature(Feature.Template templ)
+	            throws ChangeVetoException, BioException
+            {
+                Feature f = FeatureImpl.DEFAULT.realizeFeature(refSeq, refSeq, templ);
+                if (LocationTools.contains(tileSpans[tileNum], f.getLocation())) {
+                    getFeatures().addFeature(f);
+                } else {
+                    if (!spanningFeatures.containsFeature(f)) {
+                        spanningFeatures.addFeature(f);
+                    }
+                }
+                return f;
+            }
+	    
+	        public void removeFeature(Feature f) 
+                throws ChangeVetoException
+            {
+                throw new ChangeVetoException("NO");
+            }
+
+            public void addChangeListener(ChangeListener cl) {}
+            public void addChangeListener(ChangeListener cl, ChangeType ct) {}
+            public void removeChangeListener(ChangeListener cl) {}
+            public void removeChangeListener(ChangeListener cl, ChangeType ct) {}
+            public boolean isUnchanging(ChangeType ct) { return true; }
+        }
+    }    
+}
+
diff --git a/src/org/biojava/servlets/dazzle/datasource/PhobiusExampleSource.java b/src/org/biojava/servlets/dazzle/datasource/PhobiusExampleSource.java
new file mode 100644
index 0000000..f8f432b
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/PhobiusExampleSource.java
@@ -0,0 +1,181 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on May 21, 2007
+ * 
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletContext;
+
+import org.biojava.servlets.dazzle.Segment;
+
+public class PhobiusExampleSource  extends AbstractGFFFeatureSource {
+
+	String fileName;
+	String dataSourceName;
+	Map data;
+	String exampleId;
+
+	
+	
+	public String getExampleId() {
+		return exampleId;
+	}
+
+
+
+	public void setExampleId(String exampleId) {
+		this.exampleId = exampleId;
+	}
+
+
+
+	public void setFileName(String s) {
+		fileName = s;
+	}
+
+
+
+	public String getDataSourceName() {
+		return dataSourceName;
+	}
+
+	public void setDataSourceName(String dataSourceName) {
+		this.dataSourceName = dataSourceName;
+	}
+
+
+	private void parsePhobiusData(ServletContext ctx) throws IOException{
+		BufferedReader br = new BufferedReader(new InputStreamReader(ctx.getResourceAsStream(fileName)));
+		List oData = new ArrayList();
+		List sData = new ArrayList();
+		List mData = new ArrayList();
+		List iData = new ArrayList();
+		List hData = new ArrayList();
+		
+		for(String line = br.readLine(); line != null; line = br.readLine()) {
+			if ( line.charAt(0) == '#')
+				continue;
+			StringTokenizer token = new StringTokenizer(line,"\t");
+			if (token.countTokens() < 7) {
+				throw new IOException("file does not match expected format at line " + line + " it has got" +  token.countTokens() + " tokens!");
+			}
+			// pos aa	i	o	M	S
+			String pos = token.nextToken();
+			String aa  = token.nextToken();
+			String i   = token.nextToken();
+			String o   = token.nextToken();
+			String m   = token.nextToken();
+			String s   = token.nextToken();
+			String h   = token.nextToken();
+			
+			
+			GFFFeature of = new GFFFeature();
+			of.setStart(pos);
+			of.setEnd(pos);
+			of.setMethod("Phobius");
+			of.setName("Phobius O - score");
+			of.setLink("http://phobius.cgb.ki.se");
+			of.setScore(o);
+			of.setType(of.getName());		
+
+			GFFFeature sf = (GFFFeature) of.clone();
+			sf.setName("Phobius S - score");
+			sf.setScore(s);
+			sf.setType(sf.getName());
+
+			GFFFeature mf = (GFFFeature) of.clone();
+			mf.setName("Phobius M - score");
+			mf.setScore(m);
+			mf.setType(mf.getName());
+			
+			GFFFeature iif = (GFFFeature) of.clone();
+			iif.setName("Phobius i - score");
+			iif.setScore(i);
+			iif.setType(iif.getName());
+			
+			GFFFeature hydro = (GFFFeature) of.clone();
+			hydro.setMethod("KyleDoolittle");
+			hydro.setName("hydrophobicity");
+			hydro.setLink("");
+			hydro.setScore(h);
+			hydro.setType(hydro.getName());
+			
+			oData.add(of);
+			sData.add(sf);
+			mData.add(mf);
+			iData.add(iif);
+			hData.add(hydro);
+		}
+
+		oData.addAll(sData);
+		oData.addAll(mData);
+		oData.addAll(iData);
+		oData.addAll(hData);
+		data.put(exampleId,oData);
+
+	}
+
+
+	public void init(ServletContext ctx) 
+	throws DataSourceException
+	{
+		data = new HashMap();
+		super.init(ctx);
+		try {
+			//parse the phobius result file
+			parsePhobiusData(ctx);
+
+		} catch (Exception ex) {
+			throw new DataSourceException(ex, "Couldn't load data file");
+		}
+	}
+
+
+
+
+	public GFFFeature[] getFeatures(Segment seg,String[] types) throws DataSourceException {
+
+		// here:  ignore filtering by type...
+		
+		String ref = seg.toString();
+		List feats = new ArrayList();
+
+		if ( data.containsKey(ref)) {
+			feats = (List) data.get(ref);
+		}
+
+		return (GFFFeature[]) feats.toArray(new GFFFeature[feats.size()]);
+
+	}
+
+
+
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/ProxyDataSource.java b/src/org/biojava/servlets/dazzle/datasource/ProxyDataSource.java
new file mode 100644
index 0000000..a55eeac
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/ProxyDataSource.java
@@ -0,0 +1,205 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.*;
+import java.net.*;
+import java.io.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.biojava.utils.*;
+import org.biojava.utils.cache.*;
+import org.biojava.bio.*;
+import org.biojava.bio.seq.*;
+import org.biojava.bio.seq.db.*;
+import org.biojava.bio.seq.io.*;
+import org.biojava.bio.symbol.*;
+
+import org.biojava.bio.program.das.*;
+import org.biojava.bio.program.gff.*;
+
+import org.biojava.utils.xml.*;
+
+/**
+ * Annotation datasource backed by a remote DAS source.
+ *
+ * @author Thomas Down
+ * @version 0.91
+ */
+
+public class ProxyDataSource extends AbstractDataSource implements DazzleDataSource {
+    private String mapMaster;
+    private String remoteAnnotationSource;
+    private URL mapMasterURL;
+    private URL remoteAnnotationURL;
+
+    private DASSequenceDB dsdb;
+    private CacheMap      recentSeqs = new FixedSizeMap(100);
+
+    private Set allTypes;
+
+    public String getDataSourceType() {
+        return "proxy";
+    }
+    
+    public String getDataSourceVersion() {
+        return "0.91";
+    }
+    
+    public void setMapMaster(String s) {
+	this.mapMaster = s;
+    }
+
+    public String getMapMaster() {
+	return mapMaster;
+    }
+
+    public void setRemoteAnnotationSource(String s) {
+	remoteAnnotationSource = s;
+    }
+
+    public void init(ServletContext ctx) 
+        throws DataSourceException
+    {
+        super.init(ctx);
+        try {
+            mapMasterURL = new URL(mapMaster);
+            dsdb = new DASSequenceDB(mapMasterURL);
+            remoteAnnotationURL = new URL(remoteAnnotationSource);
+        } catch (Exception ex) {
+            throw new DataSourceException(ex, "Couldn't connect to map master");
+        }
+    }
+    
+    public Sequence getSequence(String ref)
+	throws DataSourceException, NoSuchElementException
+    {
+	try {
+	    DASSequence ds = (DASSequence) recentSeqs.get(ref);
+	    if (ds != null) {
+		return ds;
+	    }    
+
+	    ds = (DASSequence) dsdb.allEntryPointsDB().getSequence(ref);
+
+	    // System.err.println("Processing " + ds.getName());
+	    boolean containsAnno = false;
+	    Set oldAnnotation = new HashSet(ds.dataSourceURLs());
+	    for (Iterator i = oldAnnotation.iterator(); i.hasNext(); ) {
+		URL au = (URL) i.next();
+		// System.err.println(au.toString());
+		if (! (au.equals(remoteAnnotationURL))) {
+		    ds.removeAnnotationSource(au);
+		    // System.err.println("Removing");
+		} else {
+		    containsAnno = true;
+		    // System.err.println("Keeping");
+		}
+	    }
+
+	    if (!containsAnno) {
+		ds.addAnnotationSource(remoteAnnotationURL);
+	    }
+
+	    recentSeqs.put(ref, ds);
+	    return ds;
+	} catch (IllegalIDException ex) {
+	    throw new NoSuchElementException("Bad reference sequence: " + ref);
+        } catch (BioException ex) {
+	    throw new DataSourceException(ex, "Error getting reference sequence");
+	} catch (ChangeVetoException ex) {
+	    throw new DataSourceException(ex, "Unexpected change veto");
+	}
+    }
+
+
+    public String getLandmarkVersion(String ref) 
+	    throws DataSourceException, NoSuchElementException
+    {
+        Sequence seq = getSequence(ref);
+        try {
+            return seq.getAnnotation().getProperty(DASSequence.PROPERTY_SEQUENCEVERSION).toString();
+        } catch (NoSuchElementException ex) {
+            return "unknown";
+        }
+    }
+
+    public FeatureHolder getFeatures(String ref)
+	    throws NoSuchElementException, DataSourceException
+    {
+        return getSequence(ref).filter(new FeatureFilter.ByAnnotation(DASSequence.PROPERTY_ANNOTATIONSERVER, remoteAnnotationURL), true);
+    }
+
+    public String getFeatureID(Feature f) {
+        Annotation anno = f.getAnnotation();
+        if (anno.containsProperty(DASSequence.PROPERTY_FEATUREID)) {
+            Object idProp = anno.getProperty(DASSequence.PROPERTY_FEATUREID);
+            if (idProp instanceof List) {
+                return ((List) idProp).get(0).toString();
+            } else {
+                return idProp.toString();
+            }
+        }
+        
+        return null;
+    }
+    
+    public String getFeatureLabel(Feature f) {
+        return null;
+    }
+
+    public Set getAllTypes() {
+        if (allTypes == null) {
+            try {
+                allTypes = DAS.getTypes(remoteAnnotationURL);
+            } catch (BioException ex) {
+                throw new BioRuntimeException(ex, "Communications error with DAS server");
+            }
+        } 
+        
+        return allTypes;
+    }
+
+    public String getTypeDescription(String type) {
+        return null;
+    }
+
+    public Map getLinkouts(Feature f) {
+        Map anno = f.getAnnotation().asMap();
+        Map links = new HashMap();
+        for (Iterator i = anno.entrySet().iterator(); i.hasNext(); ) {
+            Map.Entry me = (Map.Entry) i.next();
+            String key = me.getKey().toString();
+            if (key.startsWith("href:")) {
+                Object o = me.getValue();
+                if (o instanceof List) {
+                    links.put(key.substring(5), ((List) o).get(0));
+                } else {
+                    links.put(key.substring(5), o);
+                }
+            }
+        }
+        
+        return links;
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/ProxyReferenceSource.java b/src/org/biojava/servlets/dazzle/datasource/ProxyReferenceSource.java
new file mode 100644
index 0000000..aa0a563
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/ProxyReferenceSource.java
@@ -0,0 +1,168 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.*;
+import java.net.*;
+import java.io.*;
+
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.biojava.utils.*;
+import org.biojava.utils.cache.*;
+import org.biojava.bio.*;
+import org.biojava.bio.seq.*;
+import org.biojava.bio.seq.db.*;
+import org.biojava.bio.seq.io.*;
+import org.biojava.bio.symbol.*;
+
+import org.biojava.bio.program.das.*;
+import org.biojava.bio.program.gff.*;
+
+import org.biojava.utils.xml.*;
+
+/**
+ * Reference datasource backed by a remote DAS source.
+ *
+ * @author Thomas Down
+ * @version 0.91
+ */
+
+public class ProxyReferenceSource extends AbstractDataSource implements DazzleReferenceSource {
+    private String remoteReferenceSource;
+    private URL remoteReferenceURL;
+
+    private DASSequenceDB dsdb;
+    private CacheMap recentSeqs = new FixedSizeMap(100);
+
+    private Set allTypes;
+
+    public String getDataSourceType() {
+        return "proxy";
+    }
+    
+    public String getDataSourceVersion() {
+        return "0.91";
+    }
+    
+    public String getMapMaster() {
+        return null;
+    }
+
+    public void setRemoteReferenceSource(String s) {
+        remoteReferenceSource = s;
+    }
+
+    public void init(ServletContext ctx) 
+        throws DataSourceException
+    {
+        super.init(ctx);
+        try {
+            remoteReferenceURL = new URL(remoteReferenceSource);
+            dsdb = new DASSequenceDB(remoteReferenceURL);
+        } catch (Exception ex) {
+            throw new DataSourceException(ex, "Couldn't connect to map master");
+        }
+    }
+    
+    public Sequence getSequence(String ref)
+	    throws DataSourceException, NoSuchElementException
+    {
+        try {
+            DASSequence ds = (DASSequence) recentSeqs.get(ref);
+            if (ds != null) {
+                return ds;
+            }        
+
+            ds = (DASSequence) dsdb.allEntryPointsDB().getSequence(ref);
+            recentSeqs.put(ref, ds);
+            return ds;
+        } catch (IllegalIDException ex) {
+            throw new NoSuchElementException("Bad reference sequence: " + ref);
+        } catch (BioException ex) {
+            throw new DataSourceException(ex, "Error getting reference sequence");
+        }
+    }
+
+
+    public String getLandmarkVersion(String ref) 
+	    throws DataSourceException, NoSuchElementException
+    {
+        Sequence seq = getSequence(ref);
+        try {
+            return seq.getAnnotation().getProperty(DASSequence.PROPERTY_SEQUENCEVERSION).toString();
+        } catch (NoSuchElementException ex) {
+            return "unknown";
+        }
+    }
+    
+    public Set getEntryPoints() {
+        return dsdb.ids();
+    }
+    
+    public String getFeatureID(Feature f) {
+        Annotation anno = f.getAnnotation();
+        if (anno.containsProperty(DASSequence.PROPERTY_FEATUREID)) {
+            Object idProp = anno.getProperty(DASSequence.PROPERTY_FEATUREID);
+            if (idProp instanceof List) {
+                return ((List) idProp).get(0).toString();
+            } else {
+                return idProp.toString();
+            }
+        }
+
+        return null;
+    }
+    
+
+    public Set getAllTypes() {
+        if (allTypes == null) {
+            try {
+                allTypes = DAS.getTypes(remoteReferenceURL);
+            } catch (BioException ex) {
+                throw new BioRuntimeException(ex, "Communications error with DAS server");
+            }
+        } 
+
+        return allTypes;
+    }
+
+
+    public Map getLinkouts(Feature f) {
+        Map anno = f.getAnnotation().asMap();
+        Map links = new HashMap();
+        for (Iterator i = anno.entrySet().iterator(); i.hasNext(); ) {
+            Map.Entry me = (Map.Entry) i.next();
+            String key = me.getKey().toString();
+            if (key.startsWith("href:")) {
+                Object o = me.getValue();
+                if (o instanceof List) {
+                    links.put(key.substring(5), ((List) o).get(0));
+                } else {
+                    links.put(key.substring(5), o);
+                }
+            }
+        }
+
+        return links;
+    }
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/SIFReferenceSource.java b/src/org/biojava/servlets/dazzle/datasource/SIFReferenceSource.java
new file mode 100644
index 0000000..8fac367
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/SIFReferenceSource.java
@@ -0,0 +1,480 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Set;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+
+import javax.servlet.ServletContext;
+
+import org.biojava.bio.seq.Sequence;
+import org.biojava.bio.seq.FeatureHolder;
+
+import de.mpg.mpiinf.ag3.dasmi.model.Interaction;
+import de.mpg.mpiinf.ag3.dasmi.model.Detail;
+import de.mpg.mpiinf.ag3.dasmi.model.Interactor;
+import de.mpg.mpiinf.ag3.dasmi.model.Participant;
+
+/**
+ * Simple data source that parses interactions from a SIF file 
+ * (http://www.cytoscape.org/cgi-bin/moin.cgi/Cytoscape_User_Manual/Network_Formats)
+ *
+ * For instructions how to set up a SIF reference source, please see http://biojava.org/wiki/Dazzle
+ * 
+ * @author Hagen Blankenburg, Max Planck Institute for Informatics
+ *
+ */
+public class SIFReferenceSource extends AbstractDataSource implements InteractionReferenceSource {
+	private String mapMaster = null;
+    private String coordSys = null;
+    private String interactorDbSource = null;
+    private String interactorDbSourceCvId = null;
+    private Set<String> entryPoints = null;
+    private List<String[]> tmpInteractions = null;
+    private String fileName = null;
+    private String attributeFiles = null;
+    private Map<String,String[]> attributes = null;
+    
+         
+    /***
+     * 
+     */
+    public void init(ServletContext ctx) throws DataSourceException{
+    	super.init(ctx);
+    	parseAttributes(this.attributeFiles);
+    	parseInteractions(this.fileName);
+	}
+    
+	
+	/**
+	 * Clean up
+	 */
+	protected void finalize() throws Throwable {
+		this.tmpInteractions = null;
+		super.finalize();
+	}
+	
+
+	/**
+	 * Checks if the ids given in the queries array are known to be interacting. If interactions
+	 * can be found (one query --> all interactions where this query takes part, two queries -->
+	 * all interacitons where both take part at the same time, more than two queries --> same as 
+	 * two queries, rest of the queries truncated)
+	 * @return The interactions found, null if none could be found
+	 */
+	public Interaction[] getInteractions(String[] queries, String[][] details, String operation){
+    	List<Interaction> interactions = new ArrayList<Interaction>();
+    	Iterator<String[]> it = tmpInteractions.iterator();
+    	while (it.hasNext()){
+    		String[] pair = it.next();
+    		boolean found = false;
+    		if (queries.length == 1){
+    			if (pair[0].equals(queries[0]) || pair[1].equals(queries[0])){
+    				found = true;
+    			}
+    		}else{
+    			if (operation != null && operation.equals("INTERSECTION")){
+    				if ((pair[0].equals(queries[0]) && pair[1].equals(queries[1])) 
+    						|| (pair[0].equals(queries[1]) && pair[1].equals(queries[0]))){
+    					found = true;
+    				}	
+    			}else{
+    				for (int i = 0; i < queries.length; i++){
+    				if (pair[0].equals(queries[i]) || pair[1].equals(queries[i]))
+    					found = true;
+    				}
+    			}
+    		}
+    		if (found == true){
+    			Interaction interaction = null;
+    			if (pair[0].compareTo(pair[1]) > 0){
+    				interaction = (Interaction) createElement("Interaction", pair[1]+"-"+pair[0]);
+    			}else{
+    				interaction = (Interaction) createElement("Interaction", pair[0]+"-"+pair[1]);
+    			}
+    			if (details != null){
+    				boolean remove = true;
+	    			// check if the interaction should not be returned due to detail filtering
+	    			Iterator<Detail> detIt = interaction.getDetails().iterator();
+	    			// check all details of the interaction
+	    			while (detIt.hasNext()){
+	    				Detail det = detIt.next();
+	    				// and for each detail, check if it is equal to one of the filter details
+	    				for (int i = 0; i < details.length; i++){
+	    					// if the property is the same
+	    					if (det.getProperty().equalsIgnoreCase(details[i][0])){
+	    						// check if the value is also the same, if its provided
+	    						if (details[i][1] != null){
+	    							if (det.getValue().equalsIgnoreCase(details[i][1])){
+	    								remove = false;
+	    							}
+	    						}else{
+	    							remove = false;
+	    						}
+	    					}
+	    				}
+	    			}
+    				if (remove == true){
+    					continue;
+    				}
+    			}
+    			
+    			Interactor interactor = (Interactor) createElement("Interactor", pair[0]);
+		    	Participant part = new Participant();
+		    	part.setInteractor(interactor);
+		    	interaction.addParticipant(part);
+		    	
+		    	interactor = (Interactor) createElement("Interactor", pair[1]);
+		    	part = new Participant();
+		    	part.setInteractor(interactor);
+		    	interaction.addParticipant(part);
+		    	interactions.add(interaction);
+    		}
+    	}
+    	if (interactions.size() == 0){
+    		return null;
+    	}else{
+    		return (Interaction[])interactions.toArray(new Interaction[interactions.size()]);
+    	}
+    }
+	
+	
+	/**
+	 * Parses node and edge attributes (http://www.cytoscape.org/cgi-bin/moin.cgi/Cytoscape_User_Manual/Attributes)
+	 * from the given files and stores them in an interanal data structure. The attributes will be converted into
+	 * DETAIL elements in the getInteraction method 
+	 * @param fileString Node and edge attribute files separated by semi-colon, e.g. "C:/attr1.noa;D:/attr2.eda"
+	 * @throws DataSourceException
+	 */
+	private void parseAttributes(String fileString) throws DataSourceException{
+		BufferedReader input = null;
+		if (this.attributes == null){
+			this.attributes = new HashMap<String, String[]>();
+		}
+		if (fileString == null){
+			return;
+		}
+		String[] files = fileString.split(";");
+		// for each attribute file ...
+		for (int i = 0; i < files.length; i++){
+			File file = new File(files[i]);
+			String attribute = null;
+			try {
+		    	input = new BufferedReader( new FileReader(file) );
+		    	String line = null; 
+		    	// the first line is the name of the attribute
+		    	if ((attribute = input.readLine()) == null){
+		    		break;
+		    	}
+		    	// the rest of the file has the form "identifier = attribute value"
+		    	while (( line = input.readLine()) != null){
+			    	String [] temp = null;
+			    	temp = line.split(" = ");
+			    	temp[0] = temp[0].trim();
+			    	temp[1] = temp[1].trim();
+			    	// check if the foremost part is the identifier of an interaction
+			    	String[] parts = temp[0].split(" ");
+			    	if (parts.length == 3){
+			    		if (parts[0].compareTo(parts[2]) > 0){
+			    			temp[0] = parts[2]+"-"+parts[0];
+			    		}else{
+			    			temp[0] = parts[0]+"-"+parts[2];
+			    		}
+			    	}
+			    	
+			    	// if the id already has some stored attributes add the current
+			    	if (this.attributes.containsKey(temp[0])){
+			    		String[] attr = this.attributes.get(temp[0]);
+			    		String[] newAttr = new String[attr.length + 2];
+			    		System.arraycopy( attr, 0, newAttr, 0, attr.length );
+			    		newAttr[attr.length] = attribute;
+			    		newAttr[attr.length + 1] = temp[1];
+			    		this.attributes.put(temp[0], newAttr);
+			    		attr = null;
+			    	} // no attributes for this id so far, thus create new
+			    	else{
+			    		String[] attr = new String[2];
+			    		attr[0] = attribute;
+			    		attr[1] = temp[1];
+			    		this.attributes.put(temp[0], attr);
+			    	}
+			   	}
+		    }
+		    catch (FileNotFoundException ex) {
+		    	ex.printStackTrace();
+		    	throw new DataSourceException("A node attribute file cannot be found in the specified location");
+		    }
+		    catch (IOException ex){
+		    	ex.printStackTrace();
+		    }
+		    finally {
+		    	try {
+		    		if (input!= null) {
+		    			input.close();
+		    		}
+		    	}
+		    	catch (IOException ex) {
+		    		ex.printStackTrace();
+		    	}
+		    }
+		}
+	}
+
+    
+    
+    /**
+     * Parse interaction from a SIF file (http://www.cytoscape.org/cgi-bin/moin.cgi/Cytoscape_User_Manual/Network_Formats)
+     * and store it in an internal data structure 
+     * @param fileName
+     */
+    private void parseInteractions(String fileName) throws DataSourceException{
+		this.tmpInteractions = new ArrayList<String[]>();
+		File file = new File(fileName);
+	    BufferedReader input = null;
+	    Set<String> hash = new HashSet<String>();
+	    try {
+	    	input = new BufferedReader( new FileReader(file) );
+	    	String line = null; 
+	    	while (( line = input.readLine()) != null){
+		    	String [] temp = null;
+		    	// first try to split around tabs, otherwise use spaces
+		    	temp = line.split("\t");
+		    	if (temp.length == 1){
+		    		temp = line.split(" ");
+		    	}
+		    	// the rest of the line contains at least one binary interactor
+		    	for (int i = 2; i < temp.length; i++){
+		    		if (temp[i].trim().length() > 0){
+		    			// make a hash from the identifiers to check for duplicates
+		    			String abbr = null;
+		    			if (temp[0].compareTo(temp[i]) > 0){
+		    				abbr = temp[i] + temp[0];
+		    			}else{
+		    				abbr = temp[0] + temp[i];
+		    			}
+		    			// if the interaction is not yet in there, add it
+		    			if (!hash.contains(abbr)){
+		    				String[] interaction = new String[2];
+		    				interaction[0] = temp[0];
+		    				interaction[1] = temp[i];
+		    				hash.add(abbr);
+		    				tmpInteractions.add(interaction);
+		    			}
+		    		}
+		    	}
+	    	}
+	    	hash = null;
+	    }
+	    catch (FileNotFoundException ex) {
+	    	ex.printStackTrace();
+	    	throw new DataSourceException("The SIF file cannot be founde in the specified location");
+	    }
+	    catch (IOException ex){
+	    	ex.printStackTrace();
+	    }
+	    finally {
+	    	try {
+	    		if (input!= null) {
+	    			input.close();
+	    		}
+	    	}
+	    	catch (IOException ex) {
+	    		ex.printStackTrace();
+	    	}
+	    }
+	}
+    
+    /**
+     * Creates the given element with the given id. Includes all stored attributes as details. 
+     * @param obj Interactor or Interaction
+     * @param id Id or name of the element
+     * @return either an Interactor, an Interaction or null
+     */
+    private Object createElement(String obj, String id){
+    	if (obj.equalsIgnoreCase("Interactor")){
+	    	Interactor interactor = new Interactor();
+	    	interactor.setDbCoordSys(this.coordSys);
+	    	interactor.setDbAccessionId(id);
+	    	if (this.attributes.containsKey(id)){
+	    		String[] attrs = this.attributes.get(id);
+	    		for (int i = 0; i < attrs.length; i=i+2){
+	    			// if there is an attribute symbol, do not create an extra detail but include it in the name
+	    			if (attrs[i].equalsIgnoreCase("symbol")){
+	    				interactor.setName(attrs[i+1]);
+	    			}else{
+	    				Detail detail = new Detail();
+	    				detail.setProperty(attrs[i]);
+	    				detail.setValue(attrs[i+1]);
+	    				interactor.addDetail(detail);
+	    			}
+	    		}
+	    	}
+	    	return interactor;
+    	}else if (obj.equalsIgnoreCase("Interaction")){
+	    	Interaction interaction = new Interaction();
+	    	interaction.setName(id);
+	    	if (this.attributes.containsKey(id)){
+	    		String[] attrs = this.attributes.get(id);
+	    		for (int i = 0; i < attrs.length; i=i+2){
+	    			Detail detail = new Detail();
+	    			detail.setProperty(attrs[i]);
+	    			detail.setValue(attrs[i+1]);
+	    			interaction.addDetail(detail);
+	    		}
+	    	}
+	    	return interaction;
+    	}else{
+    		return null;
+    	}
+    }
+    
+    
+    /**
+     * Return the data source string
+     */
+	public String getDataSourceType() {
+        return "sif";
+    }
+     
+	
+	/**
+	 * Return the data source version string
+	 */
+    public String getDataSourceVersion() {
+        return "1.00";
+    }
+    
+    /**
+     * Set the file name
+     * @param f File path
+     */
+    public void setFileName(String f){
+    	this.fileName = f;
+    }
+    
+    public String getFileName(){
+    	return this.fileName;
+    }
+        
+    public String getInteractorDbSource(){
+    	return this.interactorDbSource;
+    }
+    
+    public void setInteractorDbSource(String interactorDbSource){
+    	this.interactorDbSource = interactorDbSource;
+    }
+    
+    public String getInteractorDbSourceCvId(){
+    	return this.interactorDbSourceCvId;
+    }
+    
+    public void setinteractorDbSourceCvId(String interactorDbSourceCvId){
+    	this.interactorDbSourceCvId = interactorDbSourceCvId;
+    }
+    
+    public String getCoordSys(){
+    	return this.coordSys;
+    }
+    
+    public void setCoordSys(String cs){
+    	this.coordSys = cs;
+    }
+    
+    public void setMapMaster(String s) {
+        this.mapMaster = s;
+    }
+
+    public String getMapMaster() {
+        return mapMaster;
+    }
+    
+    
+    public String getAttributeFiles(){
+    	return this.attributeFiles;
+    }
+    
+    public void setAttributeFiles(String files){
+    	this.attributeFiles = files;
+    }
+    
+    public Set<String> getEntryPoints() {
+    	return this.entryPoints;
+    }
+    
+    public void setEntryPoints(Set<String> ep) {
+    	this.entryPoints = ep;
+    }
+    
+    public Sequence getSequence(String ref)
+	    throws DataSourceException, NoSuchElementException{
+        return null;
+    }
+
+    public String getLandmarkVersion(String ref) 
+	    throws DataSourceException, NoSuchElementException{
+    	return null;
+   }
+
+    public FeatureHolder getFeatures(String ref)
+	    throws NoSuchElementException, DataSourceException{
+        return null;
+    }
+      
+    public Set<String> getAllTypes() {
+        return null;
+    }
+    
+
+    /*
+	public static void main(String[] args) throws DataSourceException {
+		SIFReferenceSource sif = new SIFReferenceSource();
+		sif.parseAttributes("D:/MPII/workspace/Dazzle/testName.noa;D:/MPII/workspace/Dazzle/testSymbol.noa;D:/MPII/workspace/Dazzle/testConf.eda");
+		
+		sif.parseInteractions("D:/MPII/workspace/Dazzle/test.sif");
+		
+		String[] queries = {"1212"};
+		Interaction[] ints = sif.getInteractions(queries);
+		 for (int i = 0 ; i < ints.length ; i++) {
+		        System.out.println(ints[i]);
+		    }
+		//System.out.println(ints.length);
+	}
+  
+    public static void dump(String[] s) {
+	    System.out.println("------------");
+	    for (int i = 0 ; i < s.length ; i++) {
+	        System.out.println(s[i]);
+	    }
+	    System.out.println("------------");
+    }*/
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/StructureSource.java b/src/org/biojava/servlets/dazzle/datasource/StructureSource.java
new file mode 100644
index 0000000..13cc6b8
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/StructureSource.java
@@ -0,0 +1,216 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.*;
+import javax.servlet.*;
+import org.biojava.bio.seq.*;
+import org.biojava.bio.structure.io.*;
+
+/**
+ * Simple datasource backed to provide alignment data.
+ * can be configured in dazzlecfg.xml .
+ *
+ * @author Andreas Prlic
+ * @author Thomas Down
+ * @version 1.00
+ */
+
+public class StructureSource 
+extends AbstractDataSource 
+implements DazzleReferenceSource {
+
+	private Set allTypes;
+
+	public String filepath ;
+	public String pdbReader ; 
+	public String fileExt;
+
+	// for pfetch command 
+	public String host ;
+	public int    port ;
+
+	public String dbDriver;
+	public String dbUrl;
+	public String dbUsername;
+	public String dbPassword;
+
+	public void init(ServletContext ctx) 
+	throws DataSourceException
+	{
+		super.init(ctx);
+
+	}
+
+	public void   setHost(String m)         { host =  m ;    }
+	public String getHost()                 { return host ;  } 
+
+	public void   setPort(int p)            { port =  p ;    }
+	public int    getPort()                 { return port ;  } 
+
+	public void   setDbDriver(String dbd)   { dbDriver = dbd;   }
+	public String getDbDriver()             { return dbDriver ; }
+
+	public void   setDbUrl(String dbu)      { dbUrl = dbu ; }
+	public String getDbUrl()                { return dbUrl;}
+
+	public void   setDbUsername(String dbu) { dbUsername = dbu; }
+	public String getDbUsername()           { return dbUsername ;}
+
+	public void   setDbPassword(String dbp) { dbPassword = dbp ;}
+	public String getDbPassword()           { return dbPassword ;}
+
+	public StructureIO getPdbIo()
+	throws DataSourceException
+	{
+		System.out.println("StructureSource getPdbIo");
+		System.out.println("pdbReader: "+pdbReader);
+
+		StructureIO pdbIO = null;
+
+		try {
+			Class  c = Class.forName(pdbReader);
+			Object structureIo = c.newInstance();
+
+			boolean isStructureIOFile = false;
+
+			// go through the interfaces of the reader and see if it implements isStructureIOFile
+			Class[] interfacses = c.getInterfaces();
+			for (Class class1 : interfacses) {
+				if (class1.getName().equals("org.biojava.bio.structure.io.StructureIOFile")) {
+					isStructureIOFile = true;
+					break;
+				}				
+			}
+			System.out.println( c.getName() + " is a structureIOFile: " + isStructureIOFile);
+
+			if (pdbReader.equals("org.biojava.bio.structure.io.PDBSRSReader")) {
+
+				PDBSRSReader pdbsrs = (PDBSRSReader)structureIo ;
+
+				System.setProperty("PFETCH_host" , host    );
+				System.setProperty("PFETCH_port" , ""+port );
+
+				pdbIO = pdbsrs;
+
+
+			}  else if ( pdbReader.equals("org.biojava.bio.structure.PDBXMLReader")){
+				throw new DataSourceException("not implemented,yet "+ pdbReader);
+
+				//pdbIO = (StructureIOXML)d ;		
+				// init pdbIOXML
+
+			} else if ( pdbReader.equals("org.biojava.bio.structure.io.PDBMSDReader")){
+
+				// init pdbIOMSD
+
+				PDBMSDReader s = (PDBMSDReader)structureIo ;
+				s.setDBConnection(dbDriver,dbUrl,dbUsername,dbPassword);
+				pdbIO = s;		
+
+			} else if (isStructureIOFile) {
+				//"org.biojava.bio.structure.io.PDBFileReader"
+				System.out.println("this is a  structureIOFile");
+				StructureIOFile pdbFile = (StructureIOFile)structureIo ;
+
+				// init pdbIOFile
+
+				pdbFile.setPath(filepath);
+
+
+				// check if some specific file extensions have been requested
+				String[] spl = new String[0];
+				if ( fileExt != null ) {
+					spl = fileExt.split(" ") ;
+					for (int i=0; i<spl.length; i++){
+						System.out.println("adding extensions " + spl[i] );
+						pdbFile.addExtension(spl[i]);
+					}
+				}
+
+				pdbIO = pdbFile;
+
+			} else {
+				// all other readers should do the config themselves...
+				// e.g. uk.ac.sanger.dazzle.datasource.HibernatePDBUPAlignmentSource
+				pdbIO = (StructureIO)structureIo;
+			}
+		} catch (Exception ex) {
+			ex.printStackTrace();
+			throw new DataSourceException(ex,"Couldn't create pdbIo PDB file reader");
+		}
+
+
+		return pdbIO ;
+	}
+
+	public String getFileExt() {
+		return fileExt;
+	}
+
+	public void setFileExt(String s) {
+		fileExt = s ;
+	}
+
+	public String getPdbReader()         { return pdbReader;   }
+
+	public void   setPdbReader(String s) { pdbReader = s ;     }
+
+	public String getFilePath() {
+
+		return filepath ;   
+	}
+
+	public void setFilePath(String s) {
+
+		filepath = s;
+
+	}
+
+	public String getDataSourceType() {return "pdbfile"; }
+
+	public String getDataSourceVersion() { return "1.00";  }
+
+
+	/* not really needed ... */
+
+	public String getMapMaster() {       return null;   }
+
+
+	public String getLandmarkVersion(String ref)
+	throws DataSourceException, NoSuchElementException
+	{  return getVersion();   }
+
+	public Sequence getSequence(String ref)
+	throws NoSuchElementException, DataSourceException
+	{       return null;  }
+
+	public Set getAllTypes() {
+		if ( allTypes == null)
+			allTypes = new HashSet();
+		return Collections.unmodifiableSet(allTypes);
+	}
+
+	public Set getEntryPoints() {      return new HashMap().keySet();  }
+
+	public Set getEntryPoints(String ref) {   return new HashMap().keySet();  }
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/TilingFeatureSource.java b/src/org/biojava/servlets/dazzle/datasource/TilingFeatureSource.java
new file mode 100644
index 0000000..d1cc2c2
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/TilingFeatureSource.java
@@ -0,0 +1,27 @@
+package org.biojava.servlets.dazzle.datasource;
+
+import java.util.NoSuchElementException;
+
+import org.biojava.bio.seq.FeatureHolder;
+
+/**
+ * Interface for sources which understand maxbins.
+ * 
+ * @author Thomas Down
+ *
+ */
+public interface TilingFeatureSource extends BiojavaFeatureSource {
+	
+	/**
+	 * Return a FeatureHolder which behaves exactly like that returned by the getFeatures(String) method,
+	 * but which optionally takes the maxbins parameter into account when answering its feature-retrieval
+	 * method.
+	 * 
+	 * @param seq
+	 * @param maxbins
+	 * @return
+	 * @throws DataSourceException
+	 * @throws NoSuchElementException
+	 */
+	public FeatureHolder getFeatures(String seq, int maxbins) throws DataSourceException, NoSuchElementException;
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/TypeMetadataSource.java b/src/org/biojava/servlets/dazzle/datasource/TypeMetadataSource.java
new file mode 100644
index 0000000..381bba6
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/TypeMetadataSource.java
@@ -0,0 +1,19 @@
+/*
+ * Created on Feb 15, 2006
+ */
+package org.biojava.servlets.dazzle.datasource;
+
+/**
+ * Datasources that know how to provide extra metadata about some or all of their
+ * types.
+ * 
+ * @author thomas
+ */
+
+public interface TypeMetadataSource {
+    public String getTypeMethod(String type);
+    public String getTypeEvidenceCode(String type);
+    public String getTypeOntology(String type);
+    public String getTypeDescriptionString(String type);
+    public String getCategory(String type);
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/UniProtDataSource.java b/src/org/biojava/servlets/dazzle/datasource/UniProtDataSource.java
new file mode 100644
index 0000000..4db5d6b
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/UniProtDataSource.java
@@ -0,0 +1,167 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Apr 23, 2007
+ * 
+ */
+
+package org.biojava.servlets.dazzle.datasource;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+
+import org.biojava.bio.Annotation;
+import org.biojava.bio.seq.Feature;
+import org.biojava.bio.seq.Sequence;
+import org.biojava.bio.seq.SequenceIterator;
+import org.biojava.bio.seq.io.SeqIOTools;
+import org.biojava.bio.symbol.Location;
+
+
+/** a class that servs data from a UniProt flat file
+ * 
+ * @author Andreas Prlic
+ *
+ */
+public class UniProtDataSource extends AbstractDataSource implements DazzleReferenceSource {
+
+	private Map seqs;
+	private Set allTypes;
+	String fileName;
+
+	
+	public void init(ServletContext ctx) 
+	throws DataSourceException
+	{
+		super.init(ctx);
+		try {
+			seqs = new HashMap();
+			allTypes = new HashSet();
+			BufferedReader br = new BufferedReader(new InputStreamReader(ctx.getResourceAsStream(fileName)));
+
+//			read the SwissProt File
+			SequenceIterator sequences = SeqIOTools.readSwissprot(br);
+
+
+			//iterate through the sequences
+			while(sequences.hasNext()){
+
+				Sequence seq = sequences.nextSequence();
+			
+				seqs.put(seq.getName(), seq);
+			}
+		} catch (Exception ex) {
+			throw new DataSourceException(ex, "Couldn't load sequence file");
+		}
+	}
+
+	/** try to parse a score out of the feature notes
+	 * 
+	 */
+	public String getScore(Feature f) {
+		String score = "-";
+
+		Annotation a = f.getAnnotation();
+		try {
+			
+			String note = (String) a.getProperty("swissprot.featureattribute");
+			
+			int scorePos =note.indexOf("Score: "); 
+			if (  scorePos > 0 ) {
+
+				String sc = note.substring(scorePos+7,note.length());
+				//System.out.println("parsed " + sc);
+				try {
+					double scp  = Double.parseDouble(sc);
+					score = "" + scp;
+				} catch (Exception e){
+					e.printStackTrace();
+				}
+				try {
+					int scp = Integer.parseInt(sc);
+					score = "" + scp;
+				} catch (Exception e){ 
+					e.printStackTrace();
+				}
+				
+			}
+			
+			//score = ""+ (Double)a.getProperty(SCORE);
+			System.out.println("found score " + score);
+		} catch (NoSuchElementException e){
+			// igonre in this case...
+		}
+		return score;
+
+	}
+
+
+	public String getDataSourceType() {
+
+		return "UniProtFile";
+	}
+
+	public String getDataSourceVersion() {
+
+		return "1.00";
+	}
+
+	public void setFileName(String s) {
+		fileName = s;
+	}
+
+	public Sequence getSequence(String ref) throws DataSourceException, NoSuchElementException {
+		Sequence seq = (Sequence) seqs.get(ref);
+		if (seq == null) {
+			throw new NoSuchElementException("No sequence " + ref);
+		}
+		return seq;
+	}
+
+	public Set getAllTypes() {
+		return Collections.unmodifiableSet(allTypes);
+	}
+
+	public Set getEntryPoints() {
+		return seqs.keySet();
+	}
+
+
+
+	public String getMapMaster() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+
+
+	public String getLandmarkVersion(String ref) throws DataSourceException, NoSuchElementException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/db/GFFFeatureCache.java b/src/org/biojava/servlets/dazzle/datasource/db/GFFFeatureCache.java
new file mode 100644
index 0000000..4ce77bc
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/db/GFFFeatureCache.java
@@ -0,0 +1,34 @@
+
+package org.biojava.servlets.dazzle.datasource.db ;
+
+import org.biojava.servlets.dazzle.datasource.GFFFeature;
+
+/** an interface that defines how a cache for features looks like */
+
+public interface GFFFeatureCache {
+
+    /** see if cache contains an entry for a paritucal accession code
+     * and a das source 
+     * @param seqId 
+     * @param dassource 
+     * @return flag if is cached*/    
+    public boolean isCached(String seqId, String dassource);
+
+     /** store features in cache 
+     * @param seqId 
+     * @param dassource 
+     * @param features */
+    public void cacheFeatures(String seqId, String dassource, GFFFeature[] features);
+
+
+    /** retrieve all Features from cache for a particular sequence
+     * @param seqId 
+     * @param dassource 
+     * @return  features
+     */    
+    public GFFFeature[] retrieveFeatures(String seqId,String dassource);
+
+    /** empty the conent of the cache */
+    public void clearCache();
+
+}
diff --git a/src/org/biojava/servlets/dazzle/datasource/db/MysqlFeatureCache.java b/src/org/biojava/servlets/dazzle/datasource/db/MysqlFeatureCache.java
new file mode 100644
index 0000000..35c4a0f
--- /dev/null
+++ b/src/org/biojava/servlets/dazzle/datasource/db/MysqlFeatureCache.java
@@ -0,0 +1,358 @@
+/** biojava LGPL header */
+
+package org.biojava.servlets.dazzle.datasource.db ;
+
+
+import java.sql.*;
+import java.util.*;
+import java.text.SimpleDateFormat;
+import javax.sql.DataSource ;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+import org.biojava.servlets.dazzle.datasource.GFFFeature;
+
+
+/** a class that caches GFFFeatures using IBM's Cloudscape (former
+ * Derby) 
+
+ * how to use it: <br>
+ * add the following line to you dazzlecfg.xml file:
+ * <pre>
+ *   <resource id="GFFFeatureCache" jclass="org.biojava.servlets.dazzle.datasource.DerbyFeatureCache"/>     
+ *</pre>
+ * a datasource can then ask to get this object by :
+ * <pre>
+ *   GFFFeatureCache cache =  (GFFFeatureCache) ctx.getAttribute("GFFFeatureCache");
+ * </pre>
+ */
+
+public class MysqlFeatureCache 
+implements GFFFeatureCache 
+{
+
+	public static String tableName   = "feature_cache" ;
+	public static String DATASOURCE_NAME = "jdbc/feature_cache";
+	//Connection conn ; 
+	DataSource dataSource;
+
+
+	static String test = "select count(*) " +
+	"from " + tableName + " " + 
+	"where code = ? and dassource = ?";
+
+
+	static String sele = "select "+		    
+	" method,"+
+	" featurename,"+
+	" type,"+
+	" note,"+
+	" link,"+
+	" start,"+
+	" fend,"+
+	" phase,"+
+	" orientation,"+
+	" score,"+
+	" label " +
+	"from " + tableName + " " + 
+	"where code = ? and "+
+	" dassource = ? and"+
+	" nofeaturesflag = ? "+
+	"order by type,note" ;
+
+	static String ins = "insert into " + tableName + 
+	"   (code,"+
+	"   dassource,"+
+	"   method,"+
+	"   featurename,"+
+	"   type,"+
+	"   note,"+
+	"   link,"+
+	"   start,"+
+	"   fend," +
+	"   phase,"+
+	"   orientation,"+
+	"   score,"+
+	"   label,"+
+	"   timestamp,"+
+	"   nofeaturesflag) " +
+	"values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; 
+
+	static String nofeats = " insert into " + tableName +
+	" (code,"+
+	" dassource,"+
+	" nofeaturesflag, timestamp) " +
+	"values (?,?,?,?)";
+
+
+
+	/** init the cache */
+
+
+	public MysqlFeatureCache() {
+		System.out.println("MysqlFeature cache init");
+		try
+		{
+			// open db connection
+
+			Context env = (Context) new InitialContext().lookup("java:comp/env");
+
+			dataSource = (DataSource) env.lookup(DATASOURCE_NAME);
+
+
+		}
+		catch (Exception e) {
+			System.out.println("exception thrown:");	  
+			e.printStackTrace();	    
+		}
+
+		System.out.println("finished init of GFFFeatureCache");
+	}
+
+	/** alternative constructor, if dataSource is provided from outside
+	 * 
+	 * @param dataSourceCache
+	 */
+	public MysqlFeatureCache(DataSource dataSourceCache) {
+		dataSource = dataSourceCache;
+	}
+
+	static void printSQLError(SQLException e)
+	{
+		while (e != null)
+		{
+			System.out.println(e.toString());
+			e = e.getNextException();
+		}
+	}
+
+
+
+
+
+	/** see if cache contains an entry for a paritucal accession code
+	 * and a das source */    
+
+	public boolean isCached(String seqId, String dassource){
+		//System.out.println("cache - isCached? " + seqId + " " + dassource);
+		boolean cached = false;
+		Connection conn = null;
+		try {
+			conn = dataSource.getConnection();
+
+			PreparedStatement testsql   = conn.prepareStatement(test);
+			// todo test age of entry!
+			testsql.setString(1,seqId);
+			testsql.setString(2,dassource);
+			ResultSet row = testsql.executeQuery();
+			while (row.next()) {
+				int size = row.getInt(1);
+				if ( size > 0 ) {		   		    
+					cached = true ;
+					break;
+				}
+			}	    
+			row.close();
+			//testsql.clearParameters();
+			testsql.close();
+
+		} catch (SQLException e) {
+			e.printStackTrace();
+
+		} finally {
+			if ( conn != null ) {
+				try { conn.close();}
+				catch (SQLException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return cached ;
+
+	}
+
+	/** store features in cache */
+	public void cacheFeatures(String seqId,String dassource, GFFFeature[] features) {
+		//System.out.println("cache - cacheFeatures "+ seqId + " " + dassource);
+		Connection conn = null;
+		try {
+			conn = dataSource.getConnection();
+			if ( features.length == 0 ) {
+				//System.out.println(seqId + " feature length = 0");
+				// store that there are no features for this seqId
+				PreparedStatement flagsql   = conn.prepareStatement(nofeats);
+				flagsql.setString(1,seqId);
+				flagsql.setString(2,dassource);
+				flagsql.setString(3,"t") ; // true + there are no features
+				int ts = getTimeStamp();
+				flagsql.setInt(4,ts);
+				flagsql.executeUpdate();		
+				//conn.commit();
+				flagsql.clearParameters();
+				return;
+			}
+
+			for ( int i = 0 ; i< features.length;i++ ) {
+				GFFFeature gff = features[i];
+				//if (gff == null) {
+				//  System.out.println(" got null instead of gff feature!");
+				//}
+				cacheFeature(conn,seqId,dassource,gff);		
+			}
+			//conn.commit();
+		} catch (SQLException e) {
+			e.printStackTrace();
+		} finally {
+			if ( conn != null ) {
+				try { conn.close();}
+				catch(SQLException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+
+	}
+
+	private int getTimeStamp(){
+		java.util.Date now = new java.util.Date();
+		SimpleDateFormat formatter = new SimpleDateFormat("yyMMddHHmm");
+		String date =  formatter.format(now);
+		return Integer.parseInt(date);
+	}
+
+	private void cacheFeature(Connection conn,String seqId,String dassource, GFFFeature gff)
+	throws SQLException
+	{
+		//System.out.println("caching feature " + gff.getMethod());
+		PreparedStatement insertsql = conn.prepareStatement(ins);
+		insertsql.setString(1,seqId);
+		insertsql.setString(2,dassource);
+		insertsql.setString(3,gff.getMethod());
+		insertsql.setString(4,gff.getName());
+		insertsql.setString(5,gff.getType());
+		insertsql.setString(6,gff.getNote());
+		insertsql.setString(7,gff.getLink());
+		insertsql.setString(8,gff.getStart());
+		insertsql.setString(9,gff.getEnd());
+		insertsql.setString(10,gff.getPhase());
+		insertsql.setString(11,gff.getOrientation());
+		insertsql.setString(12,gff.getScore());
+		insertsql.setString(13,gff.getLabel());
+		// a timestamp
+		int ts = getTimeStamp();
+		insertsql.setInt(14,ts);
+		insertsql.setString(15,"f");
+		insertsql.executeUpdate();
+		//conn.commit();
+		insertsql.clearParameters();
+
+
+	}
+
+	/** retrieve all Features from cache for a particular sequence 
+	 */
+
+	public GFFFeature[] retrieveFeatures(String seqId,String dassource){
+
+		//System.out.println("cache - retreiveFeatures "+ seqId + " " + dassource);
+
+		Connection conn = null;
+		List features = new ArrayList();
+		try {
+			conn = dataSource.getConnection();
+			PreparedStatement selectsql = conn.prepareStatement(sele);
+			selectsql.setString(1,seqId);
+			selectsql.setString(2,dassource);
+			selectsql.setString(3,"f"); // nofeaturesflag 
+			ResultSet row = selectsql.executeQuery();
+			while (row.next()) {
+				GFFFeature feat = getGFFFeatureFromRow(row);
+
+				if ( feat != null ) {
+					features.add(feat);
+					//System.out.println(feat);
+				}
+			}
+			row.close();
+			selectsql.clearParameters();
+		} catch (SQLException e) {
+			e.printStackTrace();
+		} finally {
+			if (conn != null) {
+				try { 
+					conn.close();
+				} catch (SQLException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+
+		return (GFFFeature[])features.toArray(new GFFFeature[features.size()]) ;
+	}
+
+	/** convert data from a row to a GFFFeature */
+	private GFFFeature getGFFFeatureFromRow(ResultSet row) 
+	throws SQLException 
+	{
+
+		String method = row.getString(1);
+		String name   = row.getString(2);
+		String type   = row.getString(3);
+		String note   = row.getString(4);
+		String link   = row.getString(5);
+		String start  = row.getString(6);
+		String end    = row.getString(7);
+		String phase  = row.getString(8);
+		String orient = row.getString(9);
+		String score  = row.getString(10);
+		String label  = row.getString(11);
+
+		GFFFeature gff = new GFFFeature();
+		gff.setName(name.trim());
+		gff.setMethod(method.trim());
+		gff.setType(type.trim());
+		gff.setStart(start.trim());
+		gff.setEnd(end.trim());
+		gff.setNote(note.trim());
+		if ( link != null ) 
+			gff.setLink(link.trim()) ;
+		if (phase != null )
+			gff.setPhase(phase.trim());
+		if ( orient != null )
+			gff.setOrientation(orient.trim());
+		if ( score != null )
+			gff.setScore(score.trim());
+		if ( label != null )
+			gff.setLabel(label.trim());
+		return gff ;	
+
+	} 
+
+	/** clear all data in cache */
+	public void clearCache() {
+		Connection conn = null;
+		try {
+			conn = dataSource.getConnection();
+			Statement s = conn.createStatement();
+
+			String deletesql = "delete from " +tableName ;
+			System.out.println(deletesql);
+			s.execute(deletesql);
+			//conn.commit();
+			s.close();
+
+
+		} catch (SQLException e) {
+			e.printStackTrace();
+		} finally {
+			if ( conn != null ) {
+				try { 
+					conn.close();
+				}
+				catch (SQLException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/dazzle.git



More information about the debian-med-commit mailing list