diff --git a/examples/user_types/TDDecoder.java b/examples/user_types/TDDecoder.java
index 6bfdb3ca8f33b5af819472e65a229f4f177e3fd3..2f6caf5ac4054c7cba5beb817fd532e7fb8e8550 100644
--- a/examples/user_types/TDDecoder.java
+++ b/examples/user_types/TDDecoder.java
@@ -32,6 +32,8 @@ public class TDDecoder
 
   private DecoderChannel decoder;
   private TypeDefParser tdp;
+  private final ASTbuilder astBuilder;
+  private Program curAST;
 
   public TDDecoder(InputStream in) 
     throws Exception 
@@ -45,6 +47,7 @@ public class TDDecoder
     intAndRef.register(decoder, this);
     doavoid.registerSampleRef(decoder);
     this.tdp = TypeDefParser.registerTypeDefParser(decoder); 
+    this.astBuilder = new ASTbuilder(tdp);
  //   TypeDef.register(decoder, this);
  //   TypeBinding.register(decoder, this);
 
@@ -78,8 +81,7 @@ public class TDDecoder
   public void onTypeDef(TypeDefParser.ParsedTypeDef d) {
     if(d.isSampleDef()){
         System.out.println("onTypeDef (sample): ");
-        ASTbuilder v = new ASTbuilder();
-        Program p = v.makeProgram((TypeDefParser.ParsedSampleDef) d);
+        Program p = astBuilder.makeProgram(d, curAST);
         try {
                 //FileOutputStream f = new FileOutputStream("/tmp/foopp"+d.getName()+".txt");
                 //PrintStream out = new PrintStream(f);
@@ -91,6 +93,7 @@ public class TDDecoder
                 System.err.println("Exception: " + e);
                 e.printStackTrace();
         }
+        curAST = p;
     }
     //System.out.println(" "+d.getName()+";");
     //for(byte b: d.getSignature()) {
diff --git a/lib/java/se/lth/control/labcomm/ASTbuilder.java b/lib/java/se/lth/control/labcomm/ASTbuilder.java
index 73bd171750c722c910a12549f535272eafc3b5a5..d16b15621bfab4335b96cca4084fb4a2a8c59383 100644
--- a/lib/java/se/lth/control/labcomm/ASTbuilder.java
+++ b/lib/java/se/lth/control/labcomm/ASTbuilder.java
@@ -41,38 +41,40 @@ import se.lth.control.labcomm2014.compiler.VariableSize;
  */
 public class ASTbuilder implements TypeDefParser.ParsedSymbolVisitor {
 
-        private LinkedList<Type> typeStack;
-        private LinkedList<Field> fieldStack;
+    private LinkedList<Type> typeStack;
+    private LinkedList<Field> fieldStack;
+    private TypeDefParser tdp;
+
+    public ASTbuilder(TypeDefParser tdp) {
+        this.typeStack = new LinkedList<Type>();
+        this.fieldStack = new LinkedList<Field>();
+        this.tdp = tdp;
+    }
 
-        public ASTbuilder() {
-            this.typeStack = new LinkedList<Type>();
-            this.fieldStack = new LinkedList<Field>();
+    private void assertStacksEmpty() throws RuntimeException {
+        if(!typeStack.isEmpty()) {
+           throw new RuntimeException("Error: type stack not empty"); 
         }
-
-        private void assertStacksEmpty() throws RuntimeException {
-            if(!typeStack.isEmpty()) {
-               throw new RuntimeException("Error: type stack not empty"); 
-            }
-            if(!fieldStack.isEmpty()) {
-               throw new RuntimeException("Error: field stack not empty"); 
-            }
+        if(!fieldStack.isEmpty()) {
+           throw new RuntimeException("Error: field stack not empty"); 
         }
+    }
 
-        public void visit(TypeDefParser.TypeSymbol s){
-            throw new Error("not implemented? needed?");
+    public void visit(TypeDefParser.TypeSymbol s){
+        throw new Error("not implemented? needed?");
 
-        }
-        public void visit(TypeDefParser.SampleSymbol s){
-            throw new Error("not implemented? needed?");
+    }
+    public void visit(TypeDefParser.SampleSymbol s){
+        throw new Error("not implemented? needed?");
 
-        }
-        public void visit(TypeDefParser.NameSymbol s){
-            throw new Error("not implemented? needed?");
-        }
+    }
+    public void visit(TypeDefParser.NameSymbol s){
+        throw new Error("not implemented? needed?");
+    }
 
-        public void visit(TypeDefParser.PrimitiveType t){
-            typeStack.push(new PrimType(t.getName(), t.getTag()));
-        }
+    public void visit(TypeDefParser.PrimitiveType t){
+        typeStack.push(new PrimType(t.getName(), t.getTag()));
+    }
 
 // SampleRefs are currently represented as primitive types,
 // see comment in TypeDefParser
@@ -80,98 +82,140 @@ public class ASTbuilder implements TypeDefParser.ParsedSymbolVisitor {
 //            typeStack.push(new SampleRefType());
 //        }
 
-        public void visit(TypeDefParser.ParsedStructType t){
-            if(t.isVoid()) {
-                typeStack.push(new VoidType());
-            } else {
-                List<Field> tmpF = new List<Field>();
-                for( TypeDefParser.ParsedField f : t.getFields()) {
-                    f.accept(this);
-                    tmpF.add(fieldStack.pop());
-                }
-                typeStack.push(new StructType(tmpF));
+    public void visit(TypeDefParser.ParsedStructType t){
+        if(t.isVoid()) {
+            typeStack.push(new VoidType());
+        } else {
+            List<Field> tmpF = new List<Field>();
+            for( TypeDefParser.ParsedField f : t.getFields()) {
+                f.accept(this);
+                tmpF.add(fieldStack.pop());
             }
+            typeStack.push(new StructType(tmpF));
         }
-        public void visit(TypeDefParser.ParsedField t){
-            t.getType().accept(this);
-            fieldStack.push(new Field(typeStack.pop(),t.getName()));
-
-        }
-        public void visit(TypeDefParser.ArrayType t){
-            boolean isFixed = true;
-            List<Exp> dim = new List<Exp>();
-            for(int i : t.getIdx()) {
-                if(i == 0) {
-                    dim.add(new VariableSize());
-                    isFixed = false;
-                } else {
-                    dim.add(new IntegerLiteral(Integer.toString(i)));
-                }
-            }
-            t.getType().accept(this);
-            if(isFixed) {
-                typeStack.push(new FixedArrayType(typeStack.pop(), dim));
+    }
+    public void visit(TypeDefParser.ParsedField t){
+        t.getType().accept(this);
+        fieldStack.push(new Field(typeStack.pop(),t.getName()));
+  
+    }
+    public void visit(TypeDefParser.ArrayType t){
+        boolean isFixed = true;
+        List<Exp> dim = new List<Exp>();
+        for(int i : t.getIdx()) {
+            if(i == 0) {
+                dim.add(new VariableSize());
+                isFixed = false;
             } else {
-                typeStack.push(new VariableArrayType(typeStack.pop(), dim));
+                dim.add(new IntegerLiteral(Integer.toString(i)));
             }
-
         }
-        public void visit(TypeDefParser.ParsedUserType t){
-            typeStack.push(new UserType(t.getName()));
+        t.getType().accept(this);
+        if(isFixed) {
+            typeStack.push(new FixedArrayType(typeStack.pop(), dim));
+        } else {
+            typeStack.push(new VariableArrayType(typeStack.pop(), dim));
         }
+  
+    }
+    public void visit(TypeDefParser.ParsedUserType t){
+        typeStack.push(new UserType(t.getName()));
+    }
+  
 
+    public Decl makeDecl(TypeDefParser.ParsedTypeDef d) {
+        d.getType().accept(this);
+        Decl result = new TypeDecl(typeStack.pop(), d.getName());
+        return result;
+    }
 
-       public Decl makeDecl(TypeDefParser.ParsedTypeDef d) {
-           d.getType().accept(this);
-           Decl result = new TypeDecl(typeStack.pop(), d.getName());
-           return result;
+    private Program createAndCheckProgram(List<Decl> ds) {
+       Program p = new Program(ds);
+       LinkedList errors = new LinkedList();
+       p.errorCheck(errors);
+       if(errors.isEmpty()) {
+           return p;
+       } else {
+           // This should not happen
+           // get errors and throw exception
+           StringBuilder sb = new StringBuilder();
+           for (Iterator iter = errors.iterator(); iter.hasNext(); ) {
+               String s = (String)iter.next();
+               sb.append(s);
+           }
+           throw new RuntimeException("Internal error: parsed labcomm declaration has errors: "+sb.toString());
        }
+    }
 
-       private Program createAndCheckProgram(List<Decl> ds) {
-            Program p = new Program(ds);
-            LinkedList errors = new LinkedList();
-            p.errorCheck(errors);
-            if(errors.isEmpty()) {
-                return p;
-            } else {
-                // This should not happen
-                // get errors and throw exception
-                StringBuilder sb = new StringBuilder();
-                for (Iterator iter = errors.iterator(); iter.hasNext(); ) {
-                    String s = (String)iter.next();
-                    sb.append(s);
-                }
-                throw new RuntimeException("Internal error: parsed labcomm declaration has errors: "+sb.toString());
-            }
-       }
-       
-       public Program makeProgram(TypeDefParser.ParsedTypeDef d) {
-           assertStacksEmpty();
-           List<Decl> ds = new List<Decl>();
-
-           ds.add(makeDecl(d));
-           assertStacksEmpty();
-           return createAndCheckProgram(ds);
-       }
+    /** Create a labcomm AST for the ParsedTypeDef d.
+     *  If d is a sampleDecl, include the typedefs it depends on.
+     */
+    public Program makeProgram(TypeDefParser.ParsedTypeDef d) {
+        List<Decl> ds = new List<Decl>();
+        return makeProgram(d, ds);
+    }
 
-       public Decl makeDecl(TypeDefParser.ParsedSampleDef d) {
-           d.getType().accept(this);
-           Decl result = new SampleDecl(typeStack.pop(), d.getName());
-           return result;
-       }
-       public Program makeProgram(TypeDefParser.ParsedSampleDef d) {
-           assertStacksEmpty();
-           List<Decl> ds = new List<Decl>();
+    /** Create a labcomm AST for the ParsedTypeDef d, including
+     *  all declarations from p.
+     *
+     *  This copies the declarations in p, and creates a new AST.
+     *
+     *  If d is a sampleDecl, include the typedefs it depends on.
+     */
+    public Program makeProgram(TypeDefParser.ParsedTypeDef d,
+                               Program p) {
+        if(p != null) {
+           return makeProgram(d, p.getDecls().fullCopy());
+        } else {
+           return makeProgram(d);
+        }
+    }
 
-           Iterator<TypeDefParser.ParsedTypeDef> it = d.getDepIterator();
-           while(it.hasNext()){
-               ds.add(makeDecl(it.next()));
-           }
 
-           ds.add(makeDecl(d));
 
-           assertStacksEmpty();
-           return createAndCheckProgram(ds);
-       }
+    //TODO: The above method, adding to an arbitrary Program
+    //      does not really allow "recreating the labcomm file"
+    //      This method is a placeholder for 
+    public Program makeProgram(TypeDefParser.ParsedTypeDef d,
+                               TypeDefParser source) {
+        throw new Error("Not yet implemented");
     }
-
+    
+    private void tryAdd(Decl decl, List<Decl> ds){
+        boolean exists = false;
+
+        // Check if decl already exists in ds
+        // otherwise add it
+
+        // Maybe add a Program.lookupDecl(String Name) 
+        // to the NameAnalysis aspect instead of doing
+        // it here.
+        Iterator<Decl> it = ds.iterator();
+        while(!exists && it.hasNext()) {
+            Decl inList = it.next();
+            if(inList.getName().equals(decl.getName())){
+                exists = true;
+            }
+        }
+        if(!exists) {
+            ds.add(decl);
+        } 
+    }
+    
+    protected Program makeProgram(TypeDefParser.ParsedTypeDef d,
+                                  List<Decl> ds) {
+        assertStacksEmpty();
+
+        // add dependencies for sample decls
+        if(d.isSampleDef()) {
+            Iterator<TypeDefParser.ParsedTypeDef> it = d.getDepIterator();
+            while(it.hasNext()){
+                Decl decl = makeDecl(it.next());
+                tryAdd(decl,ds);
+            }
+        }
+        ds.add(makeDecl(d));
+        assertStacksEmpty();
+        return createAndCheckProgram(ds);
+    }
+}
diff --git a/lib/java/se/lth/control/labcomm/TypeDefParser.java b/lib/java/se/lth/control/labcomm/TypeDefParser.java
index a72e96510e6ee1544f42aa39c548b637172c1cbd..773ba32431a0c406229889e57436f8f1a869987e 100644
--- a/lib/java/se/lth/control/labcomm/TypeDefParser.java
+++ b/lib/java/se/lth/control/labcomm/TypeDefParser.java
@@ -420,6 +420,10 @@ public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
            return false;
        }
 
+        Iterator<ParsedTypeDef> getDepIterator() {
+           throw new Error("ParseTypeDef has no dependencies"); 
+        }        
+
        void setType(ParsedType type) {
            this.type = type;
        }