diff --git a/uk/ac/sanger/artemis/chado/ChadoCvTermView.java b/uk/ac/sanger/artemis/chado/ChadoCvTermView.java
index 9bd1d2b7c1b85c46fb5517e400cb9fcdd4ef3620..1705170933837b0a3feb26e35991ff38d54e913c 100644
--- a/uk/ac/sanger/artemis/chado/ChadoCvTermView.java
+++ b/uk/ac/sanger/artemis/chado/ChadoCvTermView.java
@@ -29,6 +29,7 @@ import org.gmod.schema.cv.CvTerm;
 
 import uk.ac.sanger.artemis.components.genebuilder.JExtendedComboBox;
 import uk.ac.sanger.artemis.components.genebuilder.cv.CvTermsComparator;
+import uk.ac.sanger.artemis.util.DatabaseLocationParser;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
@@ -345,33 +346,23 @@ public class ChadoCvTermView extends JFrame
     pfield = new JPasswordField(16);
     bacross.add(pfield);
 
+    
+    DatabaseLocationParser dlp; 
     // given -Dchado=localhost:port/dbname?username
     if(System.getProperty("chado") != null)
     {
       String db_url = System.getProperty("chado").trim();
-      int index;
-      if((index = db_url.indexOf(":")) > -1)
-      {
-        inServer.setText(db_url.substring(0, index));
-        int index2;
-        if((index2 = db_url.indexOf("/")) > -1)
-        {
-          inPort.setText(db_url.substring(index + 1, index2));
-          int index3;
-          if((index3 = db_url.indexOf("?")) > -1)
-          {
-            inDB.setText(db_url.substring(index2 + 1, index3));
-            inUser.setText(db_url.substring(index3 + 1));
-
-            /*
-             * if(!prompt_user) { location = "jdbc:postgresql://"
-             * +inServer.getText().trim()+ ":" +inPort.getText().trim()+ "/"
-             * +inDB.getText().trim()+ "?user=" +inUser.getText().trim(); return
-             * true; }
-             */
-          }
-        }
-      }
+      dlp = new DatabaseLocationParser(db_url);
+      inServer.setText(dlp.getHost());
+      inPort.setText("" + dlp.getPort());
+      inDB.setText(dlp.getDatabase());
+      inUser.setText(dlp.getUsername());
+   
+    }
+    else
+    {
+        // Still need to initialise the object
+        dlp = new DatabaseLocationParser();
     }
 
     int n = JOptionPane.showConfirmDialog(null, bacross,
@@ -379,10 +370,14 @@ public class ChadoCvTermView extends JFrame
         JOptionPane.QUESTION_MESSAGE);
     if(n == JOptionPane.CANCEL_OPTION)
       return false;
-
-    location = "jdbc:postgresql://" + inServer.getText().trim() + ":"
-        + inPort.getText().trim() + "/" + inDB.getText().trim() + "?user="
-        + inUser.getText().trim();
+    
+    
+    dlp.setHost(inServer.getText());
+    dlp.setPort(inPort.getText());
+    dlp.setDatabase(inDB.getText());
+    dlp.setUsername(inUser.getText());
+  
+    location = dlp.getCompleteURL();
 
     System.setProperty("chado", location);
     return true;
diff --git a/uk/ac/sanger/artemis/chado/ChadoDemo.java b/uk/ac/sanger/artemis/chado/ChadoDemo.java
index bed09f9ab153228fb4a2af203ac21abe02e987a3..b1b49370b02674b299fac026f011767874846138 100644
--- a/uk/ac/sanger/artemis/chado/ChadoDemo.java
+++ b/uk/ac/sanger/artemis/chado/ChadoDemo.java
@@ -79,7 +79,7 @@ import javax.swing.event.ListSelectionListener;
 import javax.swing.event.ListSelectionEvent;
 
 import uk.ac.sanger.artemis.util.ByteBuffer;
