diff --git a/src/zmapServer/file/fileServer.c b/src/zmapServer/file/fileServer.c
index b6357973558791bd3ccd9fca9dde5657c5755575..a3736aa73719baa0fa2008087cb6415ca0c68f04 100755
--- a/src/zmapServer/file/fileServer.c
+++ b/src/zmapServer/file/fileServer.c
@@ -20,28 +20,33 @@
  * This file is part of the ZMap genome database package
  * originated by
  * 	Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk,
- *      Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk
+ *      Roy Storey (Sanger Institute, UK) rds@sanger.ac.uk
  *
  * Description: These functions provide code to read a file as though
  *              it were a server according to the interface defined
  *              for accessing servers. It's crude at the moment but
  *              the aim is to allow zmap to be run from just files
- *              if required.
+ *              if required. Read the caveats below though...
  *              
  * Exported functions: See ZMap/zmapServerPrototype.h
+ *              
  * HISTORY:
- * Last edited: Oct  2 08:12 2009 (edgrif)
+ * Last edited: Nov 27 15:41 2009 (edgrif)
  * Created: Fri Sep 10 18:29:18 2004 (edgrif)
- * CVS info:   $Id: fileServer.c,v 1.41 2009-10-02 09:21:53 edgrif Exp $
+ * CVS info:   $Id: fileServer.c,v 1.42 2009-11-30 10:51:45 edgrif Exp $
  *-------------------------------------------------------------------
  */
 
 
-/* WARNING, THIS DOES NOT COPE WITH MULTIPLE ALIGNS/BLOCKS AS IT STANDS, TO DO THAT REQUIRES
- * WORK BOTH ON THE GFF PARSER CODE (TO ACCEPT ALIGN/BLOCK ID/COORDS AND ON THIS CODE TO 
- * GENERALISE IT MORE TO DEAL WITH BLOCKS...I'LL DO THAT NEXT....EG */
-
-
+/* GFF files have a prescribed format which specifically does not include anything
+ * about how the features are displayed so the zmap styles must be provided separatly.
+ * 
+ * In addition the code assumes that the gff file describes just one block of features.
+ * In theory the file could contain multiple blocks but that is not straight forward
+ * as gff provides for multiple sequences with their features in a single file but _not_
+ * multiple sub-parts of a single sequence. Hence we do not support that currently.
+ * 
+ *  */
 
 #include <glib.h>
 #include <ZMap/zmapUtils.h>
@@ -57,7 +62,9 @@ typedef struct
   ZMapServerResponseType result ;
   FileServer server ;
   ZMapGFFParser parser ;
-  GString* gff_line ;
+  GString *gff_line ;
+
+  gboolean sequence_finished ;
 } GetFeaturesStruct, *GetFeatures ;
 
 
@@ -85,15 +92,22 @@ static char *lastErrorMsg(void *server) ;
 static ZMapServerResponseType closeConnection(void *server_in) ;
 static ZMapServerResponseType destroyConnection(void *server) ;
 
+static gboolean getSequenceMapping(FileServer server, ZMapFeatureContext feature_context) ;
 static void addMapping(ZMapFeatureContext feature_context, ZMapGFFHeader header) ;
+
 static void eachAlignment(gpointer key, gpointer data, gpointer user_data) ;
 static void eachBlock(gpointer key, gpointer data, gpointer user_data) ;
