diff --git a/siaras/ConfigGen.jrag b/siaras/ConfigGen.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..d3414836aaf30d3ff140e7d8dc71e881bf2d7577
--- /dev/null
+++ b/siaras/ConfigGen.jrag
@@ -0,0 +1,83 @@
+/* -*-Java-*- */
+
+/* 
+ * Copyright (C) 2007  Anders Nilsson <anders.nilsson@cs.lth.se>
+ *
+ * This file is part of SkillServer.
+ */
+
+import java.util.*;
+
+aspect ConfigGen {
+    /********************************
+     * String genConfig()
+     ********************************/
+    syn String Device.genConfig() = "No configuration for type: "+
+        getClass().getName()+"\n";
+     eq Controller.genConfig() {
+         if (id().contains("ABB")) {
+             StringBuffer s = new StringBuffer();
+             s.append("EIO:CFG_1.0:4:0::\n");
+             s.append("#\n");
+             s.append("EIO_BUS_USER:\n");            
+             s.append("      -Name \"SIM\" -Driver \"/sim1:\"\n");
+             s.append("      -Name \"SW\" -Driver \"/sw1:\"\n");
+             s.append("      -Name \"BASE\" -Driver \"/BASE1:\"\n");
+             s.append("#\n");
+             s.append("EIO_UNIT:\n");
+             s.append("      -Name \"BOARD1\" -Type \"eip000\" -Bus \"SIM\" -Address \"6\" -Digin 16 -Digout 16\n");
+             s.append("      -Name \"BOARDSIM\" -Type \"eip000\" -Bus \"SIM\" -Address \"1\" -Digin 16 -Digout 16\n");
+//              System.out.println("devices: "+getNumDevice());
+             for (int i=0; i<getNumDevice(); i++) {
+                 Device d = (Device) getDevice(i);
+//                  System.out.println("Subdevice: "+d.id());
+                 if (d instanceof IO_Board) {
+                     s.append("      -Name ");
+                     s.append("\""+d.id()+"\" ");
+                     s.append("-Type ");
+                     s.append("\""+d.id()+"\" ");
+                     s.append("-Bus \"BASE\" ");
+                     System.out.println(d.getNumProperty());
+                     d.dumpTree("",System.out);
+                     for (int j=0; j<d.getNumProperty(); j++) {
+                         System.out.println(d.getProperty(j).decl().name());
+                         if (d.getProperty(j).decl() instanceof Signal) {
+                             Signal sig = (Signal) d.getProperty(j).decl();
+                             if (sig instanceof DigIn) {
+                                 s.append(" -Digin ");
+                             } else if (sig instanceof DigOut) {
+                                 s.append(" -DigOut ");
+                             } else {
+                                 s.append(" Unknown_Signal ");
+                             }
+                             s.append(sig.getValue());
+                         }
+                     }
+                     s.append("\n");
+//                      s.append("-Digin 16 -Digout 16\n");
+                     
+                 }
+             }
+             s.append("#\n");
+             s.append("EIO_SAFETY_SIGNAL = EIO_SIGNAL:\n");
+             s.append("      -Name \"BatAlarm\" -Type \"DO\" -Unit \"BOARD1\" -Phsig 3 -Store\n");
+             s.append("      -Name \"Charge\" -Type \"DO\" -Unit \"BOARD1\" -Phsig 1 -Store\n");
+             s.append("      -Name \"Discharge\" -Type \"DO\" -Unit \"BOARD1\" -Phsig 2 -Store\n");
+             s.append("#\n");
+             s.append("EIO_USER_SIGNAL = EIO_SIGNAL:\n");
+             s.append("      -Name \"Batlow\" -Type \"DI\" -Unit \"BOARD1\" -Phsig 5\n");
+             s.append("      -Name \"Batmeasure\" -Type \"DO\" -Unit \"BOARD1\" -Phsig 4 -Store\n");
+             s.append("      -Name \"Batreset\" -Type \"DO\" -Unit \"BOARDSIM\" -Phsig 9\n");
+             s.append("      -Name \"toollock\" -Type \"DO\" -Unit \"dig328\" -Phsig 1\n");
+             s.append("      -Name \"drillfeed\" -Type \"DO\" -Unit \"dig328\" -Phsig 2\n");
+             s.append("      -Name \"drillstop\" -Type \"DO\" -Unit \"dig328\" -Phsig 3\n");
+             s.append("      -Name \"drillstart\" -Type \"DO\" -Unit \"dig328\" -Phsig 6\n");
+             s.append("#\n");
+             s.append("EIO_GROUP_PHS = EIO_SIGNAL:\n");
+             s.append("      -Name \"Batresult\" -Type \"GO\" -Unit \"BOARDSIM\" -Phsig 1 -Length 8 -Store\n");
+             return s.toString();
+         } else {
+             return "No configuration support for controller: "+id();
+         }
+     }     
+}
diff --git a/siaras/Ontology.java b/siaras/Ontology.java
index 7ecad7b4181bbe16cec42e917f594aa0d5e8692e..dce031b209157ad7daeb1573de4f170eb6933ad3 100644
--- a/siaras/Ontology.java
+++ b/siaras/Ontology.java
@@ -29,6 +29,7 @@ public class Ontology extends Parser {
 			SiarasParser parser = new SiarasParser(r);
 
 			ast = parser.Start();
+            ast.traverseAST();
 		} catch (ParseException e) {
 			System.out.println(e.getMessage());
 		}