-
+import uk.ac.sanger.artemis.util.DatabaseLocationParser;
 
 /**
  * Chado data access example code. This searches for features by their
@@ -460,33 +460,18 @@ public class ChadoDemo
     pfield = new JPasswordField(16);
     bacross.add(pfield);
 
+    
+    DatabaseLocationParser dlp = new DatabaseLocationParser();
     // given -Dchado=localhost:port/dbname?username
     if(System.getProperty("chado") != null)
     {
       String db_url = System.getProperty("chado").trim();
-      int index;
-      if((index = db_url.indexOf(":")) > -1)
-      {
-        inServer.setText(db_url.substring(0, index));
-        int index2;
-        if((index2 = db_url.indexOf("/")) > -1)
-        {
-          inPort.setText(db_url.substring(index + 1, index2));
-          int index3;
-          if((index3 = db_url.indexOf("?")) > -1)
-          {
-            inDB.setText(db_url.substring(index2 + 1, index3));
-            inUser.setText(db_url.substring(index3 + 1));
-
-            /*
-             * if(!prompt_user) { location = "jdbc:postgresql://"
-             * +inServer.getText().trim()+ ":" +inPort.getText().trim()+ "/"
-             * +inDB.getText().trim()+ "?user=" +inUser.getText().trim(); return
-             * true; }
-             */
-          }
-        }
-      }
+      dlp.setFromURLString(db_url);
+      inServer.setText(dlp.getHost());
+      inPort.setText("" + dlp.getPort());
+      inDB.setText(dlp.getDatabase());
+      inUser.setText(dlp.getUsername());
+      
     }
 
     int n = JOptionPane.showConfirmDialog(null, bacross,
@@ -495,9 +480,12 @@ public class ChadoDemo
     if(n == JOptionPane.CANCEL_OPTION)
       return false;
 
-    location = "jdbc:postgresql://" + inServer.getText().trim() + ":"
-        + inPort.getText().trim() + "/" + inDB.getText().trim() + "?user="
-        + inUser.getText().trim();
+    dlp.setHost(inServer.getText());
+    dlp.setPort(inPort.getText());
+    dlp.setDatabase(inDB.getText());
+    dlp.setUsername(inUser.getText());
+  
+    location = dlp.getCompleteURL();
 
     System.setProperty("chado", location);
     
diff --git a/uk/ac/sanger/artemis/chado/DbSqlConfig.java b/uk/ac/sanger/artemis/chado/DbSqlConfig.java
index 7752fcc4ad56e44d4b995985898b9c5196491cee..5190f5fcffca6dfe5f18138def598eee27e298d1 100644
--- a/uk/ac/sanger/artemis/chado/DbSqlConfig.java
+++ b/uk/ac/sanger/artemis/chado/DbSqlConfig.java
@@ -29,6 +29,8 @@ import com.ibatis.sqlmap.client.SqlMapClient;
 import com.ibatis.sqlmap.client.SqlMapClientBuilder;
 import com.ibatis.common.resources.Resources;
 
+import uk.ac.sanger.artemis.util.DatabaseLocationParser;
+
 import javax.swing.JPasswordField;
 import java.util.Properties;
 import java.io.Reader;
@@ -49,6 +51,9 @@ public class DbSqlConfig
    * artemis_sqlmap/chado_iBatis_config.xml file and the
    * database location properties defined by the system property, 
    * <i>e.g.</i> -Dchado=localhost:2997/chado?tjc
+   * 
+   * It is especially important that the -Dchado argument is not prefixed with
+   * jdbc:postgresql:// as that is handled in iBatis
    *
    */
   public void init(JPasswordField fpasswd)
@@ -62,23 +67,13 @@ public class DbSqlConfig
      if(System.getProperty("chado") != null)
      {
        String url = System.getProperty("chado");
-       int index  = url.indexOf("?");
-       int index2 = url.indexOf("user=");
+       DatabaseLocationParser dlp = new DatabaseLocationParser(url);
        properties = new Properties();
 
-       int index3 = url.indexOf("://");
-       if(index3 < 0)
-         index3 = 0;
-       else
-         index3 = index3+3;
-
-       properties.put("chado", url.substring(index3,index)); 
-
-       if(index2 < 0)
-         properties.put("username", url.substring(index+1));
-       else
-         properties.put("username", url.substring(index2+5));
+       properties.put("chado",dlp.getUnprefixedURL());
 
+       properties.put("username",dlp.getUsername());
+       
        if(fpasswd != null && fpasswd.getPassword().length > 0)
          properties.put("password", new String(fpasswd.getPassword()));
      }
diff --git a/uk/ac/sanger/artemis/chado/JdbcDAO.java b/uk/ac/sanger/artemis/chado/JdbcDAO.java
index 6f1fa71484ab00c50e4bc4732e87cd81cf518c41..8f72e27e0f3b1656a5c0f5d5de6552b687721530 100644
--- a/uk/ac/sanger/artemis/chado/JdbcDAO.java
+++ b/uk/ac/sanger/artemis/chado/JdbcDAO.java
@@ -32,6 +32,8 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Vector;
 
+import uk.ac.sanger.artemis.util.DatabaseLocationParser;
+
 import org.gmod.schema.sequence.Feature;
 import org.gmod.schema.sequence.FeatureCvTerm;
 import org.gmod.schema.sequence.FeatureCvTermProp;
@@ -81,9 +83,9 @@ public class JdbcDAO extends GmodDAO
       conn = DriverManager.getConnection(location);
 
     // assume we have a password
-    final int index = location.indexOf("?user=");
-    conn = DriverManager.getConnection(location.substring(0, index),
-                                       location.substring(index + 6),
+    DatabaseLocationParser dlp = new DatabaseLocationParser(location);
+    conn = DriverManager.getConnection(dlp.getConnectionString(),
+                                       dlp.getUsername(),
                                        new String(pfield.getPassword()));
   }
 
diff --git a/uk/ac/sanger/artemis/components/ProjectProperty.java b/uk/ac/sanger/artemis/components/ProjectProperty.java
index 1011c641434c1bbcd5d5dc99d5b0d38aa721cd68..9b40765e471fb14d6bdb25bccf005d2e5dbcea2c 100644
--- a/uk/ac/sanger/artemis/components/ProjectProperty.java
+++ b/uk/ac/sanger/artemis/components/ProjectProperty.java
@@ -76,6 +76,7 @@ import uk.ac.sanger.artemis.components.database.DatabaseEntrySource;
 import uk.ac.sanger.artemis.components.database.DatabaseJPanel;
 import uk.ac.sanger.artemis.util.Document;
 import uk.ac.sanger.artemis.util.FileDocument;
+import uk.ac.sanger.artemis.util.DatabaseLocationParser;
 
 /**
  * Project file management system using a properties file.
@@ -726,9 +727,12 @@ public class ProjectProperty extends JFrame
   private void openDatabase(final Splash splash, final String featureName)
   {
     String loc = System.getProperty("chado");
-    int idx;
-    if((idx = loc.indexOf("?")) > -1 && loc.indexOf("?user=") == -1)
-      loc = loc.substring(0, idx+1) + "user=" + loc.substring(idx+1);
+    DatabaseLocationParser dlp = new DatabaseLocationParser(loc);
+    
+    
+//    int idx;
+//    if((idx = loc.indexOf("?")) > -1 && loc.indexOf("?user=") == -1)
+//      loc = loc.substring(0, idx+1) + "user=" + loc.substring(idx+1);
 
     if( entry_source == null || 
        !entry_source.getLocation().endsWith(loc) )
diff --git a/uk/ac/sanger/artemis/components/database/DatabaseEntrySource.java b/uk/ac/sanger/artemis/components/database/DatabaseEntrySource.java
index 6eaa7396367b5265fd71fa40b8f227c2dc99cc42..f8bbf93e5deb270f189f427d97e131867b77651b 100644
--- a/uk/ac/sanger/artemis/components/database/DatabaseEntrySource.java
+++ b/uk/ac/sanger/artemis/components/database/DatabaseEntrySource.java
@@ -30,6 +30,7 @@ import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.io.IOException;
 import java.io.Serializable;
+import javax.swing.JCheckBox;
 
 import javax.swing.JLabel;
 import javax.swing.JOptionPane;
@@ -43,6 +44,7 @@ import uk.ac.sanger.artemis.Options;
 import uk.ac.sanger.artemis.sequence.Bases;
 import uk.ac.sanger.artemis.sequence.NoSequenceException;
 import uk.ac.sanger.artemis.util.DatabaseDocument;
+import uk.ac.sanger.artemis.util.DatabaseLocationParser;
 import uk.ac.sanger.artemis.util.InputStreamProgressListener;
 import uk.ac.sanger.artemis.util.OutOfRangeException;
 import uk.ac.sanger.artemis.util.StringVector;
@@ -185,13 +187,14 @@ public class DatabaseEntrySource implements EntrySource, Serializable
     }
     
     pfield = promptPanel.getPfield();
+    DatabaseLocationParser dlp = new DatabaseLocationParser();
+    dlp.setHost(promptPanel.getServer());
+    dlp.setPort(promptPanel.getPort());
+    dlp.setDatabase(promptPanel.getDb());
+    dlp.setUsername(promptPanel.getUser());
+    dlp.setSSL(promptPanel.getSSL());
     
-    location = "jdbc:postgresql://" + 
-               promptPanel.getServer() + ":" +
-               promptPanel.getPort() + "/" +
-               promptPanel.getDb() + "?user=" +
-               promptPanel.getUser();
-
+    location = dlp.getCompleteURL();
     return true;
   }
   
@@ -340,6 +343,7 @@ interface ILoginPrompt
     String getPort();
     String getDb();
     String getUser();
+    boolean getSSL();
 }
 
 /**
@@ -353,6 +357,7 @@ class DatabaseLoginPrompt extends JPanel implements ILoginPrompt
   private JTextField port;
   private JTextField db;
   private JTextField user;
+  private JCheckBox ssl;
   public DatabaseLoginPrompt()
   {
     super(new GridBagLayout());
@@ -378,6 +383,9 @@ class DatabaseLoginPrompt extends JPanel implements ILoginPrompt
     c.gridy = ++nrow;
     add(new JLabel("Password : "), c);
 
+    c.gridy = ++nrow;
+    add(new JLabel("SSL : "), c);
+    
     // column 2
     nrow = 1;
     c.anchor = GridBagConstraints.WEST;
@@ -396,12 +404,16 @@ class DatabaseLoginPrompt extends JPanel implements ILoginPrompt
     add(db, c);
 
     c.gridy = ++nrow;
-    user = new JTextField("afumigatus");
+    user = new JTextField("");
     add(user, c);
     
     c.gridy = ++nrow;
     pfield = new JPasswordField(16);
     add(pfield, c);
+    
+    c.gridy = ++nrow;
+    ssl = new JCheckBox();
+    add(ssl, c);
 
     // given -Dchado=localhost:port/dbname?username
     if(System.getProperty("chado") != null)
@@ -436,44 +448,12 @@ class DatabaseLoginPrompt extends JPanel implements ILoginPrompt
   
   private void setFromURL(String db_url)
   {
-    if(db_url.startsWith("jdbc:postgresql://"))
-      db_url = db_url.substring(18);
-    
-    int index;
-    if((index = db_url.indexOf(":")) > -1)
-    {
-      server.setText(db_url.substring(0, index));
-      int index2;
-      if((index2 = db_url.indexOf("/")) > -1)
-      {
-        port.setText(db_url.substring(index + 1, index2));
-        int index3;
-        if((index3 = db_url.indexOf("?")) > -1)
-        {
-          db.setText(db_url.substring(index2 + 1, index3));
-          
-          String userStr = db_url.substring(index3 + 1);
-          if(userStr.startsWith("user="))
-            userStr = userStr.substring(5);
-          user.setText(userStr);
-
-          /*
-           * if(!prompt_user) { location = "jdbc:postgresql://"
-           * +inServer.getText().trim()+ ":" +inPort.getText().trim()+ "/"
-           * +inDB.getText().trim()+ "?user=" +inUser.getText().trim(); return
-           * true; }
-           */
-        }
-        /** 
-            @TODO GSV determine if the case where a user only passes in db name without a user name should be handled like this:
-            } else
-	        {
-	            db = (db_url.substring(index2 + 1));
-	        }
-	    /*/
-        
-      }
-    }  
+      DatabaseLocationParser dlp = new DatabaseLocationParser(db_url);
+      server.setText(dlp.getHost());
+      port.setText("" + dlp.getPort());
+      db.setText(dlp.getDatabase());
+      user.setText(dlp.getUsername());
+      ssl.setSelected(dlp.isSSLEnabled());
   }
   
   /**
@@ -554,6 +534,11 @@ class DatabaseLoginPrompt extends JPanel implements ILoginPrompt
   {
     return user.getText().trim();
   }
+  
+  public boolean getSSL()
+  {
+    return ssl.isSelected();
+  }
 }
 
 class DatabaseLoginPromptConsole implements ILoginPrompt
@@ -563,6 +548,7 @@ class DatabaseLoginPromptConsole implements ILoginPrompt
 	private String port;
 	private String db;
 	private String user;
+        private String ssl;
 
 	public DatabaseLoginPromptConsole()
 	{
@@ -583,33 +569,12 @@ class DatabaseLoginPromptConsole implements ILoginPrompt
 	
 	private void setFromURL(String db_url)
 	  {
-	    if(db_url.startsWith("jdbc:postgresql://"))
-	      db_url = db_url.substring(18);
-	    
-	    int index;
-	    if((index = db_url.indexOf(":")) > -1)
-	    {
-	      server = (db_url.substring(0, index));
-	      int index2;
-	      if((index2 = db_url.indexOf("/")) > -1)
-	      {
-	        port = (db_url.substring(index + 1, index2));
-	        int index3;
-	        if((index3 = db_url.indexOf("?")) > -1)
-	        {
-	          db = (db_url.substring(index2 + 1, index3));
-	          
-	          String userStr = db_url.substring(index3 + 1);
-	          if(userStr.startsWith("user="))
-	            userStr = userStr.substring(5);
-	          user = (userStr);
-
-	        } else
-	        {
-	            db = (db_url.substring(index2 + 1));
-	        }
-	      }
-	    }  
+              DatabaseLocationParser dlp = new DatabaseLocationParser(db_url);
+              server = dlp.getHost();
+              port = "" + dlp.getPort();
+              db = dlp.getDatabase();
+              user = dlp.getUsername();
+              ssl = dlp.isSSLEnabled() ? "y" : "";
 	  }
 	
 	public JPasswordField getPfield()
@@ -638,6 +603,11 @@ class DatabaseLoginPromptConsole implements ILoginPrompt
 	{
 		return user;
 	}
+        
+        public boolean getSSL()
+        {
+                return ssl.toLowerCase().equals("y") || ssl.toLowerCase().equals("yes");
+        }
 
 	public boolean prompt() 
 	{
@@ -672,6 +642,11 @@ class DatabaseLoginPromptConsole implements ILoginPrompt
 			password = UI.userInput("Enter Password", true);
 			userEntered = true;
 		}
+                if (ssl == null)
+		{
+			ssl = UI.userInput("Use SSL [y/n]", false);
+			userEntered = true;
+		}
 		
 		/**
 		    GSV found that that this should always return true
diff --git a/uk/ac/sanger/artemis/util/DatabaseDocument.java b/uk/ac/sanger/artemis/util/DatabaseDocument.java
index 2c27582bca97f323e63dc3a3a9e1f7ff21db85b4..a8f5abe276c25a7abfc3b95e953ec65cd7067e14 100644
--- a/uk/ac/sanger/artemis/util/DatabaseDocument.java
+++ b/uk/ac/sanger/artemis/util/DatabaseDocument.java
@@ -43,6 +43,7 @@ import uk.ac.sanger.artemis.chado.ChadoTransaction;
 import uk.ac.sanger.artemis.components.database.DatabaseEntrySource;
 import uk.ac.sanger.artemis.components.genebuilder.GeneUtils;
 import uk.ac.sanger.artemis.components.Splash;
+import uk.ac.sanger.artemis.util.DatabaseLocationParser;
 
 import org.gmod.schema.sequence.Feature;
 import org.gmod.schema.sequence.FeatureProp;
@@ -173,7 +174,7 @@ public class DatabaseDocument extends Document
    * 
    * @param location
    *          This should be a URL string giving:
-   *          jdbc:postgresql://host:port/datbase_name?user=username
+   *          jdbc:postgresql://host:port/database_name?user=username
    * 
    */
   public DatabaseDocument(String location, JPasswordField pfield)