-static gboolean sequenceRequest(FileServer server, ZMapGFFParser parser, GString* gff_line,
+static gboolean featuresRequest(FileServer server, ZMapGFFParser parser, GString *gff_line,
 				ZMapFeatureBlock feature_block) ;
-static void setLastErrorMsg(FileServer server, GError **gff_file_err_inout) ;
+
+static void eachAlignmentSequence(gpointer key, gpointer data, gpointer user_data) ;
+static void eachBlockSequence(gpointer key, gpointer data, gpointer user_data) ;
 
 static gboolean getServerInfo(FileServer server, ZMapServerInfo info) ;
+
+static void setLastErrorMsg(FileServer server, GError **gff_file_err_inout) ;
 static void setErrMsg(FileServer server, char *new_msg) ;
+static gboolean resetToStart(FileServer server) ;
 
 
 
@@ -182,6 +196,10 @@ static gboolean createConnection(void **server_out,
 }
 
 
+/* The model we use for processing the GFF file is that we open it just once
+ * and then close it when the closeConnection is called. If we need to start
+ * at the beginning of the file again we just reset the file pointer to the
+ * start. */
 static ZMapServerResponseType openConnection(void *server_in)
 {
   ZMapServerResponseType result = ZMAP_SERVERRESPONSE_REQFAIL ;
@@ -255,8 +273,10 @@ static ZMapServerResponseType getFeatureSetNames(void *server_in,
   ZMAPSERVER_LOG(Warning, FILE_PROTOCOL_STR, server->file_path,
 		 "%s", server->last_err_msg) ;
 
+
   result = ZMAP_SERVERRESPONSE_UNSUPPORTED ;
 
+
   return result ;
 }
 
@@ -298,9 +318,12 @@ static ZMapServerResponseType haveModes(void *server_in, gboolean *have_mode)
 }
 
 
+/* Currently we don't support this even though we could in theory as gff files can
+ * contains arbitrary sequences. */
 static ZMapServerResponseType getSequences(void *server_in, GList *sequences_inout)
 {
-  ZMapServerResponseType result = ZMAP_SERVERRESPONSE_OK ;
+  ZMapServerResponseType result =  ZMAP_SERVERRESPONSE_UNSUPPORTED ;
+
 
   return result ;
 }
@@ -314,13 +337,27 @@ static ZMapServerResponseType setContext(void *server_in, ZMapFeatureContext fea
 {
   ZMapServerResponseType result = ZMAP_SERVERRESPONSE_OK ;
   FileServer server = (FileServer)server_in ;
+  gboolean status ;
 
   server->req_context = feature_context ;
 
-
-  /* Like the acedb server we should be getting the mapping from the gff file here....
-   * then we could set up the block/etc stuff...this is where add mapping should be called from... */
-
+  if (!(status = getSequenceMapping(server, feature_context)))
+    {
+      result = ZMAP_SERVERRESPONSE_REQFAIL ;
+      ZMAPSERVER_LOG(Warning, FILE_PROTOCOL_STR, server->file_path,
+		     "Could not map %s because: %s",
+		     g_quark_to_string(server->req_context->sequence_name), server->last_err_msg) ;
+    }
+  else
+    {
+      if (!resetToStart(server))
+	{
+	  result = ZMAP_SERVERRESPONSE_REQFAIL ;
+	  ZMAPSERVER_LOG(Warning, FILE_PROTOCOL_STR, server->file_path,
+			 "Could not reset to file start %s because: %s",
+			 g_quark_to_string(server->req_context->sequence_name), server->last_err_msg) ;
+	}
+    }
 
 
   return result ;
@@ -331,7 +368,7 @@ static ZMapServerResponseType setContext(void *server_in, ZMapFeatureContext fea
 static ZMapServerResponseType getFeatures(void *server_in, GData *styles, ZMapFeatureContext feature_context)
 {
   FileServer server = (FileServer)server_in ;
-  GetFeaturesStruct get_features ;
+  GetFeaturesStruct get_features = {0} ;
   GIOStatus status ;
   gsize terminator_pos = 0 ;
   GError *gff_file_err = NULL ;
@@ -355,9 +392,8 @@ static ZMapServerResponseType getFeatures(void *server_in, GData *styles, ZMapFe
   get_features.result = ZMAP_SERVERRESPONSE_OK ;
   get_features.server = (FileServer)server_in ;
 
-  get_features.parser = zMapGFFCreateParser(styles, FALSE) ;
-							    /* FALSE => do the real parse. */
-
+  get_features.parser = zMapGFFCreateParser() ;
+  zMapGFFParserInitForFeatures(get_features.parser, styles, FALSE) ;
 
   get_features.gff_line = g_string_sized_new(2000) ;	    /* Probably not many lines will be >
 							       2k chars. */
@@ -422,13 +458,6 @@ static ZMapServerResponseType getFeatures(void *server_in, GData *styles, ZMapFe
 
   if (get_features.result == ZMAP_SERVERRESPONSE_OK)
     {
-      header = zMapGFFGetHeader(get_features.parser) ;
-
-      addMapping(feature_context, header) ;
-
-      zMapGFFFreeHeader(header) ;
-
-
       /* Fetch all the alignment blocks for all the sequences, this all hacky right now as really.
        * we would have to parse and reparse the file....can be done but not needed this second. */
       g_hash_table_foreach(feature_context->alignments, eachAlignment, (gpointer)&get_features) ;
@@ -456,173 +485,106 @@ static ZMapServerResponseType getFeatures(void *server_in, GData *styles, ZMapFe
 }
 
 
-static void eachBlockSequence(gpointer key, gpointer data, gpointer user_data)
-{
-  ZMapFeatureBlock feature_block = (ZMapFeatureBlock)data ;
-  GetFeatures get_features = (GetFeatures)user_data ;
-
-  if (get_features->result == ZMAP_SERVERRESPONSE_OK)
-    {
-      ZMapSequence sequence;
-      if(!(sequence = zMapGFFGetSequence(get_features->parser)))
-	{
-	  GError *error;
-	  error = zMapGFFGetError(get_features->parser);
-	  setErrMsg(get_features->server,
-		    g_strdup_printf("zMapGFFGetSequence() failed, error=%s",
-				    error->message));
-	  ZMAPSERVER_LOG(Warning, FILE_PROTOCOL_STR, 
-			 get_features->server->file_path,
-			 "%s", get_features->server->last_err_msg);
-	}
-      else
-	{
-	  ZMapFeatureContext context;
-	  ZMapFeatureSet feature_set;
-
-	  if(zMapFeatureDNACreateFeatureSet(feature_block, &feature_set))
-	    {
-	      ZMapFeatureTypeStyle dna_style = NULL;
-	      ZMapFeature feature;
-
-	      /* This temp style creation feels wrong, and probably is,
-	       * but we don't have the merged in default styles in here,
-	       * or so it seems... */
-	      dna_style = zMapStyleCreate(ZMAP_FIXED_STYLE_DNA_NAME, 
-					  ZMAP_FIXED_STYLE_DNA_NAME_TEXT);
-	      
-	      feature = zMapFeatureDNACreateFeature(feature_block, dna_style,
-						    sequence->sequence, sequence->length);
-	      
-	      zMapStyleDestroy(dna_style);
-	    }
-
-	  context = (ZMapFeatureContext)zMapFeatureGetParentGroup((ZMapFeatureAny)feature_block, 
-								  ZMAPFEATURE_STRUCT_CONTEXT) ;
-
-	  /* I'm going to create the three frame translation up front! */
-	  if (zMap_g_list_find_quark(context->feature_set_names, zMapStyleCreateID(ZMAP_FIXED_STYLE_3FT_NAME)))
-	    {
-	      if ((zMapFeature3FrameTranslationCreateSet(feature_block, &feature_set)))
-		{
-		  ZMapFeatureTypeStyle frame_style = NULL;
-		  
-		  frame_style = zMapStyleCreate(ZMAP_FIXED_STYLE_DNA_NAME, 
-						ZMAP_FIXED_STYLE_DNA_NAME_TEXT);
-		  
-		  zMapFeature3FrameTranslationSetCreateFeatures(feature_set, frame_style);
-		  
-		  zMapStyleDestroy(frame_style);
-		}
-	    }
-
-	  g_free(sequence);
-	}
-    }
-
-  return ;
-}
-
-/* Process all the alignments in a context. */
-static void eachAlignmentSequence(gpointer key, gpointer data, gpointer user_data)
-{
-  ZMapFeatureAlignment alignment = (ZMapFeatureAlignment)data ;
-  GetFeatures get_features = (GetFeatures)user_data ;
-
-  if (get_features->result == ZMAP_SERVERRESPONSE_OK)
-    g_hash_table_foreach(alignment->blocks, eachBlockSequence, (gpointer)get_features) ;
 
-  return ;
-}
 
-/* We don't support this for now... */
-static ZMapServerResponseType getContextSequence(void *server_in, GData *styles, ZMapFeatureContext feature_context_out)
+static ZMapServerResponseType getContextSequence(void *server_in, GData *styles,
+						 ZMapFeatureContext feature_context_out)
 {
   FileServer server = (FileServer)server_in ;
-  GetFeaturesStruct get_features ;
+  GetFeaturesStruct get_features = {0} ;
   GIOStatus status ;
   gsize terminator_pos = 0 ;
   GError *gff_file_err = NULL ;
   GError *error = NULL ;
 
+
+
+#ifdef ED_G_NEVER_INCLUDE_THIS_CODE
+  return ZMAP_SERVERRESPONSE_UNSUPPORTED ;
+#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */
+
+
+
   get_features.result = ZMAP_SERVERRESPONSE_OK ;
   get_features.server = (FileServer)server_in ;
 
-  get_features.parser = zMapGFFCreateParser(styles, FALSE) ;
-							    /* FALSE => do the real parse. */
-
+  get_features.parser = zMapGFFCreateParser() ;
   zMapGFFParserSetSequenceFlag(get_features.parser);
+
   get_features.gff_line = g_string_sized_new(2000) ;	    /* Probably not many lines will be >
 							       2k chars. */
-  g_io_channel_seek_position(server->gff_file, 0, G_SEEK_SET, &gff_file_err);
-
-  /* Read the header, needed for feature coord range. */
-  while ((status = g_io_channel_read_line_string(server->gff_file, get_features.gff_line,
-						 &terminator_pos,
-						 &gff_file_err)) == G_IO_STATUS_NORMAL)
+  if (resetToStart(server))
     {
       gboolean done_header = FALSE ;
 
-      *(get_features.gff_line->str + terminator_pos) = '\0' ; /* Remove terminating newline. */
-
-      if (zMapGFFParseHeader(get_features.parser, get_features.gff_line->str, &done_header))
-	{
-	  if (done_header)
-	    break ;
-	  else
-	    get_features.gff_line = g_string_truncate(get_features.gff_line, 0) ;
-							    /* Reset line to empty. */
-	}
-      else
+      /* Read the header, needed for feature coord range. */
+      while ((status = g_io_channel_read_line_string(server->gff_file, get_features.gff_line,
+						     &terminator_pos,
+						     &gff_file_err)) == G_IO_STATUS_NORMAL)
 	{
+	  *(get_features.gff_line->str + terminator_pos) = '\0' ; /* Remove terminating newline. */
+
 	  if (!done_header)
 	    {
-	      error = zMapGFFGetError(get_features.parser) ;
-
-	      if (!error)
+	      if (zMapGFFParseHeader(get_features.parser, get_features.gff_line->str, &done_header))
 		{
-		  /* SHOULD ABORT HERE.... */
-		  setErrMsg(server, 
-			    g_strdup_printf("zMapGFFParseLine() failed with no GError for line %d: %s",
-					    zMapGFFGetLineNumber(get_features.parser), get_features.gff_line->str)) ;
-		  ZMAPSERVER_LOG(Critical, FILE_PROTOCOL_STR, server->file_path,
-				 "%s", server->last_err_msg) ;
+		  if (!done_header)
+		    get_features.gff_line = g_string_truncate(get_features.gff_line, 0) ;
+							    /* Reset line to empty. */
 		}
 	      else
 		{
-		  /* If the error was serious we stop processing and return the error,
-		   * otherwise we just log the error. */
-		  if (zMapGFFTerminated(get_features.parser))
+		  if (!done_header)
 		    {
+		      error = zMapGFFGetError(get_features.parser) ;
+
+		      if (!error)
+			{
+			  /* SHOULD ABORT HERE.... */
+			  setErrMsg(server, 
+				    g_strdup_printf("zMapGFFParseLine() failed with no GError for line %d: %s",
+						    zMapGFFGetLineNumber(get_features.parser), get_features.gff_line->str)) ;
+			  ZMAPSERVER_LOG(Critical, FILE_PROTOCOL_STR, server->file_path,
+					 "%s", server->last_err_msg) ;
+			}
+		      else
+			{
+			  /* If the error was serious we stop processing and return the error,
+			   * otherwise we just log the error. */
+			  if (zMapGFFTerminated(get_features.parser))
+			    {
+			      get_features.result = ZMAP_SERVERRESPONSE_REQFAIL ;
+			      setErrMsg(server, g_strdup_printf("GFFTerminated! %s", error->message)) ;
+			      ZMAPSERVER_LOG(Critical, FILE_PROTOCOL_STR, server->file_path,
+					     "%s", server->last_err_msg) ;		    }
+			  else
+			    {
+			      setErrMsg(server,
+					g_strdup_printf("zMapGFFParseHeader() failed for line %d: %s",
+							zMapGFFGetLineNumber(get_features.parser),
+							get_features.gff_line->str)) ;
+			      ZMAPSERVER_LOG(Critical, FILE_PROTOCOL_STR, server->file_path,
+					     "%s", server->last_err_msg) ;
+			    }
+			}
 		      get_features.result = ZMAP_SERVERRESPONSE_REQFAIL ;
-		      setErrMsg(server, g_strdup_printf("GFFTerminated! %s", error->message)) ;
-		      ZMAPSERVER_LOG(Critical, FILE_PROTOCOL_STR, server->file_path,
-				     "%s", server->last_err_msg) ;		    }
-		  else
-		    {
-		      setErrMsg(server,
-				g_strdup_printf("zMapGFFParseHeader() failed for line %d: %s",
-						zMapGFFGetLineNumber(get_features.parser),
-						get_features.gff_line->str)) ;
-		      ZMAPSERVER_LOG(Critical, FILE_PROTOCOL_STR, server->file_path,
-				     "%s", server->last_err_msg) ;
 		    }
+
+		  break ;
 		}
-	      get_features.result = ZMAP_SERVERRESPONSE_REQFAIL ;
 	    }
+	  else
+	    {
+	      /* Fetch all the alignment blocks for all the sequences, this all hacky right now as really.
+	       * we would have to parse and reparse the file....can be done but not needed this second. */
+	      g_hash_table_foreach(feature_context_out->alignments, eachAlignmentSequence, (gpointer)&get_features) ;
 
-	  break ;
+	      if (get_features.sequence_finished)
+		break ;
+	    }
 	}
     }
 
-  if (get_features.result == ZMAP_SERVERRESPONSE_OK)
-    {
-      /* Fetch all the alignment blocks for all the sequences, this all hacky right now as really.
-       * we would have to parse and reparse the file....can be done but not needed this second. */
-      g_hash_table_foreach(feature_context_out->alignments, eachAlignmentSequence, (gpointer)&get_features) ;
-
-    }
-
 
   /* Clear up. */
   zMapGFFDestroyParser(get_features.parser) ;
@@ -633,6 +595,7 @@ static ZMapServerResponseType getContextSequence(void *server_in, GData *styles,
 }
 
 
+/* THIS ISN'T RIGHT..... */
 /* Return the last error message. */
 static char *lastErrorMsg(void *server_in)
 {
@@ -697,40 +660,6 @@ static ZMapServerResponseType destroyConnection(void *server_in)
  */
 
 
-/* A bit of a lash up for now, we need the parent->child mapping for a sequence and since
- * the code in this file so far simply reads a GFF file for now, we just fake it by setting
- * everything to be the same for child/parent... */
-static void addMapping(ZMapFeatureContext feature_context, ZMapGFFHeader header)
-{
-  ZMapFeatureBlock feature_block = NULL;//feature_context->master_align->blocks->data ;
-
-  feature_block = (ZMapFeatureBlock)(zMap_g_hash_table_nth(feature_context->master_align->blocks, 0)) ;
-
-  /* We just override whatever is already there...this may not be the thing to do if there
-   * are several files.... */
-  feature_context->parent_name = feature_context->sequence_name ;
-
-  feature_context->parent_span.x1 = header->features_start ;
-  feature_context->parent_span.x2 = header->features_end ;
-
-  /* I don't like having to do this right down here but user is allowed to specify "0" for
-   * end coord meaning "to the end of the sequence" and this is where we know the end... */
-  if (feature_block->block_to_sequence.t2 == 0)
-    feature_block->block_to_sequence.t2 = header->features_end ;
-
-  feature_context->sequence_to_parent.p1 = feature_context->sequence_to_parent.c1
-    = feature_block->block_to_sequence.q1 = feature_block->block_to_sequence.t1 ;
-
-  feature_context->sequence_to_parent.p2 = feature_context->sequence_to_parent.c2
-    = feature_block->block_to_sequence.q2 = feature_block->block_to_sequence.t2 ;
-
-  feature_context->length = feature_context->sequence_to_parent.c2 - feature_context->sequence_to_parent.c1 + 1;
-  
-  return ;
-}
-
-
-
 /* Small utility to deal with error messages from the GIOchannel package.
  * Note that we set gff_file_err_inout to NULL */
 static void setLastErrorMsg(FileServer server, GError **gff_file_err_inout)
@@ -773,7 +702,7 @@ static void eachBlock(gpointer key, gpointer data, gpointer user_data)
 
   if (get_features->result == ZMAP_SERVERRESPONSE_OK)
     {
-      if (!sequenceRequest(get_features->server, get_features->parser,
+      if (!featuresRequest(get_features->server, get_features->parser,
 			   get_features->gff_line, feature_block))
 	{
 	  ZMAPSERVER_LOG(Warning, FILE_PROTOCOL_STR, get_features->server->file_path,
@@ -787,7 +716,7 @@ static void eachBlock(gpointer key, gpointer data, gpointer user_data)
 }
 
 
-static gboolean sequenceRequest(FileServer server, ZMapGFFParser parser, GString* gff_line,
+static gboolean featuresRequest(FileServer server, ZMapGFFParser parser, GString* gff_line,
 				ZMapFeatureBlock feature_block)
 {
   gboolean result = FALSE ;
@@ -880,6 +809,103 @@ static gboolean sequenceRequest(FileServer server, ZMapGFFParser parser, GString
 }
 
 
+
+/* Process all the alignments in a context. */
+static void eachAlignmentSequence(gpointer key, gpointer data, gpointer user_data)
+{
+  ZMapFeatureAlignment alignment = (ZMapFeatureAlignment)data ;
+  GetFeatures get_features = (GetFeatures)user_data ;
+
+  if (get_features->result == ZMAP_SERVERRESPONSE_OK)
+    g_hash_table_foreach(alignment->blocks, eachBlockSequence, (gpointer)get_features) ;
+
+  return ;
+}
+
+
+static void eachBlockSequence(gpointer key, gpointer data, gpointer user_data)
+{
+  ZMapFeatureBlock feature_block = (ZMapFeatureBlock)data ;
+  GetFeatures get_features = (GetFeatures)user_data ;
+
+  if (get_features->result == ZMAP_SERVERRESPONSE_OK)
+    {
+      gboolean sequence_finished ;
+
+
+      if (zMapGFFParseSequence(get_features->parser, get_features->gff_line->str, &sequence_finished)
+	  && sequence_finished)
+	{
+	  ZMapSequence sequence ;
+
+	  if (!(sequence = zMapGFFGetSequence(get_features->parser)))
+	    {
+	      GError *error = NULL ;
+
+	      error = zMapGFFGetError(get_features->parser);
+
+	      setErrMsg(get_features->server,
+			g_strdup_printf("zMapGFFGetSequence() failed, error=%s",
+					error->message));
+	      ZMAPSERVER_LOG(Warning, FILE_PROTOCOL_STR, 
+			     get_features->server->file_path,
+			     "%s", get_features->server->last_err_msg);
+	    }
+	  else
+	    {
+	      ZMapFeatureContext context ;
+	      ZMapFeatureSet feature_set ;
+
+	      get_features->sequence_finished = TRUE ;
+
+	      if (zMapFeatureDNACreateFeatureSet(feature_block, &feature_set))
+		{
+		  ZMapFeatureTypeStyle dna_style = NULL;
+		  ZMapFeature feature;
+
+		  /* This temp style creation feels wrong, and probably is,
+		   * but we don't have the merged in default styles in here,
+		   * or so it seems... */
+		  dna_style = zMapStyleCreate(ZMAP_FIXED_STYLE_DNA_NAME, 
+					      ZMAP_FIXED_STYLE_DNA_NAME_TEXT);
+	      
+		  feature = zMapFeatureDNACreateFeature(feature_block, dna_style,
+							sequence->sequence, sequence->length);
+	      
+		  zMapStyleDestroy(dna_style);
+		}
+
+	      context = (ZMapFeatureContext)zMapFeatureGetParentGroup((ZMapFeatureAny)feature_block, 
+								      ZMAPFEATURE_STRUCT_CONTEXT) ;
+
+	      /* I'm going to create the three frame translation up front! */
+	      if (zMap_g_list_find_quark(context->feature_set_names, zMapStyleCreateID(ZMAP_FIXED_STYLE_3FT_NAME)))
+		{
+		  if ((zMapFeature3FrameTranslationCreateSet(feature_block, &feature_set)))
+		    {
+		      ZMapFeatureTypeStyle frame_style = NULL;
+		  
+		      frame_style = zMapStyleCreate(ZMAP_FIXED_STYLE_DNA_NAME, 
+						    ZMAP_FIXED_STYLE_DNA_NAME_TEXT);
+		  
+		      zMapFeature3FrameTranslationSetCreateFeatures(feature_set, frame_style);
+		  
+		      zMapStyleDestroy(frame_style);
+		    }
+		}
+
+	      g_free(sequence);
+	    }
+	}
+    }
+
+
+  return ;
+}
+
+
+
+
 static gboolean getServerInfo(FileServer server, ZMapServerInfo info)
 {
   gboolean result = FALSE ;
@@ -902,3 +928,166 @@ static void setErrMsg(FileServer server, char *new_msg)
   return ;
 }
 
+
+
+
+/* Tries to smap sequence into whatever its parent is, if the call fails then we set all the
+ * mappings in feature_context to be something sensible...we hope....
+ */
+static gboolean getSequenceMapping(FileServer server, ZMapFeatureContext feature_context)
+{
+  gboolean result = TRUE ;
+  ZMapGFFParser parser ;
+  GString *gff_line ;
+  gsize terminator_pos = 0 ;
+  GError *gff_file_err = NULL ;
+  ZMapGFFHeader header ;
+  GError *error = NULL ;
+
+#ifdef ED_G_NEVER_INCLUDE_THIS_CODE
+  char *parent_name = NULL, *parent_class = NULL ;
+  ZMapMapBlockStruct sequence_to_parent = {0, 0, 0, 0}, parent_to_self = {0, 0, 0, 0} ;
+  int parent_length = 0 ;
+#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */
+
+  GIOStatus gio_status ;
+  gboolean status ;
+
+
+  parser = zMapGFFCreateParser() ;
+
+  gff_line = g_string_sized_new(2000) ;			    /* Probably not many lines will be >
+							       2k chars. */
+
+  /* Read the header, needed for feature coord range. */
+  while ((gio_status = g_io_channel_read_line_string(server->gff_file, gff_line,
+						     &terminator_pos,
+						     &gff_file_err)) == G_IO_STATUS_NORMAL)
+    {
+      gboolean done_header = FALSE ;
+
+      *(gff_line->str + terminator_pos) = '\0' ;	    /* Remove terminating newline. */
+
+      if (zMapGFFParseHeader(parser, gff_line->str, &done_header))
+	{
+	  if (done_header)
+	    break ;
+	  else
+	    gff_line = g_string_truncate(gff_line, 0) ;	    /* Reset line to empty. */
+	}
+      else
+	{
+	  if (!done_header)
+	    {
+	      error = zMapGFFGetError(parser) ;
+
+	      if (!error)
+		{
+		  /* SHOULD ABORT HERE.... */
+		  setErrMsg(server, 
+			    g_strdup_printf("zMapGFFParseLine() failed with no GError for line %d: %s",
+					    zMapGFFGetLineNumber(parser), gff_line->str)) ;
+		  ZMAPSERVER_LOG(Critical, FILE_PROTOCOL_STR, server->file_path,
+				 "%s", server->last_err_msg) ;
+
+		  result = FALSE ;
+		}
+	      else
+		{
+		  /* If the error was serious we stop processing and return the error,
+		   * otherwise we just log the error. */
+		  if (zMapGFFTerminated(parser))
+		    {
+		      result = FALSE ;
+		      setErrMsg(server, g_strdup_printf("%s", error->message)) ;
+		    }
+		  else
+		    {
+		      setErrMsg(server,
+				g_strdup_printf("zMapGFFParseHeader() failed for line %d: %s",
+						zMapGFFGetLineNumber(parser),
+						gff_line->str)) ;
+		      ZMAPSERVER_LOG(Critical, FILE_PROTOCOL_STR, server->file_path,
+				     "%s", server->last_err_msg) ;
+		    }
+		}
+	    }
+
+	  break ;
+	}
+    }
+
+  if (gio_status == G_IO_STATUS_NORMAL && result)
+    {
+      header = zMapGFFGetHeader(parser) ;
+
+      addMapping(feature_context, header) ;
+
+      zMapGFFFreeHeader(header) ;
+    }
+
+
+  /* Clear up. */
+  zMapGFFDestroyParser(parser) ;
+  g_string_free(gff_line, TRUE) ;
+
+  return result ;
+}
+
+
+/* We insist that the header specifies the range of features required and we just use that
+ * for all the mappings. */
+static void addMapping(ZMapFeatureContext feature_context, ZMapGFFHeader header)
+{
+  ZMapFeatureBlock feature_block = NULL;//feature_context->master_align->blocks->data ;
+
+  feature_block = (ZMapFeatureBlock)(zMap_g_hash_table_nth(feature_context->master_align->blocks, 0)) ;
+
+  /* We just override whatever is already there...this may not be the thing to do if there
+   * are several files.... */
+  feature_context->parent_name = feature_context->sequence_name ;
+
+  /* In theory sequences all start at '1' so we insert that as the start of the parent, best we
+   * can do really. */
+#ifdef ED_G_NEVER_INCLUDE_THIS_CODE
+  feature_context->parent_span.x1 = header->features_start ;
+#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */
+  feature_context->parent_span.x1 = 1 ;
+  feature_context->parent_span.x2 = header->features_end ;
+
+  feature_context->sequence_to_parent.p1 = feature_context->sequence_to_parent.c1
+    = feature_block->block_to_sequence.q1 = feature_block->block_to_sequence.t1 = header->features_start ;
+
+  feature_context->sequence_to_parent.p2 = feature_context->sequence_to_parent.c2
+    = feature_block->block_to_sequence.q2 = feature_block->block_to_sequence.t2 = header->features_end ;
+
+  feature_context->length = feature_context->sequence_to_parent.c2 - feature_context->sequence_to_parent.c1 + 1;
+
+  return ;
+}
+
+
+
+/* For some data we need to go back to the start of the file and reread so this function
+ * simply resets the file pointer. */
+static gboolean resetToStart(FileServer server)
+{
+  gboolean result = FALSE ;
+  GError *error = NULL ;
+
+  if (g_io_channel_seek_position(server->gff_file, 0, G_SEEK_SET, &error) == G_IO_STATUS_NORMAL)
+    {
+      result = TRUE ;
+    }
+  else
+    {
+      setLastErrorMsg(server, &error) ;
+
+      result = FALSE ;
+    }
+      
+  return result ;
+}
+
+
+