@@ -60,6 +61,6 @@ public class Ontology extends Parser {
 
     public static void main(String[] args) {
         Start ast = getAST(args[0]);
-        ast.getIndividual("CLOOS_R350").dumpTree("",System.out);
+        ast.getIndividual("ABB_IRB-140").dumpTree("",System.out);
     }
 }
diff --git a/siaras/Rewrites.jrag b/siaras/Rewrites.jrag
index f9160eae69fe2e8fc281c273cefb383318707ab8..e230d80af3b551ccf2ae2ffa0096849004a13985 100644
--- a/siaras/Rewrites.jrag
+++ b/siaras/Rewrites.jrag
@@ -64,3 +64,30 @@ aspect Qualification {
         }
     }
 }
+
+aspect Property {
+    syn boolean Device.hasElement(String name) {
+        for (int i=0; i<getNumElement(); i++) {
+            if (((ComplexElement) getElement(i)).name().equals(name)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    rewrite Device {
+        when (hasElement("hasProperty")) to Device {
+            List remainList = new List();
+            for (int i=0; i<getNumElement(); i++) {
+                ComplexElement e = (ComplexElement) getElement(i);
+                if (e.name().equals("hasProperty")) {
+                    addProperty((Thing) e);
+                } else {
+                    remainList.add(e);
+                }
+            }
+            setElementList(remainList);
+            return this;
+        }
+    }
+}
diff --git a/siaras/SkillserverInterface.jrag b/siaras/SkillserverInterface.jrag
index af9607713bbaaa059b9ecf59660ac3b96258a2b4..3189e6c1164bf627a76d85d9434acf46f4588cbe 100644
--- a/siaras/SkillserverInterface.jrag
+++ b/siaras/SkillserverInterface.jrag
@@ -3,19 +3,43 @@
 /* 
  * Copyright (C) 2007  Anders Nilsson <anders.nilsson@cs.lth.se>
  *
- * This file is part of OntologyCompiler.
+ * This file is part of SkillServer.
  */
 
+import java.util.*;
+
 aspect SkillserverInterface {
+    /********************************
+     * isConfigurable()
+     ********************************/
+    syn boolean Thing.isConfigurable() = false;
+    eq Controller.isConfigurable() = true;
+    // We should probably look for properties instead. AndersN 070612
+
+    /********************************
+     * getIndividual(String id)
+     ********************************/
     public Thing Start.getIndividual(String id) {
 //         System.out.println("getIndividual: "+id);
-        return super.getIndividual(id);
+        for (int i=0; i<getNumElement(); i++) {
+            Thing t = getElement(i).getIndividual(id);
+            if (t!=null) {
+//                 System.out.println("Found: "+t);
+                return t;
+            }
+        }
+        return null;
+//         return super.getIndividual(id);
+    }
+
+    public Thing Element.getIndividual(String id) {
+        return null;
     }
 
-    public Thing ASTNode.getIndividual(String id) {
+    public Thing ComplexElement.getIndividual(String id) {
 //         System.out.println("foo: "+this);
-        for (int i=0; i<getNumChild(); i++) {
-            Thing t = getChild(i).getIndividual(id);
+        for (int i=0; i<getNumElement(); i++) {
+            Thing t = getElement(i).getIndividual(id);
             if (t!=null) {
 //                 System.out.println("Found: "+t);
                 return t;
@@ -25,49 +49,201 @@ aspect SkillserverInterface {
     }
 
     public Thing Thing.getIndividual(String id) {
-//         System.out.println("Looking for: "+id+" in: "+id());
+//         System.out.println("  "+name());
+//         System.out.println("Looking for: "+id+" in: "+id()+" ("+name()+")");
 //         System.out.println("Looking in: "+id());
-        if (id().contains(id)) {
+//         if (id().contains(id) && 
+//             (this instanceof Device)) {
+        if (id.equals(id())) {
             return this;
         } else {
             return super.getIndividual(id);
         }
     }
 
+    public Thing ClassUse.getIndividual(String id) {
+        return null;
+    }
+
+    /********************************
+     * getOWLNamedClass(String skill)
+     ********************************/
+    public Thing Start.getOWLNamedClass(String skill) {
+        System.out.println("Looking for OWL class: "+skill);
+        return super.getOWLNamedClass(skill);
+    }
+
+    public Thing ASTNode.getOWLNamedClass(String skill) {
+        for (int i=0; i<getNumChild(); i++) {
+            Thing t = getChild(i).getOWLNamedClass(skill);
+            if (t!=null) {
+//                 System.out.println("Found: "+t);
+                return t;
+            }
+        }
+        return null;        
+    }
+
+    public Thing Thing.getOWLNamedClass(String skill) {
+        if (id().contains(skill)) {
+            return this;
+        } else {
+            return super.getOWLNamedClass(skill);
+        }
+    }
+
+    /********************************
+     * getPropertyValues(String name)
+     ********************************/
+    public Collection Thing.getPropertyValues(String name) {
+//         System.out.println("Looking for property: "+name+" in "+id());
+        LinkedList l = new LinkedList();
+        for (int i=0; i<getNumElement(); i++) {
+            if (getElement(i) instanceof ClassUse) {
+                ClassUse c = (ClassUse) getElement(i);
+                if (c.name().equals(name)) {
+                    l.add(c.decl());
+                }
+            }
+        }
+//         System.out.println(name()+" "+id()+" has the following "+name+" properties:");
+//         Iterator iter = l.iterator();
+//         while (iter.hasNext()) {
+//             System.out.println("  "+((Thing) iter.next()).name());
+//         }
+        return l;
+    }
+
+    /********************************
+     * Thing Thing.getDirectType()
+     ********************************/
+    public Thing Thing.getDirectType() {
+        return this;
+    }
+
+    /********************************
+     * boolean Device.canDo(String skill)
+     ********************************/
+    public boolean Device.canDo(String skill) {
+        try {
+            Class skillClass = Class.forName("AST."+skill);
+            Iterator i = getPropertyValues("hasSkill").iterator();
+            while (i.hasNext()) {
+                if (skillClass.isAssignableFrom(i.next().getClass())) {
+                    return true;
+                }
+            }
+        } catch (ClassNotFoundException e) {
+            System.out.println("Skill class not found: "+skill);
+        }
+        return false;
+    }
+
 
+    /********************************
+     * boolean Skill.canBeDoneBy(Skill skill)
+     ********************************/
+    public boolean Skill.canBeDoneBy(Skill skill) {
+//         System.out.println(name()+" canBeDoneBy "+skill.name()+" => "+
+//                            getClass().isAssignableFrom(skill.getClass()));
+        return getClass().isAssignableFrom(skill.getClass());
+    }
+
+    public boolean ClassUse.canBeDoneBy(Skill skill) {
+//         System.out.println(decl().name()+" canBeDoneBy "+skill.name()+" => "+
+//                            ((Skill) decl()).canBeDoneBy(skill));
+        return ((Skill) decl()).canBeDoneBy(skill);
+    }
+
+    /********************************
+     * String Thing.getName()
+     ********************************/
+    public String Thing.getName() {
+        return name();
+    }
+
+    public String ClassUse.getName() {
+        return decl().name();
+    }
+
+    /********************************
+     * String Thing.getValue()
+     ********************************/
+    public String ComplexElement.getValue() {
+        return "no_value";
+    }
+
+    public String ClassUse.getValue() {
+        return decl().getValue();
+    }
+
+    public String Property.getValue() {
+        for (int i=0; i<getNumElement(); i++) {
+            ComplexElement e = (ComplexElement) getElement(i);
+            if (e instanceof ValueElement) {
+                return e.getValue();
+            }
+        }
+        return "no_value";
+    }
+
+    public String ValueElement.getValue() {
+        return ((SimpleElement) getElement(0)).getValue();
+    }
+
+    public String SimpleElement.getValue() {
+        return "no_value";
+    }
+
+    public String StringElement.getValue() {
+        return getLITERAL();
+    }
+
+    public String FloatElement.getValue() {
+        return getLITERAL();
+    }
+
+    public String IntElement.getValue() {
+        return getLITERAL();
+    }
+
+    /********************************
+     * boolean Device.instanceOf(String klass)
+     ********************************/
+    public boolean Device.instanceOf(String klass) {
+        try {
+            return Class.forName("AST."+klass).isAssignableFrom(getClass());
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
 }
 
 aspect Misc {
     public String Thing.id() {
-        if (getNumAttribute() > 0) {
-            return getAttribute(0).name();
-        } else {
-            return "unknown_id";
-        }
-//         for (int i=0; i<getNumElement(); i++) {
-// //             System.out.println("  Checking "+getElement(i));
-//             if (getElement(i).isIdentifier()) {
-// //                 System.out.println("    Found identifier: "+((ComplexElement) getElement(i)).name());
-//                 Identifier ident = (Identifier) ((ClassUse) getElement(i)).decl();
+//         if (getNumAttribute() > 0) {
+//             return getAttribute(0).name();
+//         } else {
+//             return "unknown_id";
+//         }
+        for (int i=0; i<getNumElement(); i++) {
+//             System.out.println("  Checking "+getElement(i));
+            if (getElement(i).isIdentifier()) {
+//                 System.out.println("    Found identifier: "+((ComplexElement) getElement(i)).getAttribute(0).name());
+                Identifier ident = (Identifier) ((ClassUse) getElement(i)).decl();
 //                 System.out.println("    "+((ComplexElement) ident.getElement(0)).name());
 //                 return ident.value();
-//             }
-//         }
-//         return "unknown_id";
+                return ident.getValue();
+            }
+        }
+        return "unknown_id";
     }
 
     syn boolean Element.isIdentifier() = false;
     eq ComplexElement.isIdentifier() = name().equals("hasIdentifier"); // Ugly hack!
     eq Identifier.isIdentifier() = true;
-//     eq ClassUse.isIdentifier() {
-//         Thing decl = decl();
-//         if (decl != null) {
-//             return decl.isIdentifier();
-//         } else {
-//             System.out.println("Couldn't find decl for: "+name());
-//         }
-//         return false;
-//     }
+//     eq ClassUse.isIdentifier() = decl().isIdentifier();
 
     syn lazy String Identifier.value() {
         for (int i=0; i<getNumElement(); i++) {
@@ -82,9 +258,10 @@ aspect Misc {
 
 
 aspect Decl {
-    syn lazy Thing ClassUse.decl() {
+    syn lazy Thing Thing.decl() = null;
+    eq ClassUse.decl() {
         String id = getAttribute(0).getValue().getSTRING_LITERAL();
-        System.out.println("Find decl for: "+id);
+//         System.out.println("Find decl for: "+id);
         return rootNode().findDecl(id);
     }
 
@@ -119,7 +296,7 @@ aspect Decl {
     eq Thing.findDecl(String id) {
         for (int i=0; i<getNumAttribute(); i++) {
             if (getAttribute(i).isEqualId(id)) {
-                System.out.println("      Found it: "+name());
+//                 System.out.println("      Found it: "+name());
                 return this;
             }
         }
@@ -130,9 +307,17 @@ aspect Decl {
     eq RdfId.isEqualId(String id) {
 //         System.out.println("  Checking: "+name());
         if (name().equals(id)) {
-            System.out.println("    "+name()+" == "+id);
+//             System.out.println("    "+name()+" == "+id);
             return true;
         }
         return false;
     }
 }
+
+aspect PhonyTraversal {
+    public void ASTNode.traverseAST() {
+        for (int i=0; i<getNumChild(); i++) {
+            getChild(i).traverseAST();
+        }
+    }
+}