diff --git a/projects/cadcTAP/src/ca/nrc/cadc/stc/Space.java b/projects/cadcTAP/src/ca/nrc/cadc/stc/Space.java
index b27f04a9056f88c3ba60d9afb16061e43534a153..9ad678ed998e7fe4785b15f5720713b978cc1391 100644
--- a/projects/cadcTAP/src/ca/nrc/cadc/stc/Space.java
+++ b/projects/cadcTAP/src/ca/nrc/cadc/stc/Space.java
@@ -69,387 +69,15 @@
 
 package ca.nrc.cadc.stc;
 
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Scanner;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-
-public abstract class Space
+/**
+ * Interface for a STC-S Space.
+ * 
+ */
+public interface Space
 {
-    private static Logger log;
-
-    // Default values.
-    private static final String DEFAULT_FRAME = "UNKNOWNFrame";
-    private static final String DEFAULT_REFPOS = "UNKNOWNRefPos";
-    private static final String DEFAULT_FLAVOR = "SPHER2";
-    private static final String DEFAULT_UNIT = "deg";
-    private static final String DEFAULT_UNIT_GEO = "deg deg m";
-    private static final String DEFAULT_UNIT_CART = "m";
-
-    // Dimensionality of the frame.
-    protected int dimensions;
-
-    // Words to process in the phrase?
-    protected boolean endOfWords;
-
-    // The current word from the scanner.
-    protected String currentWord;
-
-    // The tokenized phrase.
-    protected Scanner words;
-
-    // Formatter for Double values.
-    protected static DecimalFormat doubleFormat;
-
-    // Lists containing allowed values.
-    public static List<String> frames;
-    public static List<String> refposs;
-    public static List<String> flavors;
-    public static List<String> units;
-    static
-    {
-        // default log level is debug.
-        log = Logger.getLogger(Space.class);
-        log.setLevel((Level)Level.DEBUG);
-
-        // TODO: what is the format, should it even be used?
-        doubleFormat = new DecimalFormat("####.########");
-        doubleFormat.setDecimalSeparatorAlwaysShown(true);
-        doubleFormat.setMinimumFractionDigits(1);
-
-        // Allowed values for frame.
-        frames = new ArrayList<String>();
-        frames.add("ICRS");
-        frames.add("FK5");
-        frames.add("FK4");
-        frames.add("J2000");
-        frames.add("B1950");
-        frames.add("ECLIPTIC");
-        frames.add("GALACTIC");
-        frames.add("GALACTIC_II");
-        frames.add("SUPER_GALACTIC");
-        frames.add("GEO_C");
-        frames.add("GEO_D");
-        frames.add("UNKNOWNFrame");
-
-        // Allowed values for refpos.
-        refposs = new ArrayList<String>();
-        refposs.add("GEOCENTER");
-        refposs.add("BARYCENTER");
-        refposs.add("HELIOCENTER");
-        refposs.add("TOPOCENTER");
-        refposs.add("GALACTIC_CENTER");
-        refposs.add("EMBARYCENTER");
-        refposs.add("MOON");
-        refposs.add("MERCURY");
-        refposs.add("VENUS");
-        refposs.add("MARS");
-        refposs.add("JUPITER");
-        refposs.add("SATURN");
-        refposs.add("URANUS");
-        refposs.add("NEPTUNE");
-        refposs.add("PLUTO");
-        refposs.add("UNKNOWNRefPos");
-
-        // Allowed values for flavor.
-        flavors = new ArrayList<String>();
-        flavors.add("UNITSPHER");
-        flavors.add("SPHER2");
-        flavors.add("SPHER3");
-        flavors.add("CART1");
-        flavors.add("CART2");
-        flavors.add("CART3");
-
-        // Allowed values for unit.
-        units = new ArrayList<String>();
-        units.add("deg");
-        units.add("arcmin");
-        units.add("arcsec");
-        units.add("m");
-        units.add("mm");
-        units.add("km");
-        units.add("AU");
-        units.add("pc");
-        units.add("kpc");
-        units.add("Mpc");
-    }
-
-    /**
-     * STC-S phrase elements.
-     */
-    public String phrase;
-    public String space;
-    public Double fill;
-    public String frame;
-    public String refpos;
-    public String flavor;
-    public List<Double> position;
-    public String unit;
-    public List<Double> error;
-    public List<Double> resln;
-    public List<Double> size;
-    public List<Double> pixsiz;
-    public Velocity velocity;
-
-    /**
-     *
-     * @param space
-     */
-    public Space(String space)
-    {
-        this.space = space;
-    }
-
-    public Space(String space, String phrase)
-        throws StcsParsingException
-    {
-        if (phrase == null || phrase.length() == 0)
-            return;
-        this.space = space;
-        this.phrase = phrase;
-
-        endOfWords = false;
-        currentWord = null;
-        words = new Scanner(phrase);
-        words.useDelimiter("\\s");
-
-        // TODO: assign default values?
-//        dimensions = 2;
-//        frame = DEFAULT_FRAME;
-//        refpos = DEFAULT_REFPOS;
-//        flavor = DEFAULT_FLAVOR;
-
-        valiateSpace(space);
-        getFillfactor();
-        getFrame();
-        getRefpos();
-        getFlavor();
-        getDimensionality();
-        getPos();
-        getPosition();
-        getUnit();
-        getError();
-        getResolution();
-        getSize();
-        getPixSize();
-        getVelocity();
-    }
-
-    public abstract String toSTCString();
-
-    protected abstract void getPos() throws StcsParsingException;
-
-    protected void valiateSpace(String space)
-        throws StcsParsingException
-    {
-        if (words.hasNext(space))
-            words.next();
-        else
-        {
-            if (words.hasNext())
-                throw new StcsParsingException("Invalid space value, found " + words.next() + ", expecting " + space);
-            else
-                throw new StcsParsingException("Unexpected end to STC-S phrase, missing space value");
-        }
-        log.debug("space: " + space);
-    }
-
-    protected void getFillfactor()
-        throws StcsParsingException
-    {
-        if (words.hasNext("fillfactor"))
-        {
-            words.next();
-            if (words.hasNextDouble())
-                fill = words.nextDouble();
-            else
-            {
-                if (words.hasNext())
-                    throw new StcsParsingException("Invalid fillfactor value, expecting double, found " + words.next());
-                else
-                    throw new StcsParsingException("Unexpected end to STC-S phrase, missing fillfactor value");
-            }
-        }
-        log.debug("fillfactor: " + fill);
-    }
-
-    protected void getFrame()
-        throws StcsParsingException
-    {
-        if (words.hasNext())
-        {
-            frame = words.next();
-            if (!frames.contains(frame))
-                throw new StcsParsingException("Invalid frame element " + frame);
-        }
-        else
-        {
-            throw new StcsParsingException("Unexpected end to STC-S phrase, missing frame element");
-        }
-        log.debug("frame: " + frame);
-    }
-
-    protected void getRefpos()
-        throws StcsParsingException
-    {
-        if (words.hasNext())
-        {
-            currentWord = words.next();
-            if (refposs.contains(currentWord))
-            {
-                refpos = currentWord;
-                currentWord = null;
-            }
-        }
-        else
-        {
-            throw new StcsParsingException("Unexpected end to STC-S phrase before pos element");
-        }
-        log.debug("refpos: " + refpos);
-    }
-
-    protected void getFlavor()
-        throws StcsParsingException
-    {
-        if (currentWord == null)
-        {
-            if (words.hasNext())
-                currentWord = words.next();
-            else
-                throw new StcsParsingException("Unexpected end to STC-S phrase before pos element");
-        }
-        if (flavors.contains(currentWord))
-        {
-            flavor = currentWord;
-            currentWord = null;
-        }
-        else
-        {
-            throw new StcsParsingException("Invalid refpos or flavor element " + currentWord);
-        }
-        log.debug("flavor: " + flavor);
-    }
-
-    protected void getDimensionality()
-    {
-        if (flavor.equals("CART1"))
-            dimensions = 1;
-        if (flavor.equals("CART2") || flavor.equals("SPHER2"))
-            dimensions = 2;
-        if (flavor.equals("CART3") || flavor.equals("SPHER3") || flavor.equals("UNITSPHER"))
-            dimensions = 3;
-        log.debug("dimensions: " + dimensions);
-    }
-
-    protected void getPosition()
-        throws StcsParsingException
-    {
-        position = getListForElement("Position");
-    }
-
-    protected void getUnit()
-        throws StcsParsingException
-    {
-        if (endOfWords)
-            return;
-        if (currentWord == null)
-        {
-            if (words.hasNext())
-                currentWord = words.next();
-            else
-                endOfWords = true;
-        }
-        if (!endOfWords && currentWord.equals("unit"))
-        {
-            if (words.hasNext())
-            {
-                currentWord = words.next();
-                if (units.contains(currentWord))
-                {
-                    unit = currentWord;
-                    currentWord = null;
-                }
-                else
-                {
-                    throw new StcsParsingException("Invalid unit value " + currentWord);
-                }
-            }
-            else
-            {
-                throw new StcsParsingException("Unexpected end to STC-S phrase, missing unit value");
-            }
-        }
-        log.debug("unit: " + unit);
-    }
-
-    protected void getError()
-        throws StcsParsingException
-    {
-        error = getListForElement("Error");
-    }
-
-    protected void getResolution()
-        throws StcsParsingException
-    {
-        resln = getListForElement("Resolution");
-    }
-
-    protected void getSize()
-        throws StcsParsingException
-    {
-        size = getListForElement("Size");
-    }
-
-    protected void getPixSize()
-        throws StcsParsingException
-    {
-        pixsiz = getListForElement("PixSize");
-    }
-
-    protected void getVelocity()
-        throws StcsParsingException
-    {
-        if (!endOfWords && words.hasNext())
-            velocity = new Velocity(words);
-    }
+    String format(Space space);
 
-    private List<Double> getListForElement(String word)
-        throws StcsParsingException
-    {
-        if (endOfWords)
-            return null;
-        List<Double> values = null;
-        if (currentWord == null)
-        {
-            if (words.hasNext())
-                currentWord = words.next();
-            else
-                endOfWords = true;
-        }
-        if (!endOfWords && currentWord.equals(word))
-        {
-            if (!words.hasNextDouble())
-                throw new StcsParsingException(word + " element has no values");
-            while (words.hasNextDouble())
-            {
-                if (values == null)
-                    values = new ArrayList<Double>();
-                values.add(words.nextDouble());
-            }
-            currentWord = null;
-        }
-        log.debug(word + ": " + values);
-        return values;
-    }
+    Space parse(String phrase)
+        throws StcsParsingException;
 
-    protected String doubleListToString(List<Double> list)
-    {
-        StringBuilder sb = new StringBuilder();
-        for (Double d : list)
-            sb.append(doubleFormat.format(d)).append(" ");
-        return sb.toString();
-    }
 }