diff --git a/examples/omwg/total-owlable.xml b/examples/omwg/total-owlable.xml
new file mode 100644
index 0000000000000000000000000000000000000000..03b5d116e6a59157cd0f05432bde4fbfdba4cbef
--- /dev/null
+++ b/examples/omwg/total-owlable.xml
@@ -0,0 +1,463 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!DOCTYPE rdf:RDF [
+<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">
+<!ENTITY wine "http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#">
+<!ENTITY vin "http://ontology.deri.org/vin#">
+<!ENTITY proton "http://proton.semanticweb.org/">
+]>
+
+<!-- JE2010: With the "#" in the end, this is parsed (by the RDF parser...)
+    without it, this is not! -->
+<rdf:RDF xmlns="http://knowledgeweb.semanticweb.org/heterogeneity/alignment#" 
+	 xml:base="http://oms.omwg.org/wine-vin/"
+         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+	 xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
+         xmlns:align="http://knowledgeweb.semanticweb.org/heterogeneity/alignment#"
+	 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
+	 xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ex="http://example.org"
+	 xmlns:wine="http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#"
+	 xmlns:vin="http://ontology.deri.org/vin#"
+	 xmlns:proton="http://proton.semanticweb.org/"
+         xmlns:edoal="http://ns.inria.org/edoal/1.0/#">
+  
+  <Alignment rdf:about="http://oms.omwg.org/wine-vin/"> 
+    <xml>yes</xml>
+    <dc:creator>http://www.scharffe.fr/foaf.rdf</dc:creator>
+    <dc:date>2010/10/10</dc:date>
+    <method>manual</method>
+    <purpose>example</purpose>
+    <rdf:comment>This is a transformation of total.xml which can be transformed in OWL</rdf:comment>
+    <level>2EDOAL</level>
+    <type>**</type>    
+    <onto1>
+      <Ontology rdf:about="&wine;">
+      <formalism>
+	<Formalism>
+	 <uri>http://www.w3.org/TR/owl-guide/</uri>
+	 <name>owl</name>
+	</Formalism>
+      </formalism>
+      </Ontology>
+    </onto1> 
+    <onto2>
+      <Ontology rdf:about="&vin;">
+      <location>http://www.scharffe.fr/ontologies/OntologieDuVin.wsml</location>
+      <formalism>
+	<Formalism align:uri="http://www.wsmo.org/wsml/wsml-syntax/wsml-dl"
+		   align:name="wsml" />
+      </formalism>
+      </Ontology>
+    </onto2>
+
+    <!-- Class basis -->
+    <map>
+      <Cell rdf:about="MappingRule_class_basis">
+	<entity1><edoal:Class rdf:about="&wine;VintageYear"/></entity1>
+        <entity2><edoal:Class rdf:about="&vin;Millesime"/></entity2>
+        <measure rdf:datatype="&xsd;float">1.0</measure>
+        <relation>Equivalence</relation>
+      </Cell>
+    </map>
+    <!-- class const: and or not -->
+    <map>
+      <Cell rdf:about="MappingRule_class_const">
+	<entity1>
+	  <edoal:Class>
+	    <edoal:not>
+	      <edoal:Class>
+		<edoal:and rdf:parseType="Collection">
+		  <edoal:Class>
+		    <edoal:or rdf:parseType="Collection">
+		      <edoal:Class>
+			<edoal:and rdf:parseType="Collection">
+			  <edoal:Class rdf:about="&wine;Bordeaux1"/>
+			  <edoal:Class rdf:about="&wine;Bordeaux2"/>
+			</edoal:and>
+		      </edoal:Class>
+		      <edoal:Class>
+			<edoal:not>
+			  <edoal:Class rdf:about="&wine;Bordeaux3"/>
+			</edoal:not>
+		      </edoal:Class>
+		    </edoal:or>
+		  </edoal:Class>
+		  <edoal:Class>
+		    <edoal:not>
+		      <edoal:Class rdf:about="&wine;Bordeaux4"/>
+		    </edoal:not>
+		  </edoal:Class>
+		</edoal:and>
+	      </edoal:Class>
+	    </edoal:not>
+	  </edoal:Class>
+	</entity1>
+	<entity2> 
+	  <edoal:Class>
+	    <edoal:and rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&vin;Vin"/>
+	      <edoal:Class>
+		<edoal:or rdf:parseType="Collection">
+		  <edoal:Class>
+		    <edoal:not>
+		      <edoal:Class rdf:about="&vin;Bordeaux5"/>
+		    </edoal:not>
+		  </edoal:Class>
+		  <edoal:Class rdf:about="&vin;Bordeaux6"/>
+		</edoal:or>
+	      </edoal:Class>
+	      <edoal:Class>
+		<edoal:and rdf:parseType="Collection">
+		  <edoal:Class>
+		    <edoal:not>
+		      <edoal:Class rdf:about="&vin;Bordeaux7"/>
+		    </edoal:not>
+		  </edoal:Class>
+		  <edoal:Class rdf:about="&vin;Bordeaux7"/>
+		</edoal:and>
+	      </edoal:Class>
+	    </edoal:and>
+	  </edoal:Class>
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map>
+    <!-- class rest: att-type... -->
+    <map>
+      <Cell rdf:about="MappingRule_class_rest">
+	<entity1>
+	  <edoal:Class>
+	    <edoal:or rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&wine;Vin"/>
+	      <edoal:AttributeDomainRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation rdf:about="&proton;locatedIn"/>
+		</edoal:onAttribute>
+  		<edoal:class><edoal:Class rdf:about="&wine;FrenchRegion"/></edoal:class>
+	      </edoal:AttributeDomainRestriction>	  
+	      <edoal:AttributeTypeRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation rdf:about="&wine;hasTerroir"/>
+		</edoal:onAttribute>
+  		<edoal:datatype>An-integer-as-datatype</edoal:datatype>
+	      </edoal:AttributeTypeRestriction>	  
+	      <edoal:AttributeOccurenceRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation rdf:about="&wine;hasTerroir"/>
+		</edoal:onAttribute>
+		<edoal:comparator rdf:resource="&xsd;lower-than"/>
+  		<edoal:value>12</edoal:value>
+	      </edoal:AttributeOccurenceRestriction>	  
+	      <edoal:Class rdf:about="&wine;Bordeaux7"/>
+	    </edoal:or>
+	  </edoal:Class>
+	</entity1>
+	<entity2> 
+	  <edoal:Class>
+	    <edoal:and rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&vin;Vin"/>
+	      <edoal:AttributeValueRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation rdf:about="&vin;hasTerroir"/>
+		</edoal:onAttribute>
+		<edoal:comparator rdf:resource="&xsd;equals"/>
+  		<edoal:value><edoal:Instance rdf:about="&vin;Aquitaine"/></edoal:value>
+	      </edoal:AttributeValueRestriction>	  
+	      <edoal:AttributeOccurenceRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation rdf:about="&proton;locatedIn"/>
+		</edoal:onAttribute>
+		<edoal:comparator rdf:resource="&xsd;greater-than"/>
+  		<edoal:value>4</edoal:value>
+	      </edoal:AttributeOccurenceRestriction>	  
+	    </edoal:and>
+	  </edoal:Class>
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map>
+    <!-- test the quantifiers -->
+    <map>
+      <Cell rdf:about="MappingRule_class_quant">
+	<entity1>
+	  <edoal:Class>
+	    <edoal:or rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&wine;Vin"/>
+	      <edoal:AttributeDomainRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation rdf:about="&wine;hasTerroir"/>
+		</edoal:onAttribute>
+  		<edoal:all><edoal:Class rdf:about="&wine;FrenchRegion"/></edoal:all>
+	      </edoal:AttributeDomainRestriction>	  
+	    </edoal:or>
+	  </edoal:Class>
+	</entity1>
+	<entity2> 
+	  <edoal:Class>
+	    <edoal:and rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&vin;Vin"/>
+	      <edoal:AttributeDomainRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation rdf:about="&vin;hasTerroir"/>
+		</edoal:onAttribute>
+  		<edoal:exists><edoal:Class rdf:about="&wine;FrenchRegion"/></edoal:exists>
+	      </edoal:AttributeDomainRestriction>	  
+	    </edoal:and>
+	  </edoal:Class>
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map>
+    <!-- a bit more test on values -->
+    <map>
+      <Cell rdf:about="MappingRule_class_values">
+	<entity1>
+	  <edoal:Class>
+	    <edoal:or rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&wine;Vin"/>
+	      <edoal:AttributeValueRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation rdf:about="&wine;hasTerroir"/>
+		</edoal:onAttribute>
+		<edoal:comparator rdf:resource="&xsd;equals"/>
+  		<edoal:value><edoal:Instance rdf:about="&wine;Bordelais"/></edoal:value>
+	      </edoal:AttributeValueRestriction>	  
+	      <edoal:Class rdf:about="&wine;Bordeaux7"/>
+	    </edoal:or>
+	  </edoal:Class>
+	</entity1>
+	<entity2> 
+	  <edoal:Class>
+	    <edoal:and rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&vin;Vin"/>
+	      <edoal:AttributeValueRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation rdf:about="&wine;hasTerroir"/>
+		</edoal:onAttribute>
+		<edoal:comparator rdf:resource="&xsd;equals"/>
+  		<edoal:value><edoal:Literal edoal:string="33"/></edoal:value>
+	      </edoal:AttributeValueRestriction>	  
+	    </edoal:and>
+	  </edoal:Class>
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map>
+    <!-- class const and rest -->
+    <!-- rel basis -->
+    <map>
+      <Cell rdf:about="MappingRule_rel_basis">
+	<entity1><edoal:Relation rdf:about="&wine;locatedIn"/></entity1>
+        <entity2><edoal:Relation rdf:about="&vin;hasTerroir"/></entity2>
+        <measure rdf:datatype="&xsd;float">1.0</measure>
+        <relation>SubsumedBy</relation>
+      </Cell>
+    </map>
+    <!-- rel const: and or not compose inverse trans refl sym -->
+    <map>
+      <Cell rdf:about="MappingRule_rel_const">
+	<entity1>
+	  <edoal:Relation>
+	    <edoal:inverse>
+	      <edoal:Relation rdf:about="&wine;loc4"/>
+	    </edoal:inverse>
+	  </edoal:Relation>
+	</entity1>
+	<entity2> 
+	  <edoal:Relation rdf:about="&vin;place3"/>
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map>
+    <!-- rel rest: att-type... -->
+    <map>
+      <Cell rdf:about="MappingRule_rel_rest">
+	<entity1>
+	  <edoal:RelationDomainRestriction> 
+  	    <edoal:class><edoal:Class rdf:about="&wine;Bordeaux1"/></edoal:class>
+	  </edoal:RelationDomainRestriction>	  
+	</entity1>
+	<entity2> 
+	  <edoal:RelationDomainRestriction> 
+  	    <edoal:class>
+	      <edoal:Class>
+		<edoal:and rdf:parseType="Collection">
+		  <edoal:Class rdf:about="&vin;Bordeaux5"/>
+		  <edoal:Class rdf:about="&vin;Bordeaux6"/>
+		</edoal:and>
+	      </edoal:Class>
+            </edoal:class>
+	  </edoal:RelationDomainRestriction>	  
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map>
+    <!-- rel const and rest -->
+    <!-- prop basis -->
+    <map>
+      <Cell rdf:about="MappingRule_prop_basis">
+        <entity1><edoal:Property rdf:about="&wine;yearValue"/></entity1>
+        <entity2><edoal:Property rdf:about="&vin;anneeMillesime"/></entity2>
+        <measure rdf:datatype="&xsd;float">1.0</measure>
+        <relation>Equivalence</relation>
+      </Cell>
+    </map>
+    <!-- prop const: and or not compose -->
+    <map>
+      <Cell rdf:about="MappingRule_prop_const">
+	<entity1>
+	  <edoal:Property rdf:about="&wine;number1"/>
+	</entity1>
+	<entity2> 
+	  <edoal:Property rdf:about="&vin;dpt3"/>
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map>
+    <!-- prop rest: att-type... -->
+    <map>
+      <Cell rdf:about="MappingRule_prop_rest">
+	<entity1>
+	  <edoal:PropertyValueRestriction> 
+	    <edoal:comparator rdf:resource="http://www.w3.org/2001/XMLSchema#equals"/>
+  	    <edoal:value><edoal:Literal edoal:string="Bordeaux"/></edoal:value>
+	  </edoal:PropertyValueRestriction>
+	</entity1>
+	<entity2> 
+	  <edoal:PropertyDomainRestriction> 
+  	    <edoal:class>
+	      <edoal:Class>
+		<edoal:and rdf:parseType="Collection">
+		  <edoal:Class rdf:about="&vin;Bordeaux5"/>
+		  <edoal:Class rdf:about="&vin;Bordeaux6"/>
+		</edoal:and>
+	      </edoal:Class>
+            </edoal:class>
+	  </edoal:PropertyDomainRestriction>	  
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map>
+    <!-- prop const and rest -->
+    <!-- instance -->
+    <map>
+      <Cell rdf:about="MappingRule_inst_basis">
+	<entity1><edoal:Instance rdf:about="&wine;ChateauMargaux1995"/></entity1>
+        <entity2><edoal:Instance rdf:about="&vin;MoutonRotschild1889"/></entity2>
+        <measure rdf:datatype="&xsd;float">1.0</measure>
+        <relation>Equivalence</relation>
+      </Cell>
+    </map>
+    <!-- Miscelaneous -->
+    <map>
+      <Cell rdf:about="MappingRule_3">
+	<entity1>
+	  <edoal:Class>
+	    <edoal:and rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&wine;Bordeaux17"/>
+	      <edoal:Class>
+		<edoal:or rdf:parseType="Collection">
+		  <edoal:Class rdf:about="&wine;Bordeaux18"/>
+		  <edoal:Class rdf:about="&wine;Bordeaux18"/>
+		</edoal:or>
+	      </edoal:Class>
+	    </edoal:and>
+	  </edoal:Class>
+	</entity1>
+	<entity2> 
+	  <edoal:Class rdf:about="&vin;Vin"/>
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map>
+    <map>
+      <Cell rdf:about="MappingRule_4">
+	<entity1>
+ 	  <edoal:Class>
+	    <edoal:or rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&vin;Acidite"/>
+	      <edoal:Class rdf:about="&vin;Astreingence"/>
+	      <edoal:Class rdf:about="&vin;Amertume"/>
+            </edoal:or>
+    	  </edoal:Class>
+	</entity1>
+	<entity2>
+          <edoal:Class>
+            <edoal:not>
+              <edoal:Class rdf:about="&vin;WineFlavor"/>
+	    </edoal:not>
+	  </edoal:Class>
+	</entity2>
+        <measure rdf:datatype='&xsd;float'>1.</measure>
+        <relation>SubsumedBy</relation>
+      </Cell>
+    </map>
+    <!-- The transformation will be ignored by OWL -->
+    <map>
+      <Cell rdf:about="TransformationTest">
+	<entity1>
+	  <edoal:Property rdf:about="foaf:name"/>
+	</entity1>
+	<entity2>
+	  <edoal:Relation rdf:about="vcard:name"/>
+	</entity2>
+        <measure rdf:datatype='&xsd;float'>1.</measure>
+        <relation>SubsumedBy</relation>
+	<edoal:transformation>
+	  <edoal:Transformation edoal:type="o-">
+	    <edoal:entity1>
+	      <edoal:Property><edoal:compose rdf:parseType="Collection"/></edoal:Property>
+	    </edoal:entity1>
+	    <edoal:entity2>
+	      <edoal:Apply edoal:operator="concat">
+		<edoal:arguments rdf:parseType="Collection">
+		  <edoal:Property rdf:about="vcard:firstname"/>
+		  <edoal:Literal edoal:string=" "/>
+		  <!-- or even compute middle initial from middlename -->
+		  <edoal:Property rdf:about="vcard:middleinitial"/>
+		  <edoal:Literal edoal:string=". "/>
+		  <edoal:Property rdf:about="vcard:lastname"/>
+		</edoal:arguments>
+	      </edoal:Apply>
+	    </edoal:entity2>
+	  </edoal:Transformation>
+	</edoal:transformation>
+      </Cell>
+    </map>
+<!-- TOCHECK DOES NOT WORK BECAUSE OF OUT TOP/BOTTOM -->
+    <map>
+      <Cell rdf:about="ExtremeTransformationTest">
+	<entity1>
+	  <edoal:Class>
+	    <edoal:or />
+	  </edoal:Class>
+	</entity1>
+	<entity2>
+	  <edoal:Class>
+	    <edoal:and />
+	  </edoal:Class>
+	</entity2>
+        <measure rdf:datatype='&xsd;float'>1.</measure>
+        <relation>SubsumedBy</relation>
+	<edoal:transformation>
+	  <edoal:Transformation edoal:type="o-">
+	    <edoal:entity1>
+	      <edoal:Relation><edoal:compose /></edoal:Relation>
+	    </edoal:entity1>
+	    <edoal:entity2>
+	      <edoal:Relation><edoal:compose /></edoal:Relation>
+	    </edoal:entity2>
+	  </edoal:Transformation>
+	</edoal:transformation>
+      </Cell>
+    </map>
+  </Alignment>
+</rdf:RDF>
diff --git a/examples/omwg/total.xml b/examples/omwg/total.xml
index 6f484f370acb06ce6a366cb5fdb3e698460f604e..8f4de9f460847337a6629dd7754d0495a1fa1255 100644
--- a/examples/omwg/total.xml
+++ b/examples/omwg/total.xml
@@ -158,7 +158,7 @@
 		    </edoal:or>
 		  </edoal:Relation>
 		</edoal:onAttribute>