@@ -229,7 +230,7 @@ public class DatabaseDocument extends Document
    * 
    * @param location
    *          This should be a URL string giving:
-   *          jdbc:postgresql://host:port/datbase_name?user=username
+   *          jdbc:postgresql://host:port/database_name?user=username
    * @param srcFeatureId
    *          ID of a feature to be extracted.
    * @param splitGFFEntry
@@ -2473,18 +2474,20 @@ public class DatabaseDocument extends Document
         } 
       });  
     }
-    catch(RuntimeException sqlExp)
+    catch(RuntimeException runExp)
     {
-      JOptionPane.showMessageDialog(null, "SQL Problems...\n"+
+        runExp.printStackTrace();
+      JOptionPane.showMessageDialog(null, "Runtime Problems...\n"+
                                     getLocation()+"\n"+
-                                    sqlExp.getMessage(), 
-                                    "SQL Error",
+                                    runExp.getMessage(), 
+                                    "Runtime Error",
                                     JOptionPane.ERROR_MESSAGE);
       
-      logger4j.debug(sqlExp.getMessage());
+      logger4j.debug(runExp.getMessage());
     }
     catch(ConnectException exp)
     {
+        exp.printStackTrace();
       JOptionPane.showMessageDialog(null, "Connection Problems...\n"+
             exp.getMessage(), 
             "Connection Error",
@@ -2494,6 +2497,7 @@ public class DatabaseDocument extends Document
     }
     catch(java.sql.SQLException sqlExp)
     {
+        sqlExp.printStackTrace();
       JOptionPane.showMessageDialog(null, "SQL Problems....\n"+
                                     getLocation()+"\n"+
                                     sqlExp.getMessage(), 
@@ -2643,13 +2647,16 @@ public class DatabaseDocument extends Document
     // "localhost:10001/backup?chado"
     
     String url = (String)getLocation();
-    int index  = url.indexOf("?");
-    
-    String userName = url.substring(index+1).trim();
-    if(userName.startsWith("user="))
-      userName = userName.substring(5);
-    
-    return userName;
+    DatabaseLocationParser dlp = new DatabaseLocationParser(url);
+    
+//    
+//    int index  = url.indexOf("?");
+//    
+//    String userName = url.substring(index+1).trim();
+//    if(userName.startsWith("user="))
+//      userName = userName.substring(5);
+//    
+    return dlp.getUsername();
   }
   
   private GmodDAO getDAOOnly()
diff --git a/uk/ac/sanger/artemis/util/DatabaseLocationParser.java b/uk/ac/sanger/artemis/util/DatabaseLocationParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..2262d9d6fe0fa7fcf2f044513b6c8913ea583334
--- /dev/null
+++ b/uk/ac/sanger/artemis/util/DatabaseLocationParser.java
@@ -0,0 +1,375 @@
+/* DatabaseLocationParser.java
+ *
+ * created: Jun 2013
+ *
+ * This file is part of Artemis
+ *
+ * Copyright (C) 2001  Genome Research Limited
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+package uk.ac.sanger.artemis.util;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ *
+ * @author Eric Rasche <rasche.eric@yandex.ru>
+ */
+public class DatabaseLocationParser {
+
+    private String host;
+    private String database;
+    private int port = 0;
+    private String db_engine = "postgresql";
+    private String protocol = "jdbc";
+    private static org.apache.log4j.Logger logger4j =
+            org.apache.log4j.Logger.getLogger(DatabaseLocationParser.class);
+    /**
+     * Desire use of Protocol in the final URL. i.e., "jdbc:"
+     */
+    public static final int PROTOCOL = 1;
+    /**
+     * Desire use of scheme in final url. i.e., "postgres://"
+     */
+    public static final int SCHEME = 2;
+    /**
+     * Desire use of database name in final url.
+     *
+     */
+    public static final int DATABASE_NAME = 4;
+    /**
+     * Desire listing of query parameters in final url. e.g.,
+     * "user=name&ssl=true"
+     */
+    public static final int QUERY_PARAMS = 8;
+    private Map<String, String> params = new HashMap<String, String>();
+
+    /**
+     * Empty initializer
+     */
+    public DatabaseLocationParser() {
+    }
+
+    /**
+     * Create a new DLP object from a given URL
+     *
+     * @param url
+     */
+    public DatabaseLocationParser(String url) {
+        setFromURLString(url);
+    }
+
+    /**
+     * Set the URL internally and parse out important portions.
+     *
+     * @param url
+     */
+    private void setFromURLString(String url) {
+        logger4j.debug("DLP was called with a URL of [" + url + "]");
+        try {
+            //"jdbc:postgres://localhost:5432/drupal6?user=drupal6&ssl=true";
+
+            //If it's prefixed, remove that so URI parsing is correct
+            if (url.startsWith("jdbc:")) {
+                url = url.substring(5);
+            }
+            if (!url.startsWith(db_engine + "://")) {
+                url = db_engine + "://" + url;
+            }
+
+
+            URI db_loc = new URI(url);
+
+            logger4j.debug("URI " + db_loc.toString());
+            logger4j.debug("Host: " + db_loc.getHost());
+            logger4j.debug("Port: " + db_loc.getPort());
+            logger4j.debug("Engine: " + db_loc.getScheme());
+            logger4j.debug("DB: " + db_loc.getPath());
+
+            host = db_loc.getHost();
+
+            database = db_loc.getPath().substring(1);
+
+            port = db_loc.getPort();
+
+            db_engine = db_loc.getScheme();
+
+            //Split on '&' and parse each subunit
+            String[] query_params = db_loc.getQuery().split("&");
+            for (int i = 0; i < query_params.length; i++) {
+                //Split based on the equals sign
+                logger4j.debug("Given a parameter:" + query_params[i]);
+                String[] parts = query_params[i].split("=");
+
+
+                //This will fail for input like user=chad=o&ssl=true
+                //As we'll only grab user=chad
+                // Then again, who has an equals sign in their username
+                if (parts.length > 1) {
+                    params.put(parts[0], parts[1]);
+                    logger4j.debug("[" + parts[0] + "," + parts[1] + "]");
+
+                } else {
+                    // This might fail strangely, but then again they're providing funky URLs
+                    params.put("user", parts[0]);
+                    logger4j.debug("[user," + parts[0] + "]");
+                }
+            }
+        } catch (URISyntaxException ex) {
+            logger4j.warn("Error parsing URL [" + url + "]" + ex);
+        }
+        logger4j.debug("This has a complete_url of [" + getCompleteURL() + "]");
+    }
+
+    /**
+     * Returns the complete URL
+     *
+     * @return complete url
+     */
+    public String getCompleteURL() {
+        return getURLWithFixes(PROTOCOL | SCHEME
+                | DATABASE_NAME | QUERY_PARAMS);
+    }
+
+    /**
+     * Returns the URL as required for a DriverManager.getConnection object
+     *
+     * @return url as required for a SQL connection
+     */
+    public String getConnectionString() {
+        return getURLWithFixes(PROTOCOL | SCHEME
+                | DATABASE_NAME | QUERY_PARAMS);
+    }
+
+    /**
+     * Returns the unprefixed URL, for classes that automatically prepend
+     * 'jdbc:postgres://'.
+     *
+     * This is important for uk/ac/sanger/artemis/chado/DbSqlConfig.java
+     *
+     * @return unprefixed url with database and query parameters appended.
+     */
+    public String getUnprefixedURL() {
+        return getURLWithFixes(DATABASE_NAME | QUERY_PARAMS);
+    }
+
+    /**
+     * Returns a URL with a selection of modifications.
+     *
+     * Using a binary OR, one can select which modifications should be applied
+     * to create the final URL. These modifications consist of:
+     *
+     * - PROTOCOL: "jdbc:" - SCHEME: "postgresql://" - DATABASE_NAME: The
+     * supplied database name - QUERY_PARAMS: The supplied query parameters
+     * (user, ssl, etc)
+     *
+     * @param modifications, a binary OR'd selection of PROTOCOL, SCHEME,
+     * DATABASE_NAME, QUERY_PARAMS, all of which are available as public final
+     * static integers from this class
+     * @return String version of a URL, modified according to the rules
+     * supplied.
+     */
+    public String getURLWithFixes(int modifications) {
+        try {
+            String scheme = new String(db_engine);
+            String userInfo = null;
+            int db_port = new Integer(port);
+            String db_name = "/" + database;
+            String query_params = "";
+            String fragment = null;
+
+            String result = "";
+            if ((modifications & PROTOCOL) == PROTOCOL) {
+                result += protocol + ":";
+            }
+            if ((modifications & SCHEME) != SCHEME) {
+                scheme = null;
+            }
+            if ((modifications & DATABASE_NAME) != DATABASE_NAME) {
+                db_name = null;
+            }
+
+            // Query Parameters
+            // "user=chado_user&ssl=true"
+            if ((modifications & QUERY_PARAMS) == QUERY_PARAMS) {
+                if (params.size() > 0) {
+                    /**
+                     * Handling of the query parameters. There are other ways to
+                     * do this, but it's probably never going to be more than a
+                     * "user" and an "ssl" parameter, which means that in the
+                     * grand scheme of things, joining a couple strings together
+                     * isn't a big issue
+                     */
+                    Set<String> keys = params.keySet();
+                    java.util.Iterator<String> it = keys.iterator();
+                    while (it.hasNext()) {
+                        String key = it.next();
+                        query_params += key + "=" + params.get(key) + "&";
+                    }
+                    query_params = query_params.substring(0, query_params.length() - 1);
+                }
+            }
+            URI uri_result = new URI(scheme, userInfo, host, db_port, db_name, query_params, fragment);
+            logger4j.debug("Pre-final URL: " + uri_result.toString());
+
+            result = result + uri_result.toString();
+            //Bugfix. Even if SCHEME is null, // is still prepended. so we remove
+            if ((modifications & SCHEME) != SCHEME && (modifications & PROTOCOL) != PROTOCOL) {
+                result = result.substring(2);
+            }
+            return result;
+        } catch (URISyntaxException ex) {
+            logger4j.error("Could not construct URL. This will likely cause an "
+                    + "SQL connection failure. ");
+        }
+        return null;
+    }
+
+    /**
+     * Checks whether SSL is enabled
+     *
+     * @return true if SSL is enabled
+     */
+    public boolean isSSLEnabled() {
+        if (params.containsKey("ssl")) {
+            return params.get("ssl").equals("true");
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns the hostname
+     *
+     * @return the hostname
+     */
+    public String getHost() {
+        return host;
+    }
+
+    /**
+     * Returns the database
+     *
+     * @return the database name
+     */
+    public String getDatabase() {
+        return database;
+    }
+
+    /**
+     * Returns the port number
+     *
+     * @return port number
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Returns the username of the user connecting to the database
+     *
+     * @return username
+     */
+    public String getUsername() {
+        if (params.containsKey("user")) {
+            return params.get("user");
+        } else {
+            return "chado"; //That's the default u/n afaik
+        }
+    }
+
+    /**
+     * Returns the database engine
+     *
+     * @return database engine (usu. postgresql)
+     */
+    public String getDBEngine() {
+        return db_engine;
+    }
+
+    /**
+     * Sets the hostname
+     *
+     * @param hostname
+     */
+    public void setHost(String hostname) {
+        host = hostname.trim();
+    }
+
+    /**
+     * Sets the database name
+     *
+     * @param new_db_name
+     */
+    public void setDatabase(String new_db_name) {
+        database = new_db_name.trim();
+    }
+
+    /**
+     * Sets the port number
+     *
+     * @param new_port_number
+     */
+    public void setPort(String new_port_number) {
+        port = Integer.parseInt(new_port_number.trim());
+    }
+
+    /**
+     * Sets the port number
+     *
+     * @param new_port_number
+     */
+    public void setPort(int new_port_number) {
+        port = new_port_number;
+    }
+
+    /**
+     * Sets the username to connect with
+     *
+     * @param new_username
+     */
+    public void setUsername(String new_username) {
+        params.put("user", new_username.trim());
+    }
+
+    /**
+     * Enables or disables SSL in connection URL
+     *
+     * @param is_enabled
+     */
+    public void setSSL(boolean is_enabled) {
+        if (is_enabled) {
+            params.put("ssl", "true");
+        } else {
+            params.remove("ssl");
+        }
+    }
+
+    /**
+     * Sets the Database Engine
+     *
+     * @param new_db_engine
+     */
+    public void setDBEngine(String new_db_engine) {
+        db_engine = new_db_engine.trim();
+    }
+}