diff --git a/src/fr/inrialpes/exmo/align/impl/BasicParameters.java b/src/fr/inrialpes/exmo/align/impl/BasicParameters.java
new file mode 100644
index 0000000000000000000000000000000000000000..5aafb7f63dbed9d15908ab0892d0cd3fe0deaa05
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/BasicParameters.java
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2004
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+package fr.inrialpes.exmo.align.impl; 
+
+// import java classes
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+import org.semanticweb.owl.align.Parameters;
+
+/**
+  *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+public class BasicParameters implements Parameters {
+ 
+  /** The list of unlinked out  XML_Port */
+  Hashtable parameters = null;
+    
+  public BasicParameters() {
+    parameters = new Hashtable();
+  }
+  
+  public void setParameter(String name, Object value){
+    parameters.put((Object)name,value);
+  }
+
+  public void unsetParameter(String name){
+    parameters.remove((Object)name);
+  }
+
+  public Object getParameter(String name){
+    return parameters.get((Object)name);
+  }
+
+  public Enumeration getNames(){
+    return parameters.keys();
+  }
+
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/DistanceAlignment.java b/src/fr/inrialpes/exmo/align/impl/DistanceAlignment.java
new file mode 100644
index 0000000000000000000000000000000000000000..87cbdf37cd53db589f48d3de14b29cfbe2753c34
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/DistanceAlignment.java
@@ -0,0 +1,98 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2003-2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package fr.inrialpes.exmo.align.impl; 
+
+import java.lang.ClassNotFoundException;
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.io.PrintStream;
+import java.io.IOException;
+import java.net.URI;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import org.semanticweb.owl.model.OWLOntology;
+import org.semanticweb.owl.model.OWLEntity;
+import org.semanticweb.owl.model.OWLException;
+
+import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.AlignmentVisitor;
+import org.semanticweb.owl.align.Cell;
+import org.semanticweb.owl.align.Relation;
+
+/**
+ * Represents an OWL ontology alignment. An ontology comprises a number of
+ * collections. Each ontology has a number of classes, properties and
+ * individuals, along with a number of axioms asserting information
+ * about those objects.
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+
+public class DistanceAlignment extends BasicAlignment
+{
+    /** Creation **/
+    public DistanceAlignment( OWLOntology onto1, OWLOntology onto2 ){
+    	init( onto1, onto2 );
+    };
+
+    public void addAlignDistanceCell( Object ob1, Object ob2, String relation, double measure) throws AlignmentException {
+	addAlignCell( ob1, ob2, relation, 1-measure );
+    }
+    public double getAlignedDistance1( Object ob ) throws AlignmentException {
+	return (1 - getAlignedStrength1(ob));
+    };
+    public double getAlignedDistance2( Object ob ) throws AlignmentException{
+	return (1 - getAlignedStrength1(ob));
+    };
+
+	// This mechanism should be parametric!
+	// Select the best match
+	// There can be many algorithm for these:
+	// n:m: get all of those above a threshold
+	// 1:1: get the best discard lines and columns and iterate
+	// Here we basically implement ?:* because the algorithm
+	// picks up the best matching object above threshold for i.
+
+    protected void selectBestMatch( int nbobj1, Vector list1, int nbobj2, Vector list2, double[][] matrix, double threshold, Object way) throws AlignmentException {
+	if (debug > 0) System.err.print("Storing class alignment\n");
+	
+	for ( int i=0; i<nbobj1; i++ ){
+	    boolean found = false;
+	    int best = 0;
+	    double max = threshold;
+	    for ( int j=0; j<nbobj2; j++ ){
+		if ( matrix[i][j] < max) {
+		    found = true;
+		    best = j;
+		    max = matrix[i][j];
+		}
+	    }
+	    if ( found ) { addAlignDistanceCell( (OWLEntity)list1.get(i), (OWLEntity)list2.get(best), "=", max ); }
+	}
+    }
+
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/eval/SymMeanEvaluator.java b/src/fr/inrialpes/exmo/align/impl/eval/SymMeanEvaluator.java
new file mode 100644
index 0000000000000000000000000000000000000000..73f22c0245b11403e69029a0f818497f79ee2e3e
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/eval/SymMeanEvaluator.java
@@ -0,0 +1,133 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package fr.inrialpes.exmo.align.impl; 
+
+import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.Cell;
+import org.semanticweb.owl.align.Evaluator;
+import org.semanticweb.owl.align.Parameters;
+
+import org.semanticweb.owl.model.OWLOntology;
+import org.semanticweb.owl.model.OWLEntity;
+import org.semanticweb.owl.model.OWLException;
+
+import java.lang.Math;
+import java.lang.ClassNotFoundException;
+import java.util.Enumeration;
+import java.io.PrintStream;
+import java.io.IOException;
+
+import java.net.URI;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * Evaluate proximity between two alignments.
+ * This function implements a simple weighted symetric difference.
+ * Add classification per type of objects (Ind, Class, Prop...)
+ *
+ * @author Jerome Euzenat
+ * @version $Id$ 
+ */
+
+public class SymMeanEvaluator extends BasicEvaluator
+{
+    // NOTE(JE): It will be very easy to compute the score on:
+    // - Classes, Properties, Individuals separately
+    // And to aggregate them in the final value...
+    private double classScore = 0.;
+    private double propScore = 0.;
+    private double indScore = 0.;
+
+    /** Creation **/
+    public SymMeanEvaluator( Alignment align1, Alignment align2 ){
+	super(align1,align2);
+    }
+
+    public double eval( Parameters params ) throws AlignmentException {
+	int nbClassCell = 0;
+	int nbPropCell = 0;
+	int nbIndCell = 0;
+	result = 0.;
+	classScore = 0.;
+	propScore = 0.;
+	indScore = 0.;
+	
+	try {
+	    for (Enumeration e = align1.getElements() ; e.hasMoreElements() ;) {
+		Cell c1 = (Cell)e.nextElement();
+		if ( Class.forName("org.semanticweb.owl.model.OWLClass").isInstance(c1.getObject1()) )
+		    nbClassCell++;
+		else if ( Class.forName("org.semanticweb.owl.model.OWLProperty").isInstance(c1.getObject1()) )
+		    nbPropCell++;
+		else nbIndCell++;
+		Cell c2 = (Cell)align2.getAlignCell1((OWLEntity)c1.getObject1());
+		if ( c2 != null ){
+		    if ( c1.getObject2() == c2.getObject2() ) {
+			if ( Class.forName("org.semanticweb.owl.model.OWLClass").isInstance(c1.getObject1()) ) {
+			    classScore = classScore + 1 - Math.abs(c2.getStrength() - c1.getStrength());
+			} else if ( Class.forName("org.semanticweb.owl.model.OWLProperty").isInstance(c1.getObject1()) ) {
+			    propScore = propScore + 1 - Math.abs(c2.getStrength() - c1.getStrength());
+			} else {
+			    indScore = indScore + 1 - Math.abs(c2.getStrength() - c1.getStrength());}}}
+	    }
+	    for (Enumeration e = align2.getElements() ; e.hasMoreElements() ;) {
+		Cell c2 = (Cell)e.nextElement();
+		if ( Class.forName("org.semanticweb.owl.model.OWLClass").isInstance(c2.getObject1()))
+		    nbClassCell++;
+		else if ( Class.forName("org.semanticweb.owl.model.OWLProperty").isInstance(c2.getObject1()) )
+		    nbPropCell++;
+		else nbIndCell++;
+		Cell c1 = (Cell)align1.getAlignCell1((OWLEntity)c2.getObject1());
+		if ( c1 != null ){
+		    if ( c2.getObject2() == c1.getObject2() ) {
+			if ( Class.forName("org.semanticweb.owl.model.OWLClass").isInstance(c2.getObject1()) ) {
+			    classScore = classScore + 1 - Math.abs(c1.getStrength() - c2.getStrength());
+			} else if ( Class.forName("org.semanticweb.owl.model.OWLProperty").isInstance(c2.getObject1()) ) {
+			    propScore = propScore + 1 - Math.abs(c1.getStrength() - c2.getStrength());
+			} else {
+			    indScore = indScore + 1 - Math.abs(c1.getStrength() - c2.getStrength());}}}
+	    }
+	} catch (ClassNotFoundException e) { e.printStackTrace(); }
+
+	// Beware, this must come first
+	result = (classScore+propScore+indScore) / (nbClassCell+nbPropCell+nbIndCell);
+	classScore = classScore / nbClassCell;
+	propScore = propScore / nbPropCell;
+	indScore = indScore / nbIndCell;
+	return(result);
+    }
+
+    public void write( PrintStream writer ) throws java.io.IOException {
+	writer.print("<rdf:RDF>\n  <Evaluation class=\"SymMeanEvaluator\">\n    <class>");
+ 	writer.print(classScore);
+	writer.print("</class>\n    <properties>");
+ 	writer.print(propScore);
+	writer.print("</properties>\n    <individuals>");
+ 	writer.print(indScore);
+	writer.print("</individuals>\n    <result>");
+ 	writer.print(result);
+ 	writer.print("</result>\n  </Evaluation>\n</rdf:RDF>\n");
+    }
+
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/method/ClassStructAlignment.java b/src/fr/inrialpes/exmo/align/impl/method/ClassStructAlignment.java
new file mode 100644
index 0000000000000000000000000000000000000000..242196bc1e4ff4a5b3515fae0aaf7161b91749de
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/method/ClassStructAlignment.java
@@ -0,0 +1,199 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2003-2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+
+package fr.inrialpes.exmo.align.impl; 
+
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.Set;
+import java.util.HashSet;
+import java.lang.reflect.Method;
+
+import org.semanticweb.owl.model.OWLOntology;
+import org.semanticweb.owl.model.OWLClass;
+import org.semanticweb.owl.model.OWLProperty;
+import org.semanticweb.owl.model.OWLFrame;
+import org.semanticweb.owl.impl.model.OWLDataCardinalityRestrictionImpl;
+import org.semanticweb.owl.impl.model.OWLObjectCardinalityRestrictionImpl;
+import org.semanticweb.owl.model.OWLRestriction;
+import org.semanticweb.owl.model.OWLDescription;
+import org.semanticweb.owl.model.OWLNaryBooleanDescription;
+import org.semanticweb.owl.model.OWLException;
+import org.semanticweb.owl.model.OWLEntity;
+
+import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.AlignmentProcess;
+import org.semanticweb.owl.align.Cell;
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.Parameters;
+
+/** This class has been built for ISWC experiments with bibliography.
+ * It implements a non iterative (one step) OLA algorithms based on
+ * the name of classes and properties. It could be made iterative by
+ *  just adding range/domain on properties...
+ *  The parameters are:
+ *  - threshold: above what do we select for the alignment;
+ *  - epsillon [ignored]: for convergence
+ *  - pic1: weigth for class name
+ *  - pic2: weight for class attributes
+ *  - pia1 [ignored=1]: weigth for property name
+ *  - pia3 [ignored=0]: weigth for property domain
+ *  - pia4 [ignored=0]: weigth for property range
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+
+public class ClassStructAlignment extends DistanceAlignment implements AlignmentProcess
+{
+    /** Creation **/
+    public ClassStructAlignment( OWLOntology onto1, OWLOntology onto2 ){
+    	super( onto1, onto2 );
+    };
+
+    private double max( double i, double j) { if ( i>j ) return i; else return j; }
+
+    /** Processing **/
+    public void align( Alignment alignment, Parameters params ) throws AlignmentException, OWLException {
+	//ignore alignment;
+	double threshold = 0.6; // threshold above which distances are to high
+	int i, j = 0;     // index for onto1 and onto2 classes
+	int l1, l2 = 0;   // length of strings (for normalizing)
+	int nbclass1 = 0; // number of classes in onto1
+	int nbclass2 = 0; // number of classes in onto2
+	Vector classlist2 = new Vector(10); // onto2 classes
+	Vector classlist1 = new Vector(10); // onto1 classes
+	double classmatrix[][];   // class distance matrix
+	double pic1 = 0.5; // class weigth for name
+	double pic2 = 0.5; // class weight for properties
+
+	ingest( alignment );
+	// Create class lists
+	for ( Iterator it = onto2.getClasses().iterator(); it.hasNext(); nbclass2++ ){
+	    classlist2.add( it.next() );
+	}
+	for ( Iterator it = onto1.getClasses().iterator(); it.hasNext(); nbclass1++ ){
+	    classlist1.add( it.next() );
+	}
+	classmatrix = new double[nbclass1+1][nbclass2+1];
+	
+	if (debug > 0) System.err.println("Initializing class distances");
+	// Initialize class distances
+	for ( i=0; i<nbclass1; i++ ){
+	    OWLClass cl = (OWLClass)classlist1.get(i);
+	    for ( j=0; j<nbclass2; j++ ){
+		classmatrix[i][j] = pic1 * StringDistances.subStringDistance(
+									     cl.getURI().getFragment().toLowerCase(),
+									     ((OWLClass)classlist2.get(j)).getURI().getFragment().toLowerCase());
+	    }
+	}
+
+	if (debug > 0) System.err.print("Computing class distances\n");
+	// Compute classes distances
+	// -- for all of its attribute, find the best match if possible... easy
+	// -- simply replace in the matrix the value by the value plus the 
+	// classmatrix[i][j] =
+	// pic1 * classmatrix[i][j]
+	// + pic2 * 2 *
+	//  (sigma (att in c[i]) getAllignCell... )
+	//  / nbatts of c[i] + nbatts of c[j]
+	for ( i=0; i<nbclass1; i++ ){
+	    Set properties1 = getProperties( (OWLClass)classlist1.get(i), onto1 );
+	    int nba1 = properties1.size();
+	    if ( nba1 > 0 ) { // if not, keep old values...
+		Set correspondences = new HashSet();
+		for ( j=0; j<nbclass2; j++ ){
+		    Set properties2 = getProperties( (OWLClass)classlist2.get(j), onto2 );
+		    int nba2 = properties1.size();
+		    double attsum = 0.;
+		    // check that there is a correspondance
+		    // in list of class2 atts and add their weights
+		    for ( Iterator prp = properties1.iterator(); prp.hasNext(); ){
+			Cell cell = getAlignCell1( (OWLEntity)prp.next() );
+			if ( cell != null ) {
+			    if ( properties2.contains((Object)cell.getObject2() ) ) {
+				attsum = attsum + 1 - cell.getStrength();
+			    }
+			}
+		    }
+		    classmatrix[i][j] = classmatrix[i][j]
+			+ pic2 * (2 * attsum / (nba1 + nba2));
+		}
+	    }
+	    // Assess factor
+	    // -- FirstExp: nothing to be done: one pass
+	}
+	selectBestMatch( nbclass1, classlist1, nbclass2, classlist2, classmatrix, threshold, null);
+
+    }
+
+    public void getProperties( OWLDescription desc, OWLOntology o, Set list){
+	// I am Jerome Euzenat and I am sure that there is some problem here...
+	// DISPATCHING MANUALLY !
+	try {
+	    Method mm = null;
+	if ( Class.forName("org.semanticweb.owl.model.OWLRestriction").isInstance(desc) ){
+	    mm = this.getClass().getMethod("getProperties",
+					   new Class [] {Class.forName("org.semanticweb.owl.model.OWLRestriction"),Class.forName("org.semanticweb.owl.model.OWLOntology"),Class.forName("java.util.Set")});
+	} else if (Class.forName("org.semanticweb.owl.model.OWLClass").isInstance(desc) ) {
+	    mm = this.getClass().getMethod("getProperties",
+					   new Class [] {Class.forName("org.semanticweb.owl.model.OWLClass"),Class.forName("org.semanticweb.owl.model.OWLOntology"),Class.forName("java.util.Set")});
+	} else if (Class.forName("org.semanticweb.owl.model.OWLNaryBooleanDescription").isInstance(desc) ) {
+	    mm = this.getClass().getMethod("getProperties",
+					   new Class [] {Class.forName("org.semanticweb.owl.model.OWLNaryBooleanDescription"),Class.forName("org.semanticweb.owl.model.OWLOntology"),Class.forName("java.util.Set")});
+	}
+	if ( mm != null ) mm.invoke(this,new Object[] {desc,o,list});
+	    //Method mmm[] = this.getClass().getMethods();
+	    //for ( int i = 0; i < mmm.length ; i++ ){
+	    //	if ( mmm[i].getName().equals("getProperties") ){
+	    //	    mmm[i].invoke(this,new Object[] {desc,o,list});
+	    //	    i = mmm.length;
+	    //	}
+	    // }
+	} catch (Exception e) { e.printStackTrace(); };
+    }
+    public void getProperties( OWLRestriction rest, OWLOntology o, Set list) throws OWLException {
+	list.add( (Object)rest.getProperty() );
+    }
+    public void getProperties( OWLNaryBooleanDescription d, OWLOntology o, Set list) throws OWLException {
+	for ( Iterator it = d.getOperands().iterator(); it.hasNext() ;){
+	    getProperties( (OWLDescription)it.next(), o, list );
+	}
+    }
+    public void getProperties( OWLClass cl, OWLOntology o, Set list) throws OWLException {
+	for ( Iterator it = cl.getSuperClasses(o).iterator(); it.hasNext(); ){
+	    OWLDescription dsc = (OWLDescription)it.next();
+	    getProperties( dsc, o, list );
+	}
+	// JE: I suspect that this can be a cause for looping!!
+	for ( Iterator it = cl.getEquivalentClasses(o).iterator(); it.hasNext(); ){
+	    getProperties( (OWLDescription)it.next(), o, list );
+	}
+    }
+
+    private Set getProperties( OWLClass cl, OWLOntology o ) throws OWLException {
+	Set resultSet = new HashSet(); 
+	getProperties( cl, o, resultSet );
+	return resultSet;
+    }
+
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/method/PropSubsDistAlignment.java b/src/fr/inrialpes/exmo/align/impl/method/PropSubsDistAlignment.java
new file mode 100644
index 0000000000000000000000000000000000000000..96904ab740598ce0cdd0c101b2be689aeb16fe65
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/method/PropSubsDistAlignment.java
@@ -0,0 +1,129 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2003-2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+
+package fr.inrialpes.exmo.align.impl; 
+
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.Set;
+import java.util.HashSet;
+
+import org.semanticweb.owl.model.OWLOntology;
+import org.semanticweb.owl.model.OWLClass;
+import org.semanticweb.owl.model.OWLProperty;
+import org.semanticweb.owl.model.OWLFrame;
+import org.semanticweb.owl.model.OWLRestriction;
+import org.semanticweb.owl.model.OWLDescription;
+import org.semanticweb.owl.model.OWLNaryBooleanDescription;
+import org.semanticweb.owl.model.OWLException;
+import org.semanticweb.owl.model.OWLEntity;
+
+import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.AlignmentProcess;
+import org.semanticweb.owl.align.Cell;
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.Parameters;
+
+/** This class has been built for ISWC experiments with bibliography.
+ * It implements a non iterative (one step) OLA algorithms based on
+ * the name of classes and properties. It could be made iterative by
+ *  just adding range/domain on properties...
+ *  The parameters are:
+ *  - threshold: above what do we select for the alignment;
+ *  - epsillon [ignored]: for convergence
+ *  - pic1: weigth for class name
+ *  - pic2: weight for class attributes
+ *  - pia1 [ignored=1]: weigth for property name
+ *  - pia3 [ignored=0]: weigth for property domain
+ *  - pia4 [ignored=0]: weigth for property range
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+
+public class PropSubsDistAlignment extends DistanceAlignment implements AlignmentProcess
+{
+    /** Creation **/
+    public PropSubsDistAlignment( OWLOntology onto1, OWLOntology onto2 ){
+    	super( onto1, onto2 );
+	setType("**");
+    };
+
+    private double max( double i, double j) { if ( i>j ) return i; else return j; }
+
+    /** Processing **/
+    public void align( Alignment alignment, Parameters param ) throws AlignmentException, OWLException {
+	//ignore alignment;
+	double threshold = 1.; // threshold above which distances are to high
+	int i, j = 0;     // index for onto1 and onto2 classes
+	int l1, l2 = 0;   // length of strings (for normalizing)
+	int nbprop1 = 0; // number of properties in onto1
+	int nbprop2 = 0; // number of properties in onto2
+	Vector proplist2 = new Vector(10); // onto2 properties
+	Vector proplist1 = new Vector(10); // onto1 properties
+	double propmatrix[][];   // properties distance matrix
+
+	// Create property lists and matrix
+	for ( Iterator it = onto1.getObjectProperties().iterator(); it.hasNext(); nbprop1++ ){
+	    proplist1.add( it.next() );
+	}
+	for ( Iterator it = onto1.getDataProperties().iterator(); it.hasNext(); nbprop1++ ){
+	    proplist1.add( it.next() );
+	}
+	for ( Iterator it = onto2.getObjectProperties().iterator(); it.hasNext(); nbprop2++ ){
+	    proplist2.add( it.next() );
+	}
+	for ( Iterator it = onto2.getDataProperties().iterator(); it.hasNext(); nbprop2++ ){
+	    proplist2.add( it.next() );
+	}
+	propmatrix = new double[nbprop1+1][nbprop2+1];
+
+	if (debug > 0) System.err.println("Initializing property distances");
+	for ( i=0; i<nbprop1; i++ ){
+	    OWLProperty cl = (OWLProperty)proplist1.get(i);
+	    String s1 = cl.getURI().getFragment().toLowerCase();
+	    for ( j=0; j<nbprop2; j++ ){
+		cl = (OWLProperty)proplist2.get(j);
+		String s2 = cl.getURI().getFragment().toLowerCase();
+		propmatrix[i][j] = StringDistances.subStringDistance( s1, s2 );
+	    }
+	}
+
+	// Compute property distances
+	if (debug > 0) System.err.print("Storing property alignment\n");
+	for ( i=0; i<nbprop1; i++ ){
+	    boolean found = false;
+	    int best = 0;
+	    double max = threshold;
+	    for ( j=0; j<nbprop2; j++ ){
+		if ( propmatrix[i][j] < max) {
+		    found = true;
+		    best = j;
+		    max = propmatrix[i][j];
+		}
+	    }
+	    if ( found ) { addAlignDistanceCell( (OWLProperty)proplist1.get(i), (OWLProperty)proplist2.get(best), "=", max ); }
+	}
+		
+    }
+
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/method/StringDistances.java b/src/fr/inrialpes/exmo/align/impl/method/StringDistances.java
new file mode 100644
index 0000000000000000000000000000000000000000..bdfdc46cc2ae05ad34af5cea7eb9950246411b1a
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/method/StringDistances.java
@@ -0,0 +1,151 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2003-2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+/** 
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+package fr.inrialpes.exmo.align.impl; 
+
+
+public class StringDistances {
+
+  //*****************************
+  // Compute substring distance
+  // = 1 - (2 | length of longest common substring | / |s1|+|s2|)
+  //*****************************
+
+    public static double subStringDistance (String s1, String s2) {
+	if (s1 == null || s2 == null) {
+	    throw new IllegalArgumentException("Strings must not be null");
+	}
+		
+	int l1 = s1.length(); // length of s
+	int l2 = s2.length(); // length of t
+		
+	if ((l1 == 0) && ( l2 == 0 )) return 0;
+	if ((l1 == 0) || ( l2 == 0 )) return 1;
+
+	int max = Math.min( l1, l2 ); // the maximal length of a subs
+	int best = 0; // the best subs length so far
+	    
+	int i = 0; // iterates through s1
+	int j = 0; // iterates through s2
+
+	for( i=0; (i < l1) && (l1-i > best); i++ ){
+	    j = 0;
+	    while( l2-j > best ){
+		int k = i;
+		for( ; (j < l2 )
+			 && (s1.charAt(k) != s2.charAt(j) ); j++) {};
+		if ( j != l2 ) {// we have found a starting point
+		    for( j++, k++; (j < l2) && (k < l1) && (s1.charAt(k) == s2.charAt(j)); j++, k++);
+		    best = Math.max( best, k-i );
+		}
+	    }
+	}
+	//System.err.println(s1+" x "+s2+" = "+(1.0 - ((double)2*best / (l1+l2))));
+	return (1.0 - ((double)2*best / (l1+l2)));
+    }
+
+
+/* Pointer was provided in Todd Hugues (Lockheed)
+   Taken from http://www.merriampark.com/ldjava.htm
+   Initial algorithm by Michael Gilleland
+   Integrated in Apache Jakarta Commons
+   Improved by Chas Emerick
+   This algorithm should be taken appart of this file and reset in the
+   context of a proper package name with an acceptable license terms.
+   Hopefully, Jakarta Commons will provide this.
+ */
+
+
+    public static int levenshteinDistance (String s, String t) {
+	if (s == null || t == null) {
+	    throw new IllegalArgumentException("Strings must not be null");
+	}
+		
+	/*
+	  The difference between this impl. and the previous is that, rather 
+	  than creating and retaining a matrix of size s.length()+1 by 
+	  t.length()+1,
+	  we maintain two single-dimensional arrays of length s.length()+1.
+	  The first, d, is the 'current working' distance array that maintains
+	  the newest distance cost counts as we iterate through the characters
+	  of String s.  Each time we increment the index of String t we are 
+	  comparing, d is copied to p, the second int[]. Doing so allows us
+	  to retain the previous cost counts as required by the algorithm
+	  (taking the minimum of the cost count to the left, up one, and
+	  diagonally up and to the left of the current cost count being
+	  calculated).
+	  (Note that the arrays aren't really copied anymore, just switched...
+	  this is clearly much better than cloning an array or doing a
+	  System.arraycopy() each time  through the outer loop.)
+	  
+	  Effectively, the difference between the two implementations is this
+	  one does not cause an out of memory condition when calculating the LD
+	  over two very large strings.  		
+	*/		
+		
+	int n = s.length(); // length of s
+	int m = t.length(); // length of t
+		
+	if (n == 0) return m;
+	else if (m == 0) return n;
+
+	int p[] = new int[n+1]; //'previous' cost array, horizontally
+	int d[] = new int[n+1]; // cost array, horizontally
+	int _d[]; //placeholder to assist in swapping p and d
+
+	// indexes into strings s and t
+	int i; // iterates through s
+	int j; // iterates through t
+
+	char t_j; // jth character of t
+
+	int cost; // cost
+
+	for (i = 0; i<=n; i++) p[i] = i;
+	
+	for (j = 1; j<=m; j++) {
+	    t_j = t.charAt(j-1);
+	    d[0] = j;
+	    
+	    for (i=1; i<=n; i++) {
+		cost = s.charAt(i-1)==t_j ? 0 : 1;
+		// minimum of cell to the left+1, to the top+1,
+		// diagonally left and up +cost				
+		d[i] = Math.min(Math.min(d[i-1]+1, p[i]+1),  p[i-1]+cost);  
+	    }
+	    
+	    // copy current distance counts to 'previous row' distance counts
+	    _d = p;
+	    p = d;
+	    d = _d;
+	} 
+
+	// our last action in the above loop was to switch d and p, so p now 
+	// actually has the most recent cost counts
+	//System.err.println(s+" x "+t+" = "+p[n]);
+	return p[n];
+    }
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/method/StrucSubsDistAlignment.java b/src/fr/inrialpes/exmo/align/impl/method/StrucSubsDistAlignment.java
new file mode 100644
index 0000000000000000000000000000000000000000..cfb7dba38293b7b929213302a15aa672890f1a53
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/method/StrucSubsDistAlignment.java
@@ -0,0 +1,281 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2003-2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+
+package fr.inrialpes.exmo.align.impl; 
+
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.Set;
+import java.util.HashSet;
+import java.lang.reflect.Method;
+import java.lang.Integer;
+
+import org.semanticweb.owl.model.OWLOntology;
+import org.semanticweb.owl.model.OWLClass;
+import org.semanticweb.owl.model.OWLProperty;
+import org.semanticweb.owl.model.OWLFrame;
+import org.semanticweb.owl.model.OWLRestriction;
+import org.semanticweb.owl.model.OWLDescription;
+import org.semanticweb.owl.model.OWLNaryBooleanDescription;
+import org.semanticweb.owl.model.OWLException;
+import org.semanticweb.owl.model.OWLEntity;
+
+import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.AlignmentProcess;
+import org.semanticweb.owl.align.Cell;
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.Parameters;
+
+/** This class has been built for ISWC experiments with bibliography.
+ * It implements a non iterative (one step) OLA algorithms based on
+ * the name of classes and properties. It could be made iterative by
+ *  just adding range/domain on properties...
+ *  The parameters are:
+ *  - threshold: above what do we select for the alignment;
+ *  - epsillon [ignored]: for convergence
+ *  - pic1: weigth for class name
+ *  - pic2: weight for class attributes
+ *  - pia1 [ignored=1]: weigth for property name
+ *  - pia3 [ignored=0]: weigth for property domain
+ *  - pia4 [ignored=0]: weigth for property range
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+
+public class StrucSubsDistAlignment extends DistanceAlignment implements AlignmentProcess
+{
+    /** Creation **/
+    public StrucSubsDistAlignment( OWLOntology onto1, OWLOntology onto2 ){
+    	super( onto1, onto2 );
+	setType("**");
+    };
+
+    private double max( double i, double j) { if ( i>j ) return i; else return j; }
+
+    /** Processing **/
+    public void align( Alignment alignment, Parameters params ) throws AlignmentException, OWLException {
+	//ignore alignment;
+	double threshold = 1.; // threshold above which distances are too high
+	int i, j = 0;     // index for onto1 and onto2 classes
+	int l1, l2 = 0;   // length of strings (for normalizing)
+	int nbclass1 = 0; // number of classes in onto1
+	int nbclass2 = 0; // number of classes in onto2
+	Vector classlist2 = new Vector(10); // onto2 classes
+	Vector classlist1 = new Vector(10); // onto1 classes
+	double classmatrix[][];   // class distance matrix
+	int nbprop1 = 0; // number of properties in onto1
+	int nbprop2 = 0; // number of properties in onto2
+	Vector proplist2 = new Vector(10); // onto2 properties
+	Vector proplist1 = new Vector(10); // onto1 properties
+	double propmatrix[][];   // properties distance matrix
+	double pic1 = 0.5; // class weigth for name
+	double pic2 = 0.5; // class weight for properties
+	double pia1 = 1.; // relation weight for name
+	double pia2 = 0.; // relation weight for domain
+	double pia3 = 0.; // relation weight for range
+	double epsillon = 0.05; // stoping condition
+
+	if ( params.getParameter("debug") != null )
+	    debug = ((Integer)params.getParameter("debug")).intValue();
+
+	// Create property lists and matrix
+	for ( Iterator it = onto1.getObjectProperties().iterator(); it.hasNext(); nbprop1++ ){
+	    proplist1.add( it.next() );
+	}
+	for ( Iterator it = onto1.getDataProperties().iterator(); it.hasNext(); nbprop1++ ){
+	    proplist1.add( it.next() );
+	}
+	for ( Iterator it = onto2.getObjectProperties().iterator(); it.hasNext(); nbprop2++ ){
+	    proplist2.add( it.next() );
+	}
+	for ( Iterator it = onto2.getDataProperties().iterator(); it.hasNext(); nbprop2++ ){
+	    proplist2.add( it.next() );
+	}
+	propmatrix = new double[nbprop1+1][nbprop2+1];
+	
+	// Create class lists
+	for ( Iterator it = onto2.getClasses().iterator(); it.hasNext(); nbclass2++ ){
+	    classlist2.add( it.next() );
+	}
+	for ( Iterator it = onto1.getClasses().iterator(); it.hasNext(); nbclass1++ ){
+	    classlist1.add( it.next() );
+	}
+	classmatrix = new double[nbclass1+1][nbclass2+1];
+
+	if (debug > 0) System.err.println("Initializing property distances");
+	for ( i=0; i<nbprop1; i++ ){
+	    OWLProperty cl = (OWLProperty)proplist1.get(i);
+	    String s1 = cl.getURI().getFragment().toLowerCase();
+	    for ( j=0; j<nbprop2; j++ ){
+		cl = (OWLProperty)proplist2.get(j);
+		String s2 = cl.getURI().getFragment().toLowerCase();
+		propmatrix[i][j] = pia1 * StringDistances.subStringDistance( s1, s2 );
+	    }
+	}
+
+	if (debug > 0) System.err.println("Initializing class distances");
+	// Initialize class distances
+	for ( i=0; i<nbclass1; i++ ){
+	    OWLClass cl = (OWLClass)classlist1.get(i);
+	    for ( j=0; j<nbclass2; j++ ){
+		classmatrix[i][j] = pic1 * StringDistances.subStringDistance(
+						    cl.getURI().getFragment().toLowerCase(),
+						    ((OWLClass)classlist2.get(j)).getURI().getFragment().toLowerCase());
+	    }
+	}
+
+	// Iterate until completion
+	double factor = 1.0;
+	while ( factor > epsillon ){
+	    // Compute property distances
+	    // -- FirstExp: nothing to be done: one pass
+	    // Here create the best matches for property distance already
+	    // -- FirstExp: goes directly in the alignment structure
+	    //    since it will never be refined anymore...
+	    if (debug > 0) System.err.print("Storing property alignment\n");
+	    for ( i=0; i<nbprop1; i++ ){
+		boolean found = false;
+		int best = 0;
+		double max = threshold;
+		for ( j=0; j<nbprop2; j++ ){
+		    if ( propmatrix[i][j] < max) {
+			found = true;
+			best = j;
+			max = propmatrix[i][j];
+		    }
+		}
+		if ( found ) { addAlignDistanceCell( (OWLProperty)proplist1.get(i), (OWLProperty)proplist2.get(best), "=", max ); }
+	    }
+	    
+	    if (debug > 0) System.err.print("Computing class distances\n");
+	    // Compute classes distances
+	    // -- for all of its attribute, find the best match if possible... easy
+	    // -- simply replace in the matrix the value by the value plus the 
+	    // classmatrix[i][j] =
+	    // pic1 * classmatrix[i][j]
+	    // + pic2 * 2 *
+	    //  (sigma (att in c[i]) getAllignCell... )
+	    //  / nbatts of c[i] + nbatts of c[j]
+	    for ( i=0; i<nbclass1; i++ ){
+		Set properties1 = getProperties( (OWLClass)classlist1.get(i), onto1 );
+		int nba1 = properties1.size();
+		if ( nba1 > 0 ) { // if not, keep old values...
+		    Set correspondences = new HashSet();
+		    for ( j=0; j<nbclass2; j++ ){
+			Set properties2 = getProperties( (OWLClass)classlist2.get(j), onto2 );
+			int nba2 = properties1.size();
+			double attsum = 0.;
+			// check that there is a correspondance
+			// in list of class2 atts and add their weights
+			for ( Iterator prp = properties1.iterator(); prp.hasNext(); ){
+			    Cell cell = getAlignCell1( (OWLEntity)prp.next() );
+			    if ( cell != null ) {
+				if ( properties2.contains((Object)cell.getObject2() ) ) {
+				    attsum = attsum + 1 - cell.getStrength();
+				}
+			    }
+			}
+			classmatrix[i][j] = classmatrix[i][j]
+			    + pic2 * (2 * attsum / (nba1 + nba2));
+		    }
+		}
+	    }
+	    // Assess factor
+	    // -- FirstExp: nothing to be done: one pass
+	    factor = 0.;
+	}
+
+	// This mechanism should be parametric!
+	// Select the best match
+	// There can be many algorithm for these:
+	// n:m: get all of those above a threshold
+	// 1:1: get the best discard lines and columns and iterate
+	// Here we basically implement ?:* because the algorithm
+	// picks up the best matching object above threshold for i.
+	if (debug > 0) System.err.print("Storing class alignment\n");
+	
+	for ( i=0; i<nbclass1; i++ ){
+	    boolean found = false;
+	    int best = 0;
+	    double max = threshold;
+	    for ( j=0; j<nbclass2; j++ ){
+		if ( classmatrix[i][j] < max) {
+		    found = true;
+		    best = j;
+		    max = classmatrix[i][j];
+		}
+	    }
+	    if ( found ) { addAlignDistanceCell( (OWLClass)classlist1.get(i), (OWLClass)classlist2.get(best), "=", max ); }
+	}
+    }
+    
+    public void getProperties( OWLDescription desc, OWLOntology o, Set list){
+	// I am Jerome Euzenat and I am sure that there is some problem here...
+	// DISPATCHING MANUALLY !
+	try {
+	    Method mm = null;
+	    if ( Class.forName("org.semanticweb.owl.model.OWLRestriction").isInstance(desc) ){
+		mm = this.getClass().getMethod("getProperties",
+					       new Class [] {Class.forName("org.semanticweb.owl.model.OWLRestriction"),Class.forName("org.semanticweb.owl.model.OWLOntology"),Class.forName("java.util.Set")});
+	    } else if (Class.forName("org.semanticweb.owl.model.OWLClass").isInstance(desc) ) {
+		mm = this.getClass().getMethod("getProperties",
+					       new Class [] {Class.forName("org.semanticweb.owl.model.OWLClass"),Class.forName("org.semanticweb.owl.model.OWLOntology"),Class.forName("java.util.Set")});
+	    } else if (Class.forName("org.semanticweb.owl.model.OWLNaryBooleanDescription").isInstance(desc) ) {
+		mm = this.getClass().getMethod("getProperties",
+					       new Class [] {Class.forName("org.semanticweb.owl.model.OWLNaryBooleanDescription"),Class.forName("org.semanticweb.owl.model.OWLOntology"),Class.forName("java.util.Set")});
+	    }
+	    if ( mm != null ) mm.invoke(this,new Object[] {desc,o,list});
+	    //Method mmm[] = this.getClass().getMethods();
+	    //for ( int i = 0; i < mmm.length ; i++ ){
+	    //	if ( mmm[i].getName().equals("getProperties") ){
+	    //	    mmm[i].invoke(this,new Object[] {desc,o,list});
+	    //	    i = mmm.length;
+	    //	}
+	    // }
+	} catch (Exception e) { e.printStackTrace(); };
+    }
+    public void getProperties( OWLRestriction rest, OWLOntology o, Set list) throws OWLException {
+	list.add( (Object)rest.getProperty() );
+    }
+    public void getProperties( OWLNaryBooleanDescription d, OWLOntology o, Set list) throws OWLException {
+	for ( Iterator it = d.getOperands().iterator(); it.hasNext() ;){
+	    getProperties( (OWLDescription)it.next(), o, list );
+	}
+    }
+    public void getProperties( OWLClass cl, OWLOntology o, Set list) throws OWLException {
+	for ( Iterator it = cl.getSuperClasses(o).iterator(); it.hasNext(); ){
+	    OWLDescription dsc = (OWLDescription)it.next();
+	    getProperties( dsc, o, list );
+	}
+	// JE: I suspect that this can be a cause for looping!!
+	for ( Iterator it = cl.getEquivalentClasses(o).iterator(); it.hasNext(); ){
+	    getProperties( (OWLDescription)it.next(), o, list );
+	}
+    }
+
+    private Set getProperties( OWLClass cl, OWLOntology o ) throws OWLException {
+	Set resultSet = new HashSet(); 
+	getProperties( cl, o, resultSet );
+	return resultSet;
+    }
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/rel/EquivRelation.java b/src/fr/inrialpes/exmo/align/impl/rel/EquivRelation.java
new file mode 100644
index 0000000000000000000000000000000000000000..300d2266cc08393e220cad33f444613f4a25b6a6
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/rel/EquivRelation.java
@@ -0,0 +1,48 @@
+/*
+ * $Id$
+ * Copyright (C) INRIA Rhône-Alpes, 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package fr.inrialpes.exmo.align.impl; 
+
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.AlignmentVisitor;
+
+/**
+ * Represents an OWL equivalence relation.
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+public class EquivRelation extends BasicRelation
+{
+    public void accept( AlignmentVisitor visitor) throws AlignmentException {
+	visitor.visit( this );
+    }
+    /**
+     * It is intended that the value of the relation is =, < or >.
+     * But this can be any string in other applications.
+     */
+
+    /** Creation **/
+    public EquivRelation(){
+	super("=");
+    }
+}
+
+
diff --git a/src/fr/inrialpes/exmo/align/impl/rel/IncompatRelation.java b/src/fr/inrialpes/exmo/align/impl/rel/IncompatRelation.java
new file mode 100644
index 0000000000000000000000000000000000000000..223c9492024eb74b09f0f35b9250228937c2b977
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/rel/IncompatRelation.java
@@ -0,0 +1,48 @@
+/*
+ * $Id$
+ * Copyright (C) INRIA Rhône-Alpes, 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package fr.inrialpes.exmo.align.impl; 
+
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.AlignmentVisitor;
+
+/**
+ * Represents an OWL equivalence relation.
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+public class IncompatRelation extends BasicRelation
+{
+    public void accept( AlignmentVisitor visitor) throws AlignmentException {
+        visitor.visit( this );
+    }
+    /**
+     * It is intended that the value of the relation is =, < or >.
+     * But this can be any string in other applications.
+     */
+
+    /** Creation **/
+    public IncompatRelation(){
+	super("%");
+    }
+}
+
+
diff --git a/src/fr/inrialpes/exmo/align/impl/rel/SubsumeRelation.java b/src/fr/inrialpes/exmo/align/impl/rel/SubsumeRelation.java
new file mode 100644
index 0000000000000000000000000000000000000000..cd901aa7d1e42055c5cf15d05b8b28ab2c7b2a8a
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/rel/SubsumeRelation.java
@@ -0,0 +1,48 @@
+/*
+ * $Id$
+ * Copyright (C) INRIA Rhône-Alpes, 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package fr.inrialpes.exmo.align.impl; 
+
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.AlignmentVisitor;
+
+/**
+ * Represents an OWL subsumption relation.
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+public class SubsumeRelation extends BasicRelation
+{
+    public void accept( AlignmentVisitor visitor) throws AlignmentException {
+        visitor.visit( this );
+    }
+    /**
+     * It is intended that the value of the relation is =, < or >.
+     * But this can be any string in other applications.
+     */
+
+    /** Creation **/
+    public SubsumeRelation(){
+	super("<");
+    }
+}
+
+
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java
new file mode 100644
index 0000000000000000000000000000000000000000..4516fe5b88ba4aeed76a823bbd897098fdfd1734
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java
@@ -0,0 +1,163 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2003-2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package fr.inrialpes.exmo.align.impl; 
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.io.PrintStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URI;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import org.semanticweb.owl.model.OWLOntology;
+import org.semanticweb.owl.model.OWLEntity;
+import org.semanticweb.owl.model.OWLException;
+
+import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.AlignmentVisitor;
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.Cell;
+import org.semanticweb.owl.align.Relation;
+
+/**
+ * Renders an alignment as a new ontology merging these.
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+
+public class OWLAxiomsRendererVisitor implements AlignmentVisitor
+{
+    PrintStream writer = null;
+    Alignment alignment = null;
+    Cell cell = null;
+
+    public OWLAxiomsRendererVisitor( PrintStream writer ){
+	this.writer = writer;
+    }
+
+    public void visit( Alignment align ) throws AlignmentException {
+	alignment = align;
+	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");	
+	try {
+	    writer.print("  <owl:Ontology rdf:about=\"\">\n");
+	    writer.print("    <rdfs:comment>Aligned ontollogies</rdfs:comment>\n");
+	    writer.print("    <owl:imports rdf:resource=\""+((OWLOntology)align.getOntology1()).getLogicalURI().toString()+"\"/>\n");
+	    writer.print("    <owl:imports rdf:resource=\""+((OWLOntology)align.getOntology2()).getLogicalURI().toString()+"\"/>\n");
+	    writer.print("  </owl:Ontology>\n\n");
+
+	    for( Enumeration e = align.getElements() ; e.hasMoreElements(); ){
+		Cell c = (Cell)e.nextElement();
+		c.accept( this );
+	    } //end for
+	} catch (OWLException e) { throw new AlignmentException("getURI problem", e); };
+	
+	writer.print("</rdf:RDF>\n");
+    }
+    public void visit( Cell cell ) throws AlignmentException {
+	this.cell = cell;
+	OWLOntology onto1 = (OWLOntology)alignment.getOntology1();
+	try {
+	    URI entity1URI = ((OWLEntity)cell.getObject1()).getURI();
+	    if ( (OWLEntity)onto1.getClass( entity1URI ) != null ) { // A class
+		writer.print("  <owl:Class rdf:about=\""+entity1URI.toString()+"\">\n");
+		cell.getRelation().accept( this );
+		writer.print("  </owl:Class>\n");
+	    } else if ( (OWLEntity)onto1.getDataProperty( entity1URI ) != null ) { // A Dataproperty
+		writer.print("  <owl:DatatypeProperty rdf:about=\""+entity1URI.toString()+"\">\n");
+		cell.getRelation().accept( this );
+		writer.print("  </owl:DatatypeProperty>\n");
+	    } else if ( (OWLEntity)onto1.getObjectProperty( entity1URI ) != null ) { // An ObjectProperty
+		writer.print("  <owl:ObjectProperty rdf:about=\""+entity1URI.toString()+"\">\n");
+		cell.getRelation().accept( this );
+		writer.print("  </owl:ObjectProperty>\n");
+	    } else if ( (OWLEntity)onto1.getIndividual( entity1URI ) != null ) { // An individual (but check this)
+		writer.print("  <owl:Thing rdf:about=\""+entity1URI.toString()+"\">\n");
+		cell.getRelation().accept( this );
+		writer.print("  </owl:Thing>\n");
+	    }
+	    writer.print("\n");
+	} catch (OWLException e) { throw new AlignmentException("getURI problem", e); };
+    }
+    public void visit( EquivRelation rel ) throws AlignmentException {
+	OWLOntology onto2 = (OWLOntology)alignment.getOntology2();
+	try {
+	    URI entity2URI = ((OWLEntity)cell.getObject2()).getURI();
+	    if ( (OWLEntity)onto2.getClass( entity2URI ) != null ) { // A class
+		writer.print("    <owl:equivalentClass rdf:resource=\""+entity2URI.toString()+"\"/>\n");
+	    } else if ( (OWLEntity)onto2.getDataProperty( entity2URI ) != null ) { // A Dataproperty
+		writer.print("    <owl:equivalentProperty rdf:resource=\""+entity2URI.toString()+"\"/>\n");
+	    } else if ( (OWLEntity)onto2.getObjectProperty( entity2URI ) != null ) { // An ObjectProperty
+		writer.print("    <owl:equivalentProperty rdf:resource=\""+entity2URI.toString()+"\"/>\n");
+	    } else if ( (OWLEntity)onto2.getIndividual( entity2URI ) != null ) { // An individual (but check this)
+		writer.print("    <owl:sameAs rdf:resource=\""+entity2URI.toString()+"\"/>\n");
+	    }
+	} catch (OWLException e) { throw new AlignmentException("getURI problem", e); };
+    }
+
+
+    public void visit( SubsumeRelation rel ) throws AlignmentException {
+	OWLOntology onto2 = (OWLOntology)alignment.getOntology2();
+	try {
+	    URI entity2URI = ((OWLEntity)cell.getObject2()).getURI();
+	    if ( (OWLEntity)onto2.getClass( entity2URI ) != null ) { // A class
+		writer.print("    <rdfs:subClassOf rdf:resource=\""+entity2URI.toString()+"\"/>\n");
+	    } else if ( (OWLEntity)onto2.getDataProperty( entity2URI ) != null ) { // A Dataproperty
+		writer.print("    <rdfs:subPropertyOf rdf:resource=\""+entity2URI.toString()+"\"/>\n");
+	    } else if ( (OWLEntity)onto2.getObjectProperty( entity2URI ) != null ) { // An ObjectProperty
+		writer.print("    <rdfs:subPropertyOf rdf:resource=\""+entity2URI.toString()+"\"/>\n");
+	    }
+	} catch (OWLException e) { throw new AlignmentException("getURI problem", e); };
+    }
+    public void visit( IncompatRelation rel ) throws AlignmentException {
+	OWLOntology onto2 = (OWLOntology)alignment.getOntology2();
+	try {
+	    URI entity2URI = ((OWLEntity)cell.getObject2()).getURI();
+	    writer.print("    <owl:inverseOf rdf:resource=\""+entity2URI.toString()+"\"/>\n");
+	} catch (OWLException e) { throw new AlignmentException("getURI problem", e); };
+    }
+    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.EquivRelation").isInstance(rel) ){
+		mm = this.getClass().getMethod("visit",
+					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.EquivRelation")});
+	    } else if (Class.forName("fr.inrialpes.exmo.align.impl.SubsumeRelation").isInstance(rel) ) {
+		mm = this.getClass().getMethod("visit",
+					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.SubsumeRelation")});
+	    } else if (Class.forName("fr.inrialpes.exmo.align.impl.IncompatRelation").isInstance(rel) ) {
+		mm = this.getClass().getMethod("visit",
+					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.IncompatRelation")});
+	    }
+	    if ( mm != null ) mm.invoke(this,new Object[] {rel});
+	} catch (Exception e) { throw new AlignmentException("Dispatching problem ", e); };
+    };
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
new file mode 100644
index 0000000000000000000000000000000000000000..619b08c7465efd8c0e55002872ee962fec84c008
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
@@ -0,0 +1,112 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2003-2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package fr.inrialpes.exmo.align.impl; 
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.io.PrintStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URI;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import org.semanticweb.owl.model.OWLOntology;
+import org.semanticweb.owl.model.OWLEntity;
+import org.semanticweb.owl.model.OWLException;
+
+import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.AlignmentVisitor;
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.Cell;
+import org.semanticweb.owl.align.Relation;
+
+/**
+ * Renders an alignment as a new ontology merging these.
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+
+public class RDFRendererVisitor implements AlignmentVisitor
+{
+    PrintStream writer = null;
+    Alignment alignment = null;
+    Cell cell = null;
+
+    public RDFRendererVisitor( PrintStream writer ){
+	this.writer = writer;
+    }
+
+    public void visit( Alignment align ) throws AlignmentException {
+	alignment = align;
+	writer.print("<?xml version='1.0' encoding='utf-8");
+	//	writer.print(writer.getEncoding().toString());
+	writer.print("' standalone='no'?>\n");
+	writer.print("<!DOCTYPE rdf:RDF SYSTEM \"align.dtd\">\n\n");
+	// add date, etc.
+	writer.print("<rdf:RDF xmlns='http://knowledgeweb.semanticweb.org/heterogeneity/alignment'\n         xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'\n         xmlns:xsd='http://www.w3.org/2001/XMLSchema#'>\n");
+	writer.print("<Alignment>\n  <xml>yes</xml>\n");
+	writer.print("  <level>");
+	writer.print( align.getLevel() );
+	writer.print("</level>\n  <type>");
+	writer.print( align.getType() );
+	writer.print("</type>\n  <onto1>");
+	try {
+	    writer.print( ((OWLOntology)align.getOntology1()).getLogicalURI().toString());
+	    writer.print("</onto1>\n  <onto2>");
+	    writer.print( ((OWLOntology)align.getOntology2()).getLogicalURI().toString());
+	    writer.print("</onto2>\n");
+	    if ( align.getFile1() != null )
+		writer.print("  <uri1>"+align.getFile1().toString()+"</uri1>\n");
+	    if ( align.getFile2() != null )
+		writer.print("  <uri2>"+align.getFile2().toString()+"</uri2>\n");
+	    writer.print("  <map>\n");
+	    
+	    for( Enumeration e = align.getElements() ; e.hasMoreElements(); ){
+		Cell c = (Cell)e.nextElement();
+		c.accept( this );
+	    } //end for
+	} catch (OWLException ex) { throw new AlignmentException( "getURI problem", ex); }
+	writer.print("  </map>\n</Alignment>\n");
+	writer.print("</rdf:RDF>\n");
+    }
+    public void visit( Cell cell ) throws AlignmentException {
+	this.cell = cell;
+	//OWLOntology onto1 = (OWLOntology)alignment.getOntology1();
+	try {
+	    writer.print("    <Cell>\n      <entity1 rdf:resource='");
+	    writer.print( ((OWLEntity)cell.getObject1()).getURI().toString() );
+	    writer.print("'/>\n      <entity2 rdf:resource='");
+	    writer.print( ((OWLEntity)cell.getObject2()).getURI().toString() );
+	    writer.print("'/>\n      <measure rdf:datatype='http://www.w3.org/2001/XMLSchema#float'>");
+	    writer.print( cell.getStrength() );
+	    writer.print("</measure>\n      <relation>");
+	    cell.getRelation().accept( this );
+	    writer.print("</relation>\n    </Cell>\n");
+	} catch ( OWLException e) { throw new AlignmentException( "getURI problem", e ); }
+    }
+    public void visit( Relation rel ) {
+	rel.write( writer );
+    };
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/SWRLRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/SWRLRendererVisitor.java
new file mode 100644
index 0000000000000000000000000000000000000000..c018b19a0d3b97b43ba288767b4228df4c8b24e2
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/SWRLRendererVisitor.java
@@ -0,0 +1,136 @@
+/*
+ * $id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2003-2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package fr.inrialpes.exmo.align.impl; 
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.io.PrintStream;
+import java.io.IOException;
+
+import java.lang.reflect.Method;
+import java.net.URI;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import org.semanticweb.owl.model.OWLOntology;
+import org.semanticweb.owl.model.OWLEntity;
+import org.semanticweb.owl.model.OWLException;
+
+import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.AlignmentVisitor;
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.Cell;
+import org.semanticweb.owl.align.Relation;
+
+/**
+ * Renders an alignment as a SWRL rule set interpreting
+ *.data of the first ontology into the second one.
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+
+public class SWRLRendererVisitor implements AlignmentVisitor
+{
+    PrintStream writer = null;
+    Alignment alignment = null;
+    Cell cell = null;
+
+    public SWRLRendererVisitor( PrintStream writer ){
+	this.writer = writer;
+    }
+
+    public void visit( Alignment align ) throws AlignmentException {
+	alignment = align;
+	writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+	writer.println("<swrlx:Ontology swrlx:name=\"generatedAl\"");
+	writer.println("                xmlns:swrlx=\"http://www.daml.org/2003/11/swrl#\"");
+	writer.println("                xmlns:owlx=\"http://www.w3.org/2003/05/owl-xml\"");
+	writer.println("                xmlns:ruleml=\"http://www.ruleml.org/inspec#\">");
+	try {
+	    writer.println("  <owlx:Imports rdf:resource=\""+((OWLOntology)align.getOntology1()).getLogicalURI().toString()+"\"/>\n");
+	    for( Enumeration e = align.getElements() ; e.hasMoreElements(); ){
+		Cell c = (Cell)e.nextElement();
+		c.accept( this );
+	    }
+	} catch (OWLException e) { throw new AlignmentException("getURI problem", e); };
+	writer.println("</swrlx:Ontology>");
+    }
+
+    public void visit( Cell cell ) throws AlignmentException {
+	this.cell = cell;
+	OWLOntology onto1 = (OWLOntology)alignment.getOntology1();
+	try {
+	    URI entity1URI = ((OWLEntity)cell.getObject1()).getURI();
+	    if ( ((OWLEntity)onto1.getClass( entity1URI ) != null )
+		 || ((OWLEntity)onto1.getDataProperty( entity1URI ) != null)
+		 || ((OWLEntity)onto1.getObjectProperty( entity1URI ) != null )) { 
+		cell.getRelation().accept( this );
+	    }
+	} catch (OWLException e) { throw new AlignmentException("getURI problem", e); };
+    }
+
+    public void visit( EquivRelation rel ) throws AlignmentException {
+	// This is a very partial implementation since the code will depends
+	// on properties and classes.
+	// JE...
+	try {
+	    writer.println("  <ruleml:imp>");
+	    writer.println("    <ruleml:_body>");
+	    writer.println("      <swrlx:classAtom>");
+	    writer.println("        <swrlx:Class swrlx:name=\""+((OWLEntity)cell.getObject1()).getURI().toString()+"\"/>");
+	    writer.println("        <ruleml:var>x</ruleml:var>");
+	    writer.println("      </swrlx:classAtom>");
+	    writer.println("    </ruleml:_body>");
+	    writer.println("    <ruleml:_head>");
+	    writer.println("      <swrlx:classAtom>");
+	    writer.println("        <swrlx:Class swrlx:name=\""+((OWLEntity)cell.getObject2()).getURI().toString()+"\"/>");
+	    writer.println("        <ruleml:var>x</ruleml:var>");
+	    writer.println("      </swrlx:classAtom>");
+	    writer.println("    </ruleml:_head>");
+	    writer.println("  </ruleml:imp>\n");
+	} catch (Exception e) { throw new AlignmentException("getURI problem", e); };
+    }
+
+    public void visit( SubsumeRelation rel ){};
+    public void visit( IncompatRelation rel ){};
+
+    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.EquivRelation").isInstance(rel) ){
+		mm = this.getClass().getMethod("visit",
+					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.EquivRelation")});
+	    } else if (Class.forName("fr.inrialpes.exmo.align.impl.SubsumeRelation").isInstance(rel) ) {
+		mm = this.getClass().getMethod("visit",
+					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.SubsumeRelation")});
+	    } else if (Class.forName("fr.inrialpes.exmo.align.impl.IncompatRelation").isInstance(rel) ) {
+		mm = this.getClass().getMethod("visit",
+					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.IncompatRelation")});
+	    }
+	    if ( mm != null ) mm.invoke(this,new Object[] {rel});
+	} catch (Exception e) { throw new AlignmentException("Dispatching problem ", e); };
+    };
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/XSLTRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/XSLTRendererVisitor.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6c7ee0f78dd08bf188a0f45b73af345844c85b0
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/XSLTRendererVisitor.java
@@ -0,0 +1,135 @@
+/*
+ * $id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2003-2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package fr.inrialpes.exmo.align.impl; 
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.io.PrintStream;
+import java.io.IOException;
+
+import java.lang.reflect.Method;
+import java.net.URI;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import org.semanticweb.owl.model.OWLOntology;
+import org.semanticweb.owl.model.OWLEntity;
+import org.semanticweb.owl.model.OWLException;
+
+import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.AlignmentVisitor;
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.Cell;
+import org.semanticweb.owl.align.Relation;
+
+/**
+ * Renders an alignment as a XSLT stylesheet transforming 
+ *.data of the first ontology into the second one.
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+public class XSLTRendererVisitor implements AlignmentVisitor
+{
+    PrintStream writer = null;
+    Alignment alignment = null;
+    Cell cell = null;
+
+    public XSLTRendererVisitor( PrintStream writer ){
+	this.writer = writer;
+    }
+
+    public void visit( Alignment align ) throws AlignmentException {
+	alignment = align;
+	    writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+	    writer.println("<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\"");
+	writer.println("    xmlns:owl=\"http://www.w3.org/2002/07/owl#\"");
+	writer.println("    xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"");
+	writer.println("    xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\" ");
+	writer.println("    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema#\">\n");	
+	for( Enumeration e = align.getElements() ; e.hasMoreElements(); ){
+	    Cell c = (Cell)e.nextElement();
+	    c.accept( this );
+	}
+
+	writer.println("  <!-- Copying the root -->");
+	writer.println("  <xsl:template match=\"/\">");
+	writer.println("    <xsl:apply-templates/>");
+	writer.println("  </xsl:template>");
+	writer.println("");
+	writer.println("  <!-- Copying all elements and attributes -->");
+	writer.println("  <xsl:template match=\"*|@*|text()\">");
+	writer.println("    <xsl:copy>");
+	writer.println("      <xsl:apply-templates select=\"*|@*|text()\"/>");
+	writer.println("    </xsl:copy>");
+	writer.println("  </xsl:template>");
+	writer.println("");
+	writer.print("</xsl:stylesheet>\n");
+    }
+
+    public void visit( Cell cell ) throws AlignmentException {
+	this.cell = cell;
+	OWLOntology onto1 = (OWLOntology)alignment.getOntology1();
+	try {
+	    URI entity1URI = ((OWLEntity)cell.getObject1()).getURI();
+	    if ( ((OWLEntity)onto1.getClass( entity1URI ) != null )
+		 || ((OWLEntity)onto1.getDataProperty( entity1URI ) != null)
+		 || ((OWLEntity)onto1.getObjectProperty( entity1URI ) != null )) { 
+		cell.getRelation().accept( this );
+	    }
+	} catch (OWLException e) { throw new AlignmentException("getURI problem", e); };
+    }
+
+    public void visit( EquivRelation rel ) throws AlignmentException {
+	// The code is exactly the same for properties and classes
+	try {
+	    writer.println("  <xsl:template match=\""+((OWLEntity)cell.getObject1()).getURI().toString()+"\">");
+	    writer.println("    <xsl:element name=\""+((OWLEntity)cell.getObject2()).getURI().toString()+"\">");
+	    writer.println("      <xsl:apply-templates select=\"*|@*|text()\"/>");
+	    writer.println("    </xsl:element>");
+	    writer.println("  </xsl:template>\n");
+	} catch (OWLException e) { throw new AlignmentException("getURI problem", e); };
+    }
+
+    public void visit( SubsumeRelation rel ){};
+    public void visit( IncompatRelation rel ){};
+
+    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.EquivRelation").isInstance(rel) ){
+		mm = this.getClass().getMethod("visit",
+					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.EquivRelation")});
+	    } else if (Class.forName("fr.inrialpes.exmo.align.impl.SubsumeRelation").isInstance(rel) ) {
+		mm = this.getClass().getMethod("visit",
+					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.SubsumeRelation")});
+	    } else if (Class.forName("fr.inrialpes.exmo.align.impl.IncompatRelation").isInstance(rel) ) {
+		mm = this.getClass().getMethod("visit",
+					       new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.IncompatRelation")});
+	    }
+	    if ( mm != null ) mm.invoke(this,new Object[] {rel});
+	} catch (Exception e) { throw new AlignmentException("Dispatching problem ", e); };
+    };
+}
diff --git a/src/org/semanticweb/owl/align/AlignmentVisitor.java b/src/org/semanticweb/owl/align/AlignmentVisitor.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f8d123bb6546165f1aa3f1e8a36f0bb104751df
--- /dev/null
+++ b/src/org/semanticweb/owl/align/AlignmentVisitor.java
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package org.semanticweb.owl.align;
+
+/**
+ *
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+public interface AlignmentVisitor
+{
+    public void visit( Alignment a ) throws AlignmentException;
+    public void visit( Cell c ) throws AlignmentException;
+    public void visit( Relation r ) throws AlignmentException;
+ }
diff --git a/src/org/semanticweb/owl/align/Parameters.java b/src/org/semanticweb/owl/align/Parameters.java
new file mode 100644
index 0000000000000000000000000000000000000000..b0d8902f4ec3b1fede9874f5fe43bf8c8db566cf
--- /dev/null
+++ b/src/org/semanticweb/owl/align/Parameters.java
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2004
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+package org.semanticweb.owl.align; 
+
+import java.util.Enumeration;
+
+/**
+ * A set of parameters to be passed to an alignment or evaluation method.
+ * This interface is a minimal one: add, remove, get parameter value, get
+ * a list of available parameters as an enumeration.
+ * I does not provide any integrity checking (set and unset silently and
+ * erase the previous value is there were one).
+ * getParameter must return (null) if no corresponding parameter exist.
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$ 
+ */
+
+public interface Parameters {
+ 
+    public void setParameter(String name, Object value);
+    public void unsetParameter(String name);
+    public Object getParameter(String name);
+    public Enumeration getNames();
+
+}