-		<edoal:comparator rdf:resource="&xsd;less-than"/>
+		<edoal:comparator rdf:resource="&xsd;lower-than"/>
   		<edoal:value>12</edoal:value>
 	      </edoal:AttributeOccurenceRestriction>	  
 	      <edoal:Class rdf:about="&wine;Bordeaux7"/>
@@ -234,7 +234,6 @@
 		    </edoal:compose>
 		  </edoal:Relation>
 		</edoal:onAttribute>
-		<edoal:comparator rdf:resource="&xsd;equals"/>
   		<edoal:exists><edoal:Class rdf:about="&wine;FrenchRegion"/></edoal:exists>
 	      </edoal:AttributeDomainRestriction>	  
 	    </edoal:and>
@@ -627,12 +626,14 @@
     </map>
     <!-- prop const and rest -->
     <!-- instance -->
+    <!-- This equivalence does not means anything.
+	 It was a subsumption which was not better -->
     <map>
       <Cell rdf:about="MappingRule_inst_basis">
 	<entity1><edoal:Instance rdf:about="&wine;ChateauMargaux1995"/></entity1>
         <entity2><edoal:Instance rdf:about="&vin;MoutonRotschild1889"/></entity2>
         <measure rdf:datatype="&xsd;float">1.0</measure>
-        <relation>SubsumedBy</relation>
+        <relation>Equivalence</relation>
       </Cell>
     </map>
     <!-- Miscelaneous -->
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java b/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java
index 745a4062e713ce5964056c60b99a7b55e345c44c..38651cb74b438e2cba24111c9950f95d54ad7d07 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java
@@ -35,6 +35,16 @@ public class Comparator {
     public static Comparator LOWER = initComparator( Namespace.XSD.prefix+"lower-than", -1 );
     public static Comparator GREATER = initComparator( Namespace.XSD.prefix+"greater-than", 1 );
 
+    public static Comparator getComparator( URI u ) {
+	if ( u.equals( EQUAL.getURI() ) ) {
+	    return EQUAL;
+	} else if ( u.equals( LOWER.getURI() ) ) {
+	    return LOWER;
+	} else if ( u.equals( GREATER.getURI() ) ) {
+	    return GREATER;
+	} else return new Comparator( u );
+    }
+
     protected Comparator() {
 	super();
     }
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java b/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java
index 0c577757ab63b82a46776f879c6593bac65d9c42..f34ca819238ef54cb99a77cb3dfec444de9c61dd 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java
@@ -22,6 +22,10 @@
 
 package fr.inrialpes.exmo.align.impl.edoal;
 
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.AlignmentVisitor;
+import org.semanticweb.owl.align.Visitable;
+
 /**
  * <p>
  * Id to represent a datatype
@@ -31,11 +35,15 @@ package fr.inrialpes.exmo.align.impl.edoal;
  * </p>
  */
 
-public class Datatype { //implements Cloneable, Visitable {
+public class Datatype implements Visitable { //implements Cloneable
 
     /** Holds the type */
     private String type;
 
+    public void accept( AlignmentVisitor visitor) throws AlignmentException {
+        visitor.visit( this );
+    }
+
     /**
      * Constructs an object with the given type.
      * 
@@ -53,10 +61,6 @@ public class Datatype { //implements Cloneable, Visitable {
 	this.type = type;
     }
 
-    //    public void accept(AlignmentVisitor visitor) throws AlignmentException {
-    //	visitor.visit(this);
-    //    }
-
     public String plainText() {
 	return type;
     }
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java
index 1bfe4006949fb17e1ae76218cd55b2ac104eb570..02042218d51c80b856a36cda8752820723085333 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java
@@ -34,6 +34,9 @@ import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.Cell;
 import org.semanticweb.owl.align.Relation;
 
+import fr.inrialpes.exmo.align.impl.Annotations;
+import fr.inrialpes.exmo.align.impl.Namespace;
+import fr.inrialpes.exmo.align.impl.Extensions;
 import fr.inrialpes.exmo.align.impl.ObjectAlignment;
 import fr.inrialpes.exmo.align.impl.BasicRelation;
 import fr.inrialpes.exmo.align.impl.rel.*;
@@ -41,6 +44,46 @@ import fr.inrialpes.exmo.align.impl.rel.*;
 import fr.inrialpes.exmo.ontowrap.LoadedOntology;
 import fr.inrialpes.exmo.ontowrap.OntowrapException;
 
+import fr.inrialpes.exmo.align.parser.SyntaxElement;
+import fr.inrialpes.exmo.align.parser.SyntaxElement.Constructor;
+
+import fr.inrialpes.exmo.align.impl.edoal.Id;
+import fr.inrialpes.exmo.align.impl.edoal.PathExpression;
+import fr.inrialpes.exmo.align.impl.edoal.Expression;
+import fr.inrialpes.exmo.align.impl.edoal.ClassExpression;
+import fr.inrialpes.exmo.align.impl.edoal.ClassId;
+import fr.inrialpes.exmo.align.impl.edoal.ClassConstruction;
+import fr.inrialpes.exmo.align.impl.edoal.ClassRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.ClassTypeRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.ClassDomainRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.ClassValueRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.ClassOccurenceRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.PropertyExpression;
+import fr.inrialpes.exmo.align.impl.edoal.PropertyId;
+import fr.inrialpes.exmo.align.impl.edoal.PropertyConstruction;
+import fr.inrialpes.exmo.align.impl.edoal.PropertyRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.PropertyDomainRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.PropertyTypeRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.PropertyValueRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.RelationExpression;
+import fr.inrialpes.exmo.align.impl.edoal.RelationId;
+import fr.inrialpes.exmo.align.impl.edoal.RelationConstruction;
+import fr.inrialpes.exmo.align.impl.edoal.RelationRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.RelationDomainRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.RelationCoDomainRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.InstanceExpression;
+import fr.inrialpes.exmo.align.impl.edoal.InstanceId;
+
+import fr.inrialpes.exmo.align.impl.edoal.Transformation;
+import fr.inrialpes.exmo.align.impl.edoal.ValueExpression;
+import fr.inrialpes.exmo.align.impl.edoal.Value;
+import fr.inrialpes.exmo.align.impl.edoal.Apply;
+import fr.inrialpes.exmo.align.impl.edoal.Datatype;
+import fr.inrialpes.exmo.align.impl.edoal.Comparator;
+import fr.inrialpes.exmo.align.impl.edoal.EDOALRelation;
+import fr.inrialpes.exmo.align.impl.edoal.EDOALCell;
+import fr.inrialpes.exmo.align.impl.edoal.EDOALAlignment;
+
 /**
  * Renders an alignment as a new ontology merging these.
  *
@@ -48,16 +91,19 @@ import fr.inrialpes.exmo.ontowrap.OntowrapException;
  * @version $Id$ 
  */
 
-public class OWLAxiomsRendererVisitor implements AlignmentVisitor {
+public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements AlignmentVisitor {
     boolean heterogeneous = false;
-    PrintWriter writer = null;
+    boolean edoal = false;
     Alignment alignment = null;
     LoadedOntology onto1 = null;
     LoadedOntology onto2 = null;
     Cell cell = null;
+    Relation toProcess = null;
 
+    private static Namespace DEF = Namespace.ALIGNMENT;
+    
     public OWLAxiomsRendererVisitor( PrintWriter writer ){
-	this.writer = writer;
+	super( writer );
     }
 
     public void init( Properties p ) {
@@ -65,197 +111,840 @@ public class OWLAxiomsRendererVisitor implements AlignmentVisitor {
     };
 
     public void visit( Visitable o ) throws AlignmentException {
-	if ( o instanceof Alignment ) visit( (Alignment)o );
+	if ( o instanceof Expression ) visit( (Expression)o );
+	else if ( o instanceof ValueExpression ) visit( (ValueExpression)o );
+	else if ( o instanceof Transformation ) visit( (Transformation)o );
 	else if ( o instanceof Cell ) visit( (Cell)o );
 	else if ( o instanceof Relation ) visit( (Relation)o );
+	else if ( o instanceof Alignment ) visit( (Alignment)o );
+	else throw new AlignmentException( "Cannot dispatch Expression "+o );
     }
 
     public void visit( Alignment align ) throws AlignmentException {
-	if ( !( align instanceof ObjectAlignment ))  {
-	    throw new AlignmentException("OWLAxiomsRenderer: cannot render simple alignment. Turn them into ObjectAlignment, by toObjectAlignement()");
-	}
 	alignment = align;
 	if ( align instanceof ObjectAlignment ){
 	    onto1 = (LoadedOntology)((ObjectAlignment)alignment).getOntologyObject1();
 	    onto2 = (LoadedOntology)((ObjectAlignment)alignment).getOntologyObject2();
+	} else if ( align instanceof EDOALAlignment ) {
+	    edoal = true;
+	} else {
+	    throw new AlignmentException("OWLAxiomsRenderer: cannot render simple alignment. Turn them into ObjectAlignment, by toObjectAlignement() or use EDOALAlignment");
 	}
-	writer.print("<rdf:RDF\n");
-	writer.print("    xmlns:owl=\"http://www.w3.org/2002/07/owl#\"\n");
-	writer.print("    xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n");
-	writer.print("    xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\" \n");
-	writer.print("    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema#\">\n\n");	
-	writer.print("  <owl:Ontology rdf:about=\"\">\n");
-	writer.print("    <rdfs:comment>Matched ontologies</rdfs:comment>\n");
-	writer.print("    <rdfs:comment>Generated by fr.inrialpes.exmo.align.renderer.OWLAxiomsRendererVisitor</rdfs:comment>\n");
+	writer.print("<rdf:RDF"+NL);
+	writer.print("    xmlns:owl=\"http://www.w3.org/2002/07/owl#\""+NL);
+	writer.print("    xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""+NL);
+	writer.print("    xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\" "+NL);
+	writer.print("    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema#\">"+NL+NL);	
+	writer.print("  <owl:Ontology rdf:about=\"\">"+NL);
+	writer.print("    <rdfs:comment>Matched ontologies</rdfs:comment>"+NL);
+	writer.print("    <rdfs:comment>Generated by fr.inrialpes.exmo.align.renderer.OWLAxiomsRendererVisitor</rdfs:comment>"+NL);
 	for ( String[] ext : align.getExtensions() ){
-	    writer.print("    <rdfs:comment>"+ext[1]+": "+ext[2]+"</rdfs:comment>\n");
+	    writer.print("    <rdfs:comment>"+ext[1]+": "+ext[2]+"</rdfs:comment>"+NL);
 	}
-	writer.print("    <owl:imports rdf:resource=\""+align.getOntology1URI().toString()+"\"/>\n");
-	writer.print("    <owl:imports rdf:resource=\""+align.getOntology2URI().toString()+"\"/>\n");
-	writer.print("  </owl:Ontology>\n\n");
+	writer.print("    <owl:imports rdf:resource=\""+align.getOntology1URI().toString()+"\"/>"+NL);
+	writer.print("    <owl:imports rdf:resource=\""+align.getOntology2URI().toString()+"\"/>"+NL);
+	writer.print("  </owl:Ontology>"+NL+NL);
 	
 	try {
 	    for( Cell c : align ){
 		Object ob1 = c.getObject1();
 		Object ob2 = c.getObject2();
 		
-		if ( heterogeneous ||
+		if ( heterogeneous || edoal ||
 		     ( onto1.isClass( ob1 ) && onto2.isClass( ob2 ) ) ||
 		     ( onto1.isDataProperty( ob1 ) && onto2.isDataProperty( ob2 ) ) ||
 		     ( onto1.isObjectProperty( ob1 ) && onto2.isObjectProperty( ob2 ) ) ||
-		     ( onto1.isIndividual( ob1 ) && onto2.isIndividual( ob2 ) ) )
+		     ( onto1.isIndividual( ob1 ) && onto2.isIndividual( ob2 ) ) ) {
 		    c.accept( this );
-		
+		}
 	    } //end for
 	} catch ( OntowrapException owex ) {
 	    throw new AlignmentException( "Error accessing ontology", owex );
 	}
 
-	writer.print("</rdf:RDF>\n");
+	writer.print("</rdf:RDF>"+NL);
     }
 
     public void visit( Cell cell ) throws AlignmentException {
-	this.cell = cell;
-	Object ob1 = cell.getObject1();
-	Object ob2 = cell.getObject2();
-	URI u1;
-	try {
-	    if ( cell.getRelation() instanceof SubsumedRelation ){
-		u1 = onto2.getEntityURI( cell.getObject2() );
-	    } else {
-		u1 = onto1.getEntityURI( ob1 );
-	    }
-	    if ( onto1.isClass( ob1 ) ) {
-		writer.print("  <owl:Class rdf:about=\""+u1+"\">\n");
-		cell.getRelation().accept( this );
-		writer.print("  </owl:Class>\n");
-	    } else if ( onto1.isDataProperty( ob1 ) ) {
-		writer.print("  <owl:DatatypeProperty rdf:about=\""+u1+"\">\n");
-		cell.getRelation().accept( this );
-		writer.print("  </owl:DatatypeProperty>\n");
-	    } else if ( onto1.isObjectProperty( ob1 ) ) {
-		writer.print("  <owl:ObjectProperty rdf:about=\""+u1+"\">\n");
-		cell.getRelation().accept( this );
-		writer.print("  </owl:ObjectProperty>\n");
-	    } else if ( onto1.isIndividual( ob1 ) ) {
-		writer.print("  <owl:Thing rdf:about=\""+u1+"\">\n");
-		cell.getRelation().accept( this );
-		writer.print("  </owl:Thing>\n");
+	if ( cell.getId() != null ) writer.print(NL+NL+"<!-- "+cell.getId()+" -->"+NL);
+	if ( cell instanceof EDOALCell ) {
+	    visit( (EDOALCell)cell );
+	} else {
+	    this.cell = cell;
+	    Object ob1 = cell.getObject1();
+	    Object ob2 = cell.getObject2();
+	    URI u1;
+	    try {
+		if ( cell.getRelation() instanceof SubsumedRelation ){
+		    u1 = onto2.getEntityURI( cell.getObject2() );
+		} else {
+		    u1 = onto1.getEntityURI( ob1 );
+		}
+		if ( ob1 instanceof ClassExpression || onto1.isClass( ob1 ) ) {
+		    writer.print("  <owl:Class rdf:about=\""+u1+"\">"+NL);
+		    cell.getRelation().accept( this );
+		    writer.print("  </owl:Class>"+NL);
+		} else if ( ob1 instanceof PropertyExpression || onto1.isDataProperty( ob1 ) ) {
+		    writer.print("  <owl:DatatypeProperty rdf:about=\""+u1+"\">"+NL);
+		    cell.getRelation().accept( this );
+		    writer.print("  </owl:DatatypeProperty>"+NL);
+		} else if ( ob1 instanceof RelationExpression || onto1.isObjectProperty( ob1 ) ) {
+		    writer.print("  <owl:ObjectProperty rdf:about=\""+u1+"\">"+NL);
+		    cell.getRelation().accept( this );
+		    writer.print("  </owl:ObjectProperty>"+NL);
+		} else if ( ob1 instanceof InstanceExpression || onto1.isIndividual( ob1 ) ) {
+		    writer.print("  <owl:Thing rdf:about=\""+u1+"\">"+NL);
+		    cell.getRelation().accept( this );
+		    writer.print("  </owl:Thing>"+NL);
+		}
+	    } catch ( OntowrapException owex ) {
+		throw new AlignmentException( "Error accessing ontology", owex );
 	    }
-	} catch ( OntowrapException owex ) {
-	    throw new AlignmentException( "Error accessing ontology", owex );
 	}
     }
 
+    public String getRelationName( LoadedOntology onto, Object ob, Relation rel ) {
+	try {
+	    if ( rel instanceof EquivRelation ) {
+		if ( onto.isClass( ob ) ) {
+		    return "owl:equivalentClass";
+		} else if ( onto.isProperty( ob ) ) {
+		    return "owl:equivalentProperty";
+		} else if ( onto.isIndividual( ob ) ) {
+		    return "owl:sameAs";
+		}
+	    } else if ( rel instanceof SubsumeRelation ) {
+		if ( onto.isClass( ob ) ) {
+		    return "rdfs:subClassOf";
+		} else if ( onto.isProperty( ob ) ) {
+		    return "rdfs:subPropertyOf";
+		}
+	    } else if ( rel instanceof SubsumedRelation ) {
+		if ( onto.isClass( ob ) ) {
+		    return "rdfs:subClassOf";
+		} else if ( onto.isProperty( ob ) ) {
+		    return "rdfs:subPropertyOf";
+		}
+	    } else if ( rel instanceof IncompatRelation ) {
+		if ( onto.isClass( ob ) ) {
+		    return "rdfs:disjointFrom";
+		} else if ( onto.isIndividual( ob ) ) {
+		    return "owl:differentFrom";
+		}
+	    }
+	} catch ( OntowrapException owex ) {}; // return null anyway
+	return null;
+    }
+
     public void visit( EquivRelation rel ) throws AlignmentException {
 	Object ob2 = cell.getObject2();
-	URI u2;
-	try {
-	    u2 = onto2.getEntityURI( ob2 );
-	    if ( onto2.isClass( ob2 ) ) {
-		writer.print("    <owl:equivalentClass rdf:resource=\""+u2+"\"/>\n");
-	    } else if ( onto2.isDataProperty( ob2 ) ) {
-		writer.print("    <owl:equivalentProperty rdf:resource=\""+u2+"\"/>\n");
-	    } else if ( onto2.isObjectProperty( ob2 ) ) {
-		writer.print("    <owl:equivalentProperty rdf:resource=\""+u2+"\"/>\n");
-	    } else if ( onto2.isIndividual( ob2 ) ) {
-		writer.print("    <owl:sameAs rdf:resource=\""+u2+"\"/>\n");
+	String owlrel = getRelationName( onto2, ob2, rel );
+	if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel );
+	if ( !edoal ) {
+	    try {
+		writer.print("    <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL);
+	    } catch ( OntowrapException owex ) {
+		throw new AlignmentException( "Error accessing ontology", owex );
+	    }
+	} else {
+	    if ( ob2 instanceof InstanceId ) {
+		writer.print("    <"+owlrel+" rdf:resource=\""+((InstanceId)ob2).getURI()+"\"/>"+NL);
+	    } else {
+		writer.println("    <"+owlrel+">");
+		((Expression)ob2).accept( this );
+		writer.println("    </"+owlrel+">");
 	    }
-	} catch ( OntowrapException owex ) {
-	    throw new AlignmentException( "Error accessing ontology", owex );
 	}
     }
 
     public void visit( SubsumeRelation rel ) throws AlignmentException {
 	Object ob2 = cell.getObject2();
-	URI u2;
+	String owlrel = getRelationName( onto2, ob2, rel );
+	if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel );
+	if ( !edoal ) {
 	try {
-	    u2 = onto2.getEntityURI( ob2 );
-	    if ( onto1.isClass( ob2 ) ) {
-		writer.print("    <rdfs:subClassOf rdf:resource=\""+u2+"\"/>\n");
-	    } else if ( onto1.isDataProperty( ob2 ) ) {
-		writer.print("    <rdfs:subPropertyOf rdf:resource=\""+u2+"\"/>\n");
-	    } else if ( onto1.isObjectProperty( ob2 ) ) {
-		writer.print("    <rdfs:subPropertyOf rdf:resource=\""+u2+"\"/>\n");
-	    }
+	    writer.print("    <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL);
 	} catch ( OntowrapException owex ) {
 	    throw new AlignmentException( "Error accessing ontology", owex );
 	}
+	} else {
+	    writer.println("    <"+owlrel+">");
+	    ((Expression)ob2).accept( this );
+	    writer.println("    </"+owlrel+">");
+	}
     }
 
     public void visit( SubsumedRelation rel ) throws AlignmentException {
 	Object ob1 = cell.getObject1();
-	URI u1;
+	String owlrel = getRelationName( onto1, ob1, rel );
+	if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel );
+	if ( !edoal ) {
 	try {
-	    u1 = onto1.getEntityURI( ob1 );
-	    if ( onto1.isClass( ob1 ) ) {
-		writer.print("    <rdfs:subClassOf rdf:resource=\""+u1+"\"/>\n");
-	    } else if ( onto1.isDataProperty( ob1 ) ) {
-		writer.print("    <rdfs:subPropertyOf rdf:resource=\""+u1+"\"/>\n");
-	    } else if ( onto1.isObjectProperty( ob1 ) ) {
-		writer.print("    <rdfs:subPropertyOf rdf:resource=\""+u1+"\"/>\n");
-	    }
+	    writer.print("    <"+owlrel+" rdf:resource=\""+onto1.getEntityURI( ob1 )+"\"/>"+NL);
 	} catch ( OntowrapException owex ) {
 	    throw new AlignmentException( "Error accessing ontology", owex );
 	}
+	} else {
+	    writer.println("    <"+owlrel+">");
+	    ((Expression)ob1).accept( this );
+	    writer.println("    </"+owlrel+">");
+	}
     }
 
     public void visit( IncompatRelation rel ) throws AlignmentException {
 	Object ob2 = cell.getObject2();
-	URI u2;
+	String owlrel = getRelationName( onto2, ob2, rel );
+	if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel );
+	if ( !edoal ) {
 	try {
-	    u2 = onto2.getEntityURI( ob2 );
+	    writer.print("    <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL);
 	} catch ( OntowrapException owex ) {
 	    throw new AlignmentException( "Cannot find entity URI", owex );
 	}
-	writer.print("    <owl:disjointWith rdf:resource=\""+u2+"\"/>\n");
+	} else {
+	    writer.println("    <"+owlrel+">");
+	    ((Expression)ob2).accept( this );
+	    writer.println("    </"+owlrel+">");
+	}
     }
 
     public void visit( Relation rel ) throws AlignmentException {
-	// JE: I do not understand why I need this,
-	// but this seems to be the case...
-	try {
-	    Method mm = null;
-	    if ( Class.forName("fr.inrialpes.exmo.align.impl.rel.EquivRelation").isInstance(rel) ){
-		mm = this.getClass().getMethod("visit",
-					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.EquivRelation")});
-	    } else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumeRelation").isInstance(rel) ) {
-		mm = this.getClass().getMethod("visit",
-					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumeRelation")});
-	    } else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumedRelation").isInstance(rel) ) {
-		mm = this.getClass().getMethod("visit",
-					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumedRelation")});
-	    } else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.IncompatRelation").isInstance(rel) ) {
-		mm = this.getClass().getMethod("visit",
-					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.IncompatRelation")});
-	    }
-	    if ( mm != null ) mm.invoke(this,new Object[] {rel});
-	    else {
-		if ( Class.forName("fr.inrialpes.exmo.align.impl.BasicRelation").isInstance(rel) ){
-		    Object ob2 = cell.getObject2();
-		    URI u2;
-		    try {
-			u2 = onto2.getEntityURI( ob2 );
-			if ( onto2.isIndividual( ob2 ) ) { // ob1 has been checked before
-			    // It would be better to check that r is a relation of one of the ontologies by
-			    // onto1.isObjectProperty( onto1.getEntity( new URI ( r ) ) )
-			    String r = ((BasicRelation)rel).getRelation();
-			    if ( r!=null && !r.equals("") )
-				writer.print("    <"+r+" rdf:resource=\""+u2+"\"/>\n");
+	if ( rel instanceof EDOALRelation ) visit( (EDOALRelation)rel );
+	else {
+	    // JE: I do not understand why I need this,
+	    // but this seems to be the case...
+	    try {
+		Method mm = null;
+		if ( Class.forName("fr.inrialpes.exmo.align.impl.rel.EquivRelation").isInstance(rel) ){
+		    mm = this.getClass().getMethod("visit",
+						   new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.EquivRelation")});
+		} else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumeRelation").isInstance(rel) ) {
+		    mm = this.getClass().getMethod("visit",
+						   new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumeRelation")});
+		} else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumedRelation").isInstance(rel) ) {
+		    mm = this.getClass().getMethod("visit",
+						   new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumedRelation")});
+		} else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.IncompatRelation").isInstance(rel) ) {
+		    mm = this.getClass().getMethod("visit",
+						   new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.IncompatRelation")});
+		}
+		if ( mm != null ) mm.invoke(this,new Object[] {rel});
+		else {
+		    if ( Class.forName("fr.inrialpes.exmo.align.impl.BasicRelation").isInstance(rel) ){
+			try {
+			    // This is only for individuals
+			    Object ob2 = cell.getObject2();
+			    if ( onto2.isIndividual( ob2 ) ) { 
+				// ob1 has been checked before
+				// It would be better to check that r is a relation of one of the ontologies by
+				// onto1.isObjectProperty( onto1.getEntity( new URI ( r ) ) )
+				String r = ((BasicRelation)rel).getRelation();
+				if ( r!=null && !r.equals("") ) {
+				    URI u2 = onto2.getEntityURI( ob2 );
+				    writer.print("    <"+r+" rdf:resource=\""+u2+"\"/>"+NL);
+				}
+			    }
+			} catch ( OntowrapException owex ) {
+			    throw new AlignmentException( "Error accessing ontology", owex );
 			}
-		    } catch ( OntowrapException owex ) {
-			throw new AlignmentException( "Error accessing ontology", owex );
 		    }
 		}
+	    } catch (IllegalAccessException e) {
+		e.printStackTrace();
+	    } catch (ClassNotFoundException e) {
+		e.printStackTrace();
+	    } catch (NoSuchMethodException e) {
+		e.printStackTrace();
+	    } catch (InvocationTargetException e) { 
+		e.printStackTrace();
 	    }
-	} catch (IllegalAccessException e) {
-	    e.printStackTrace();
-	} catch (ClassNotFoundException e) {
-	    e.printStackTrace();
-	} catch (NoSuchMethodException e) {
-	    e.printStackTrace();
-	} catch (InvocationTargetException e) { 
-	    e.printStackTrace();
 	}
     };
+
+    public void visit( EDOALCell cell ) throws AlignmentException {
+	this.cell = cell;
+	toProcess = cell.getRelation();
+	if ( ((EDOALRelation)toProcess).getDirection() != EDOALRelation.Direction.SUBSUMES
+	     && ((EDOALRelation)toProcess).getDirection() != EDOALRelation.Direction.HASINSTANCE ) {
+	    ((Expression)cell.getObject1()).accept( this );
+	} else {
+	    ((Expression)cell.getObject2()).accept( this );
+	}
+	writer.print(NL);
+    }
+
+    /**
+     * The current implementation is not satisfying:
+     * EDOALRelation is deconnected from Relation (for historical purposes)
+     * This is left this way because the complete relations should be reengineered
+     */
+    public void visit( EDOALRelation o ) throws AlignmentException {
+	String relName;
+	boolean reversed = false;
+	Object ob2 = cell.getObject2();
+	if ( o.getDirection() == EDOALRelation.Direction.EQUIVALENCE ) {
+	    if ( ob2 instanceof ClassExpression ) {
+		relName = "owl:equivalentClass";
+	    } else if ( ob2 instanceof PropertyExpression || ob2 instanceof RelationExpression ) {
+		relName = "owl:equivalentProperty";
+	    } else if ( ob2 instanceof InstanceExpression ) {
+		relName = "owl:sameAs";
+	    } else throw new AlignmentException( "Equivalence relation cannot apply to "+o );
+	} else if (  o.getDirection() == EDOALRelation.Direction.DISJOINTFROM ) {
+	    if ( ob2 instanceof ClassExpression ) {
+		relName = "owl:disjointFrom";
+	    } else if ( ob2 instanceof InstanceExpression ) {
+		relName = "owl:differentFrom";
+	    } else throw new AlignmentException( "Disjointness relation cannot apply to "+o );
+	} else if (  o.getDirection() == EDOALRelation.Direction.SUBSUMES ) {
+	    reversed = true;
+	    if ( ob2 instanceof ClassExpression ) {
+		relName = "owl:subClassOf";
+	    } else if ( ob2 instanceof PropertyExpression || ob2 instanceof RelationExpression ) {
+		relName = "owl:subPropertyOf";
+	    } else throw new AlignmentException( "Subsumption relation cannot apply to "+o );
+	} else if (  o.getDirection() == EDOALRelation.Direction.SUBSUMEDBY ) {
+	    if ( ob2 instanceof ClassExpression ) {
+		relName = "owl:subClassOf";
+	    } else if ( ob2 instanceof PropertyExpression || ob2 instanceof RelationExpression ) {
+		relName = "owl:subPropertyOf";
+	    } else throw new AlignmentException( "Subsumption relation cannot apply to "+o );
+	} else if (  o.getDirection() == EDOALRelation.Direction.INSTANCEOF ) {
+	    relName = "rdf:type";
+	} else if (  o.getDirection() == EDOALRelation.Direction.HASINSTANCE ) {
+	    reversed = true;
+	    relName = "rdf:type";
+	} else {
+	    throw new AlignmentException( "Cannot deal with relation "+o );
+	}
+	writer.print("  <"+relName+">"+NL);
+	increaseIndent();
+	if ( reversed ) {
+	    ((Expression)cell.getObject1()).accept( this );
+	} else {
+	    ((Expression)ob2).accept( this );
+	}
+	decreaseIndent();
+	writer.print(NL+"  </"+relName+">");
+    }
+
+    // ******* EDOAL
+
+    public void visit( Expression o ) throws AlignmentException {
+	if ( o instanceof ClassExpression ) visit( (ClassExpression)o );
+	else if ( o instanceof RelationRestriction ) visit( (RelationRestriction)o );
+	else if ( o instanceof PropertyRestriction ) visit( (PropertyRestriction)o );
+	else if ( o instanceof ClassRestriction ) visit( (ClassRestriction)o );
+	else if ( o instanceof PathExpression ) visit( (PathExpression)o );
+	else if ( o instanceof PropertyExpression ) visit( (PropertyExpression)o );
+	else if ( o instanceof InstanceExpression ) visit( (InstanceExpression)o );
+	else if ( o instanceof RelationExpression ) visit( (RelationExpression)o );
+	else throw new AlignmentException( "Cannot dispatch Expression "+o );
+    }
+
+    public void visit( final PathExpression p ) throws AlignmentException {
+	if ( p instanceof RelationExpression ) visit( (RelationExpression)p );
+	else if ( p instanceof PropertyExpression ) visit( (PropertyExpression)p );
+	else throw new AlignmentException( "Cannot dispatch PathExpression "+p );
+    }
+
+    public void visit( final ClassExpression e ) throws AlignmentException {
+	if ( e instanceof ClassId ) visit( (ClassId)e );
+	else if ( e instanceof ClassConstruction )  visit( (ClassConstruction)e );
+	else if ( e instanceof ClassRestriction )  visit( (ClassRestriction)e );
+	else throw new AlignmentException( "Cannot dispatch ClassExpression "+e );
+    }
+
+    public void visit( final ClassId e ) throws AlignmentException {
+	if ( toProcess == null ) {
+	    indentedOutput("<owl:Class "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\"/>");
+	} else {
+	    Relation toProcessNext = toProcess;
+	    toProcess = null;
+	    indentedOutput("<owl:Class "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\">"+NL);
+	    increaseIndent();
+	    toProcessNext.accept( this );
+	    writer.print(NL);
+	    decreaseIndent();
+	    indentedOutput("</owl:Class>");
+	}
+    }
+
+    public void visit( final ClassConstruction e ) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	final Constructor op = e.getOperator();
+	String owlop = null;
+	// Very special treatment
+	if ( toProcessNext != null && e.getComponents().size() == 0 ) {
+	    if ( op == Constructor.AND ) owlop = "http://www.w3.org/2002/07/owl#Thing";
+	    else if ( op == Constructor.OR ) owlop = "http://www.w3.org/2002/07/owl#Nothing";
+	    else if ( op == Constructor.NOT ) throw new AlignmentException( "Complement constructor cannot be empty");
+	    indentedOutput("<owl:Class "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+owlop+"\">"+NL);
+	    increaseIndent();
+	    toProcessNext.accept( this ); 
+	    writer.print(NL);
+	    decreaseIndent();
+	    indentedOutput("</owl:Class>");
+	} else {
+	    if ( op == Constructor.AND ) owlop = "intersectionOf";
+	    else if ( op == Constructor.OR ) owlop = "unionOf";
+	    else if ( op == Constructor.NOT ) owlop = "complementOf";
+	    else throw new AlignmentException( "Unknown class constructor : "+op );
+	    if ( e.getComponents().size() == 0 ) {
+		if ( op == Constructor.AND ) indentedOutput("<owl:Thing/>");
+		else if ( op == Constructor.OR ) indentedOutput("<owl:Nothing/>");
+		else throw new AlignmentException( "Complement constructor cannot be empty");
+	    } else {
+		indentedOutput("<owl:Class>"+NL);
+		increaseIndent();
+		indentedOutput("<owl:"+owlop);
+		if ( ( (op == Constructor.AND) || (op == Constructor.OR) ) ) 
+		    writer.print(" "+SyntaxElement.RDF_PARSETYPE.print(DEF)+"=\"Collection\"");
+		writer.print(">"+NL);
+		increaseIndent();
+		for (final ClassExpression ce : e.getComponents()) {
+		    writer.print(linePrefix);
+		    ce.accept( this );
+		    writer.print(NL);
+		}
+		decreaseIndent();
+		indentedOutput("</owl:"+owlop+">"+NL);
+		if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+		decreaseIndent();
+		indentedOutput("</owl:Class>");
+	    }
+	}
+    }
+
+    public void visit(final ClassRestriction e) throws AlignmentException {
+	if ( e instanceof ClassValueRestriction ) visit( (ClassValueRestriction)e );
+	else if ( e instanceof ClassTypeRestriction )  visit( (ClassTypeRestriction)e );
+	else if ( e instanceof ClassDomainRestriction )  visit( (ClassDomainRestriction)e );
+	else if ( e instanceof ClassOccurenceRestriction )  visit( (ClassOccurenceRestriction)e );
+	else throw new AlignmentException( "Cannot dispatch ClassExpression "+e );
+    }
+
+    public void visit( final ClassValueRestriction c ) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	indentedOutput("<owl:Restriction>"+NL);
+	increaseIndent();
+	indentedOutput("<owl:onProperty>"+NL);
+	increaseIndent();
+	c.getRestrictionPath().accept( this );
+	decreaseIndent();
+	writer.print(NL);
+	indentedOutputln("</owl:onProperty>");
+	ValueExpression ve = c.getValue();
+	if ( ve instanceof Value ) {
+	    indentedOutput("<owl:hasValue");
+	    if ( ((Value)ve).getType() != null ) {
+		writer.print( " rdf:datatype=\""+((Value)ve).getType()+"\"" );
+	    }
+	    writer.print( ">"+((Value)ve).getValue()+"</owl:hasValue>"+NL);
+	} else if ( ve instanceof InstanceId ) {
+	    indentedOutput("<owl:hasValue>"+NL);
+	    increaseIndent();
+	    ve.accept( this );
+	    decreaseIndent();
+	    writer.print(NL);
+	    indentedOutput("</owl:hasValue>"+NL);
+	} else throw new AlignmentException( "OWL does not support path constraints in hasValue : "+ve );
+	if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+	decreaseIndent();
+	indentedOutput("</owl:Restriction>");
+    }
+
+    public void visit( final ClassTypeRestriction c ) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	indentedOutput("<owl:Restriction>"+NL);
+	increaseIndent();
+	indentedOutput("<owl:onProperty>"+NL);
+	increaseIndent();
+	c.getRestrictionPath().accept( this );
+	writer.print(NL);
+	decreaseIndent();
+	indentedOutput("</owl:onProperty>"+NL);
+	indentedOutput("<owl:allValuesFrom>"+NL);
+	increaseIndent();
+	visit( c.getType() ); // JE2010 ??
+	writer.print(NL);
+	decreaseIndent();
+	indentedOutput("</owl:allValuesFrom>"+NL);
+	if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+	decreaseIndent();
+	indentedOutput("</owl:Restriction>");
+    }
+
+    public void visit( final ClassDomainRestriction c ) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	indentedOutput("<owl:Restriction>"+NL);
+	increaseIndent();
+	indentedOutput("<owl:onProperty>"+NL);
+	increaseIndent();
+	c.getRestrictionPath().accept( this );
+	writer.print(NL);
+	decreaseIndent();
+	indentedOutput("</owl:onProperty>"+NL);
+	if ( c.isUniversal() ) {
+	    indentedOutput("<owl:allValuesFrom>"+NL);
+	} else {
+	    indentedOutput("<owl:someValuesFrom>"+NL);
+	}
+	increaseIndent();
+	c.getDomain().accept( this );
+	writer.print(NL);
+	decreaseIndent();
+	if ( c.isUniversal() ) {
+	    indentedOutput("</owl:allValuesFrom>"+NL);
+	} else {
+	    indentedOutput("</owl:someValuesFrom>"+NL);
+	}
+	if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+	decreaseIndent();
+	indentedOutput("</owl:Restriction>");
+    }
+
+    // TOTEST
+    public void visit( final ClassOccurenceRestriction c ) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	indentedOutput("<owl:Restriction>"+NL);
+	increaseIndent();
+	indentedOutput("<owl:onProperty>"+NL);
+	increaseIndent();
+	c.getRestrictionPath().accept( this );
+	writer.print(NL);
+	decreaseIndent();
+	indentedOutput("</owl:onProperty>"+NL);
+	String cardinality = null;
+	Comparator comp = c.getComparator();
+	if ( comp == Comparator.EQUAL ) cardinality = "cardinality";
+	else if ( comp == Comparator.LOWER ) cardinality = "maxCardinality";
+	else if ( comp == Comparator.GREATER ) cardinality = "minCardinality";
+	else throw new AlignmentException( "Unknown comparator : "+comp.getURI() );
+	indentedOutput("<owl:"+cardinality+" rdf:datatype=\"&xsd;nonNegativeInteger\">");
+	writer.print(c.getOccurence());
+	writer.print("</owl:"+cardinality+">"+NL);
+	if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+	decreaseIndent();
+	indentedOutput("</owl:Restriction>");
+    }
+    
+    public void visit(final PropertyExpression e) throws AlignmentException {
+	if ( e instanceof PropertyId ) visit( (PropertyId)e );
+	else if ( e instanceof PropertyConstruction ) visit( (PropertyConstruction)e );
+	else if ( e instanceof PropertyRestriction ) visit( (PropertyRestriction)e );
+	else throw new AlignmentException( "Cannot dispatch ClassExpression "+e );
+    }
+	
+    public void visit(final PropertyId e) throws AlignmentException {
+	if ( toProcess == null ) {
+	    indentedOutput("<owl:DatatypeProperty "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\"/>");
+	} else {
+	    Relation toProcessNext = toProcess;
+	    toProcess = null;
+	    indentedOutput("<owl:DatatypeProperty "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\">"+NL);
+	    increaseIndent();
+	    toProcessNext.accept( this );
+	    writer.print(NL);
+	    decreaseIndent();
+	    indentedOutput("</owl:DatatypeProperty>");
+	}
+    }
+
+    /**
+     * OWL, and in particular OWL 2, does not allow for more Relation (ObjectProperty)
+     * and Property (DataProperty) constructor than owl:inverseOf
+     * It is thus imposible to transcribe our and, or and not constructors.
+     */
+    public void visit(final PropertyConstruction e) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	indentedOutput("<owl:DatatypePropety>"+NL);
+	increaseIndent();
+	final Constructor op = e.getOperator();
+	String owlop = null;
+	// JE: FOR TESTING
+	//owlop = "FORTESTING("+op.name()+")";
+	if ( owlop == null ) throw new AlignmentException( "Cannot translate property construction in OWL : "+op );
+	indentedOutput("<owl:"+owlop);
+	if ( (op == Constructor.AND) || (op == Constructor.OR) || (op == Constructor.COMP) ) writer.print(" "+SyntaxElement.RDF_PARSETYPE.print(DEF)+"=\"Collection\"");
+	writer.print(">"+NL);
+	increaseIndent();
+	if ( (op == Constructor.AND) || (op == Constructor.OR) || (op == Constructor.COMP) ) {
+	    for ( final PathExpression pe : e.getComponents() ) {
+		writer.print(linePrefix);
+		pe.accept( this );
+		writer.print(NL);
+	    }
+	} else {
+	    for (final PathExpression pe : e.getComponents()) {
+		pe.accept( this );
+		writer.print(NL);
+	    }
+	}
+	decreaseIndent();
+	indentedOutput("</owl:"+owlop+">"+NL);
+	if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+	decreaseIndent();
+	indentedOutput("</owl:DatatypePropety>");
+    }
+    
+    public void visit(final PropertyRestriction e) throws AlignmentException {
+	if ( e instanceof PropertyValueRestriction ) visit( (PropertyValueRestriction)e );
+	else if ( e instanceof PropertyDomainRestriction ) visit( (PropertyDomainRestriction)e );
+	else if ( e instanceof PropertyTypeRestriction ) visit( (PropertyTypeRestriction)e );
+	else throw new AlignmentException( "Cannot dispatch ClassExpression "+e );
+    }
+	
+    public void visit(final PropertyValueRestriction c) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	indentedOutput("<owl:DatatypeProperty>"+NL);
+	increaseIndent();
+	indentedOutput("<rdfs:range>"+NL);
+	increaseIndent();
+	indentedOutput("<rdfs:Datatype>"+NL);
+	increaseIndent();
+	indentedOutput("<owl:oneOf>"+NL);
+	increaseIndent();
+	// In EDOAL, this does only contain one value and is thus rendered as:
+	indentedOutput("<rdf:Description>"+NL);
+	increaseIndent();
+	ValueExpression ve = c.getValue();
+	if ( ve instanceof Value ) {
+	    indentedOutput("<rdf:first");
+	    if ( ((Value)ve).getType() != null ) {
+		writer.print( " rdf:datatype=\""+((Value)ve).getType()+"\"" );
+	    }
+	    writer.print( ">"+((Value)ve).getValue()+"</rdf:first>"+NL);
+	} else {
+	    indentedOutput("<rdf:first>"+NL);
+	    ve.accept( this );
+	    writer.print("</rdf:first>"+NL);
+	    indentedOutput("<rdf:rest rdf:resource=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#nil\"/>"+NL);
+	}
+	decreaseIndent();
+	indentedOutput("</rdf:Description>"+NL);
+	// This is incorrect for more than one value... see the OWL:
+	/*
+         <rdfs:Datatype>
+          <owl:oneOf>
+           <rdf:Description>
+            <rdf:first rdf:datatype="&xsd;integer">1</rdf:first>
+             <rdf:rest>
+              <rdf:Description>
+               <rdf:first rdf:datatype="&xsd;integer">2</rdf:first>
+               <rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
+              </rdf:Description>
+             </rdf:rest>
+            </rdf:Description>
+           </owl:oneOf>
+          </rdfs:Datatype>
+	*/
+	decreaseIndent();
+	indentedOutput("</owl:oneOf>"+NL);
+	decreaseIndent();
+	indentedOutput("</rdfs:Datatype>"+NL);
+	decreaseIndent();
+	indentedOutput("</rdfs:range>"+NL);
+	if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+	decreaseIndent();
+	indentedOutput("</owl:DatatypeProperty>");
+    }
+
+    public void visit(final PropertyDomainRestriction c) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	indentedOutput("<owl:DatatypeProperty>"+NL);
+	increaseIndent();
+	indentedOutput("<rdfs:domain>"+NL);
+	increaseIndent();
+	c.getDomain().accept( this );
+	writer.print(NL);
+	decreaseIndent();
+	indentedOutput("</rdfs:domain>"+NL);
+	if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+	decreaseIndent();
+	indentedOutput("</owl:DatatypeProperty>");
+    }
+
+    public void visit(final PropertyTypeRestriction c) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	indentedOutput("<owl:DatatypeProperty>"+NL);
+	increaseIndent();
+	indentedOutput("<rdfs:range>"+NL);
+	increaseIndent();
+	c.getType().accept( this );
+	decreaseIndent();
+	indentedOutput("</rdfs:range>"+NL);
+	if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+	decreaseIndent();
+	indentedOutput("</owl:DatatypeProperty>");
+    }
+    
+    public void visit( final RelationExpression e ) throws AlignmentException {
+	if ( e instanceof RelationId ) visit( (RelationId)e );
+	else if ( e instanceof RelationRestriction ) visit( (RelationRestriction)e );
+	else if ( e instanceof RelationConstruction ) visit( (RelationConstruction)e );
+	else throw new AlignmentException( "Cannot dispatch ClassExpression "+e );
+    }
+	
+    public void visit( final RelationId e ) throws AlignmentException {
+	if ( toProcess == null ) {
+	    indentedOutput("<owl:ObjectProperty "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\"/>");
+	} else {
+	    Relation toProcessNext = toProcess;
+	    toProcess = null;
+	    indentedOutput("<owl:ObjectProperty "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\">"+NL);
+	    increaseIndent();
+	    toProcessNext.accept( this );
+	    writer.print(NL);
+	    decreaseIndent();
+	    indentedOutput("</owl:ObjectProperty>");
+	}
+    }
+
+    /**
+     * OWL, and in particular OWL 2, does not allow for more Relation (ObjectProperty)
+     * and Property (DataProperty) constructor than owl:inverseOf
+     * It is thus imposible to transcribe our and, or and not constructors.
+     * Moreover, they have no constructor for the symmetric, transitive and reflexive
+     * closure and the compositional closure (or composition) can only be obtained by
+     * defining a property subsumed by this closure through an axiom.
+     * It is also possible to rewrite the reflexive closures as axioms as well.
+     * But the transitive closure can only be obtained through subsuption.
+     */
+    public void visit( final RelationConstruction e ) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	indentedOutput("<owl:ObjectProperty>"+NL);
+	increaseIndent();
+	final Constructor op = e.getOperator();
+	String owlop = null;
+	if ( op == Constructor.INVERSE ) owlop = "owl:inverseOf";
+	// JE: FOR TESTING
+	//owlop = "FORTESTING("+op.name()+")";
+	if ( owlop == null ) throw new AlignmentException( "Cannot translate relation construction in OWL : "+op );
+	indentedOutput("<owl:"+owlop);
+	if ( (op == Constructor.OR) || (op == Constructor.AND) || (op == Constructor.COMP) ) writer.print(" "+SyntaxElement.RDF_PARSETYPE.print(DEF)+"=\"Collection\"");
+	writer.print(">"+NL);
+	increaseIndent();
+	if ( (op == Constructor.AND) || (op == Constructor.OR) || (op == Constructor.COMP) ) {
+	    for (final PathExpression re : e.getComponents()) {
+		writer.print(linePrefix);
+		re.accept( this );
+		writer.print(NL);
+	    }
+	} else { // NOT... or else: enumerate them
+	    for (final PathExpression re : e.getComponents()) {
+		re.accept( this );
+		writer.print(NL);
+	    }
+	}
+	decreaseIndent();
+	indentedOutput("</owl:"+owlop+">"+NL);
+	if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+	decreaseIndent();
+	indentedOutput("</owl:ObjectProperty>");
+    }
+    
+    public void visit( final RelationRestriction e ) throws AlignmentException {
+	if ( e instanceof RelationCoDomainRestriction ) visit( (RelationCoDomainRestriction)e );
+	else if ( e instanceof RelationDomainRestriction ) visit( (RelationDomainRestriction)e );
+	else throw new AlignmentException( "Cannot dispatch ClassExpression "+e );
+    }
+	
+    public void visit(final RelationCoDomainRestriction c) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	indentedOutput("<owl:ObjectProperty>"+NL);
+	increaseIndent();
+	indentedOutput("<rdfs:range>"+NL);
+	increaseIndent();
+	c.getCoDomain().accept( this );
+	writer.print(NL);
+	decreaseIndent();
+	indentedOutput("</rdfs:range>"+NL);
+	if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+	decreaseIndent();
+	indentedOutput("</owl:ObjectProperty>");
+    }
+
+    public void visit(final RelationDomainRestriction c) throws AlignmentException {
+	Relation toProcessNext = toProcess;
+	toProcess = null;
+	indentedOutput("<owl:ObjectProperty>"+NL);
+	increaseIndent();
+	indentedOutput("<rdfs:domain>"+NL);
+	increaseIndent();
+	c.getDomain().accept( this );
+	writer.print(NL);
+	decreaseIndent();
+	indentedOutput("</rdfs:domain>"+NL);
+	if ( toProcessNext != null ) { toProcessNext.accept( this ); writer.print(NL); }
+	decreaseIndent();
+	indentedOutput("</owl:ObjectProperty>");
+    }
+    
+    public void visit( final InstanceExpression e ) throws AlignmentException {
+	if ( e instanceof InstanceId ) visit( (InstanceId)e );
+	else throw new AlignmentException( "Cannot handle InstanceExpression "+e );
+    }
+
+    public void visit( final InstanceId e ) throws AlignmentException {
+	if ( toProcess == null ) {
+	    indentedOutput("<owl:Individual "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\"/>");
+	} else {
+	    Relation toProcessNext = toProcess;
+	    toProcess = null;
+	    indentedOutput("<owl:Individual "+SyntaxElement.RDF_ABOUT.print(DEF)+"=\""+e.getURI()+"\">"+NL);
+	    increaseIndent();
+	    toProcessNext.accept( this );
+	    writer.print(NL);
+	    decreaseIndent();
+	    indentedOutput("</owl:Individual>");
+	}
+    }
+    
+    public void visit( final ValueExpression e ) throws AlignmentException {
+	if ( e instanceof InstanceExpression ) visit( (InstanceExpression)e );
+	else if ( e instanceof PathExpression )  visit( (PathExpression)e );
+	else if ( e instanceof Apply )  visit( (Apply)e );
+	else if ( e instanceof Value )  visit( (Value)e );
+	else throw new AlignmentException( "Cannot dispatch ClassExpression "+e );
+    }
+
+    // Unused: see ClassValueRestriction above
+    public void visit( final Value e ) throws AlignmentException {
+    }
+	
+    // OWL does not allow for function calls
+    public void visit( final Apply e ) throws AlignmentException {
+	throw new AlignmentException( "Cannot render function call in OWL "+e );
+    }
+
+    // Not implemented. We only ignore transformations in OWL
+    public void visit( final Transformation transf ) throws AlignmentException {
+    }
+
+    /**
+     * Our Datatypes are only strings identifying datatypes.
+     * For OWL, they should be considered as built-in types because we do 
+     * not know how to add other types.
+     * Hence we could simply have used a rdfs:Datatype="<name>"
+     *
+     * OWL offers further possiblities, such as additional owl:withRestriction
+     * clauses
+     */
+    public void visit( final Datatype e ) {
+	indentedOutput("<owl:Datatype><owl:onDataType rdf:resource=\""+e.plainText()+"\"/></owl:Datatype>");
+    }
+	
+
 }
diff --git a/src/fr/inrialpes/exmo/align/parser/RDFParser.java b/src/fr/inrialpes/exmo/align/parser/RDFParser.java
index 5f0dca797b338f20895a97778d2ad7ce4cf39807..3c940b76007e64d114749f7ebad89098b4e2efcf 100644
--- a/src/fr/inrialpes/exmo/align/parser/RDFParser.java
+++ b/src/fr/inrialpes/exmo/align/parser/RDFParser.java
@@ -553,7 +553,7 @@ public class RDFParser {
 		stmt = node.getProperty( (Property)SyntaxElement.COMPARATOR.resource );
 		if ( stmt == null ) throw new AlignmentException( "Required edoal:comparator property" );
 		URI id = getNodeId( stmt.getResource() );
-		if ( id != null ) comp = new Comparator( id );
+		if ( id != null ) comp = Comparator.getComparator( id );
 		else throw new AlignmentException("edoal:comparator requires an URI");
 		if ( rdfType.equals( SyntaxElement.OCCURENCE_COND.resource ) ) {
 		    stmt = node.getProperty( (Property)SyntaxElement.VALUE.resource );
@@ -681,7 +681,7 @@ public class RDFParser {
 	    if ( stmt == null ) throw new AlignmentException( "Required edoal:comparator property" );
 	    URI id = getNodeId( stmt.getResource() );
 	    if ( id == null ) throw new AlignmentException("edoal:comparator requires and URI");
-	    Comparator comp = new Comparator( id );
+	    Comparator comp = Comparator.getComparator( id );
 	    stmt = node.getProperty( (Property)SyntaxElement.VALUE.resource );
 	    if ( stmt == null ) throw new AlignmentException( "Required edoal:value property" );
 	    ValueExpression v = parseValue( stmt.getObject() );
diff --git a/test/src/EDOALExportTest.java b/test/src/EDOALExportTest.java
index a4f445b5630d7564320f90c1ba72309104b0754c..2640a478dc837c5756ca704006a014ca8baa62fd 100644
--- a/test/src/EDOALExportTest.java
+++ b/test/src/EDOALExportTest.java
@@ -35,9 +35,11 @@ import org.semanticweb.owl.align.Alignment;
 import org.semanticweb.owl.align.Visitable;
 
 import fr.inrialpes.exmo.align.impl.renderer.RDFRendererVisitor;
+import fr.inrialpes.exmo.align.impl.renderer.OWLAxiomsRendererVisitor;
 import fr.inrialpes.exmo.align.impl.Annotations;
 import fr.inrialpes.exmo.align.impl.Namespace;
 import fr.inrialpes.exmo.align.impl.edoal.EDOALAlignment;
+import fr.inrialpes.exmo.align.parser.AlignmentParser;
 import fr.inrialpes.exmo.ontowrap.Ontology;
 import fr.inrialpes.exmo.ontowrap.BasicOntology;
 
@@ -93,7 +95,6 @@ import fr.inrialpes.exmo.align.impl.edoal.Value;
 import fr.inrialpes.exmo.align.impl.edoal.Datatype;
 import fr.inrialpes.exmo.align.impl.edoal.Comparator;
 
-
 /**
  * These tests corresponds to the tests presented in the examples/omwg directory
  */
@@ -127,6 +128,50 @@ public class EDOALExportTest {
 	return stream.toString();
     }
 
+    // Load the full test ==> break because not all can be rendered
+    @Test(expectedExceptions = AlignmentException.class, groups = { "full", "omwg", "raw" }, dependsOnMethods = {"setUp"})
+    public void testOWLRendering0() throws Exception {
+	AlignmentParser aparser = new AlignmentParser( 0 );
+	aparser.initAlignment( null );
+	Alignment alignment = aparser.parse( "file:examples/omwg/total.xml" );
+	assertNotNull( alignment );
+	// Print it in a string
+	ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
+	PrintWriter writer = new PrintWriter (
+			  new BufferedWriter(
+			       new OutputStreamWriter( stream, "UTF-8" )), true);
+	AlignmentVisitor renderer = new OWLAxiomsRendererVisitor( writer );
+	alignment.render( renderer );
+    }
+
+    // Load the stripped down test ==> it loads
+    // This cannot be passed to an OWL parser because no typechecking has been done
+    // This is only a syntactic test
+    @Test(groups = { "full", "omwg", "raw" }, dependsOnMethods = {"testOWLRendering0"})
+    public void testOWLRendering1() throws Exception {
+	AlignmentParser aparser = new AlignmentParser( 0 );
+	aparser.initAlignment( null );
+	Alignment alignment = aparser.parse( "file:examples/omwg/total-owlable.xml" );
+	assertNotNull( alignment );
+	// Print it in a string
+	ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
+	PrintWriter writer = new PrintWriter (
+			  new BufferedWriter(
+			       new OutputStreamWriter( stream, "UTF-8" )), true);
+	/*
+	OutputStream stream = new FileOutputStream( "/tmp/total.owl" );
+	PrintWriter writer = new PrintWriter (
+			  new BufferedWriter(
+			       new OutputStreamWriter( stream, "UTF-8" )), true);
+	*/
+	AlignmentVisitor renderer = new OWLAxiomsRendererVisitor( writer );
+	alignment.render( renderer );
+	writer.flush();
+	writer.close();
+	String str1 = stream.toString();
+	assertEquals( str1.length(), 12099 );
+    }
+
     @Test(groups = { "full", "omwg", "raw" }, dependsOnMethods = {"setUp"})
     public void testExportPath() throws Exception {
 	/*
diff --git a/test/src/EDOALParserTest.java b/test/src/EDOALParserTest.java
index 30f1d75c0308b27e9e681004be941744ba9a8e61..6b6e2138c6f12f6a2d3b34d222f57b4234e82718 100644
--- a/test/src/EDOALParserTest.java
+++ b/test/src/EDOALParserTest.java
@@ -84,14 +84,15 @@ public class EDOALParserTest {
 	aparser1 = new AlignmentParser( 0 );
 	aparser1.initAlignment( null );
 	//System.err.println( str1 );
-	alignment = aparser1.parseString( str1 );
+	Alignment al = aparser1.parseString( str1 );
+	assertEquals( alignment.nbCells(), al.nbCells() );
 	// Print it in another string
 	stream = new ByteArrayOutputStream(); 
 	writer = new PrintWriter (
 			  new BufferedWriter(
 			       new OutputStreamWriter( stream, "UTF-8" )), true);
 	renderer = new RDFRendererVisitor( writer );
-	alignment.render( renderer );
+	al.render( renderer );
 	writer.flush();
 	writer.close();
 	String str2 = stream.toString();