diff --git a/README.AServ b/README.AServ
index 397eec741a8b2b97ddda47aee4fd8565b8176065..4f08a51c85e8dda96a32c2e1a38d053bcc4013b7 100644
--- a/README.AServ
+++ b/README.AServ
@@ -55,6 +55,6 @@ $ java -jar lib/alignsvc.jar -H
 
 The alignment server is then available through HTTP with:
 
-    	      http://localhost:8089/html/align
+    	      http://localhost:8089/html/
 
 
diff --git a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java
index 09c8f19161aa9594cabbe293d8c9b9a1692c4226..b56e8eae1d7b21a4afbbc39477c1a6f4983edbbe 100644
--- a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java
+++ b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java
@@ -20,18 +20,34 @@
 
 package fr.inrialpes.exmo.align.service;
 
+import fr.inrialpes.exmo.align.parser.AlignmentParser;
+
 import org.semanticweb.owl.align.Parameters;
+import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.AlignmentProcess;
+import org.semanticweb.owl.align.AlignmentVisitor;
+import org.semanticweb.owl.align.AlignmentException;
+
+import org.semanticweb.owl.util.OWLManager;
+import org.semanticweb.owl.model.OWLOntology;
+import org.semanticweb.owl.model.OWLException;
+import org.semanticweb.owl.io.owl_rdf.OWLRDFParser;
+import org.semanticweb.owl.io.owl_rdf.OWLRDFErrorHandler;
+import org.semanticweb.owl.io.ParserException;
+
+import org.xml.sax.SAXException;
+import java.sql.SQLException;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.io.BufferedWriter;
+import java.io.OutputStreamWriter;
+import java.net.URI;
 import java.util.Hashtable;
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Enumeration;
-
-import java.sql.SQLException;
-
-import fr.inrialpes.exmo.align.service.StoreRDFFormat;
-import fr.inrialpes.exmo.align.service.DBService;
-import fr.inrialpes.exmo.align.service.CacheImpl;
+import java.util.Iterator;
 
 public class AServProtocolManager {
 
@@ -40,6 +56,17 @@ public class AServProtocolManager {
     Hashtable services = null; // name -> service
     CacheImpl alignmentCache = null;
 
+    Hashtable loadedOntologies = null;
+    OWLRDFErrorHandler handler = null;
+
+    // This should be stored somewhere
+    int localId = 0; // surrogate of emitted messages
+    String myId = null; // id of this alignment server
+
+    /*********************************************************************
+     * Initialization and constructor
+     *********************************************************************/
+
     public AServProtocolManager () {
 	renderers = new Hashtable();
 	methods = new Hashtable();
@@ -49,6 +76,8 @@ public class AServProtocolManager {
     public void init( DBService connection, Parameters p ) throws SQLException {
 	alignmentCache = new CacheImpl( connection );
 	alignmentCache.init();
+	// dummy string
+	myId = "localhost://alignserv";
 	// This is ugly but it seems that Java does not provides the 
 	// opportunity to find the loaded implementations of an interface!
 	// Read all these parameters from the database
@@ -63,15 +92,33 @@ public class AServProtocolManager {
 	renderers.put("SKOS","fr.inrialpes.exmo.align.impl.renderer.SKOSRendererVisitor");
 	renderers.put("SWRL","fr.inrialpes.exmo.align.impl.renderer.SWRLRendererVisitor");
 	renderers.put("XSLT","fr.inrialpes.exmo.align.impl.renderer.XSLTRendererVisitor");
+	loadedOntologies = new Hashtable();
+	handler = new OWLRDFErrorHandler() {
+		public void owlFullConstruct(int code, String message)
+		    throws SAXException {
+		}
+		public void owlFullConstruct(int code, String message, Object o)
+		    throws SAXException {
+		}
+		public void error(String message) throws SAXException {
+		    throw new SAXException(message.toString());
+		}
+		public void warning(String message) throws SAXException {
+		    System.err.println("WARNING: " + message);
+		}
+	    };
     }
 
     public void close() {
     }
 
-    // ==================================================
-    // Protocol primitives
-    // ==================================================
+    private int newId() { return localId++; }
+
+    /*********************************************************************
+     * Extra administration primitives
+     *********************************************************************/
 
+    // DONE BUT UNSATISFACTORY
     public Set listmethods (){
 	Set result = new HashSet();
 	for (Enumeration e = methods.elements() ; e.hasMoreElements() ;) {
@@ -80,6 +127,7 @@ public class AServProtocolManager {
 	return result;
     }
 
+    // DONE BUT UNSATISFACTORY
     public Set listrenderers(){
 	Set result = new HashSet();
 	for (Enumeration e = renderers.elements() ; e.hasMoreElements() ;) {
@@ -88,75 +136,320 @@ public class AServProtocolManager {
 	return result;
     }
 
+    // DONE
+    public Enumeration alignments(){
+	return alignmentCache.listAlignments();
+    }
+
+    /*********************************************************************
+     * Basic protocol primitives
+     *********************************************************************/
+
+    // DONE
+    // Implements: store (different from store below)
+    public Message load( Message mess ){
+	Parameters params = mess.getParameters();
+	// load the alignment
+	String name = (String)params.getParameter("url");
+	System.err.println("Preparing for "+name);
+	Alignment init = null;
+	try {
+	    //if (debug > 0) System.err.println(" Parsing init");
+	    AlignmentParser aparser = new AlignmentParser(0);
+	    init = aparser.parse( name, loadedOntologies );
+	    //if (debug > 0) System.err.println(" Init parsed");
+	} catch (Exception e) {
+	    return new UnreachableAlignment(newId(),mess,myId,mess.getSender(),name,(Parameters)null);
+	}
+	System.err.println("For recording");
+	// register it
+	String id = alignmentCache.recordNewAlignment( init, true );
+	System.err.println("For returning");
+	return new AlignmentId(newId(),mess,myId,mess.getSender(),id,(Parameters)null);
+    }
+
+    // DONE
+    // Implements: align
     public Message align(Message mess){
+	Parameters params = mess.getParameters();
+	String method = (String)params.getParameter("method");
+	// find and access o, o'
+	URI uri1 = null;
+	URI uri2 = null;
+	try {
+	    uri1 = new URI((String)params.getParameter("onto1"));
+	    uri2 = new URI((String)params.getParameter("onto2"));
+	} catch (Exception e) {}; //done below
+	OWLOntology onto1 = reachable( uri1 );
+	OWLOntology onto2 = reachable( uri2 );
+	if ( onto1 == null ){
+	    // Unreachable
+	    return new UnreachableOntology(newId(),mess,myId,mess.getSender(),(String)params.getParameter("onto1"),(Parameters)null);
+	} else if ( onto2 == null ){
+	    return new UnreachableOntology(newId(),mess,myId,mess.getSender(),(String)params.getParameter("onto2"),(Parameters)null);
+	} else {
+	    // find n
+	    Alignment init = null;
+	    if ( params.getParameter("init") != null && !params.getParameter("init").equals("") ) {
+		try {
+		    //if (debug > 0) System.err.println(" Retrieving init");
+		    //AlignmentParser aparser = new AlignmentParser(0);
+		    //init = aparser.parse((String)params.getParameter("init"), loadedOntologies);
+		    try {
+			init = alignmentCache.getAlignment( (String)params.getParameter("init") );
+		    } catch (Exception e) {
+			return new UnknownAlignment(newId(),mess,myId,mess.getSender(),(String)params.getParameter("init"),(Parameters)null);
+		    }
+		    // Not really useful
+		    onto1 = (OWLOntology)init.getOntology1();
+		    onto2 = (OWLOntology)init.getOntology2();
+		    //if (debug > 0) System.err.println(" Init retrieved");
+		} catch (Exception e) {
+		    return new UnknownAlignment(newId(),mess,myId,mess.getSender(),(String)params.getParameter("init"),(Parameters)null);
+		}
+	    }
+	    // Try to retrieve first
+	    Set alignments = null;
+	    try {
+		alignments = alignmentCache.getAlignments( onto1.getLogicalURI(), onto2.getLogicalURI() );
+	    } catch (OWLException e) {
+		// Unexpected OWLException!
+	    }
+	    String id = null;
+	    if ( alignments != null ) {
+		for ( Iterator it = alignments.iterator(); it.hasNext() && (id == null); ){
+		    Alignment al = ((Alignment)it.next());
+		    if ( al.getExtension( "method" ).equals(method) )
+			id = al.getExtension( "id" );
+		}
+	    }
+	    // Otherwise compute
+	    if ( id == null ){
+		// Create alignment object
+		try {
+		    Object[] mparams = {(Object)onto1, (Object)onto2 };
+		    if ( method == null )
+			method = "fr.inrialpes.exmo.align.impl.method.StringDistAlignment";
+		    Class alignmentClass = Class.forName(method);
+		    Class oClass = Class.forName("org.semanticweb.owl.model.OWLOntology");
+		    Class[] cparams = { oClass, oClass };
+		    java.lang.reflect.Constructor alignmentConstructor = alignmentClass.getConstructor(cparams);
+		    AlignmentProcess result = (AlignmentProcess)alignmentConstructor.newInstance(mparams);
+		    result.setFile1(uri1);
+		    result.setFile2(uri2);
+		    // call alignment algorithm
+		    long time = System.currentTimeMillis();
+		    result.align(init, params); // add opts
+		    long newTime = System.currentTimeMillis();
+		    result.setExtension( "time", Long.toString(newTime - time) );
+		    // ask to store A'
+		    id = alignmentCache.recordNewAlignment( result, true );
+		} catch (Exception e) {
+		    return new NonConformParameters(newId(),mess,myId,mess.getSender(),"nonconform/params/",(Parameters)null);
+		}
+	    }
+	    // JE: In non OWL-API-based version, here unload ontologies
+	    // return A' surrogate
+	    return new AlignmentId(newId(),mess,myId,mess.getSender(),id,(Parameters)null);
+	}
+    }
+
+    // DONE
+    // Implements: query-aligned
+    public Message existingAlignments( Message mess ){
+	Parameters params = mess.getParameters();
+	// find and access o, o'
+	URI uri1 = null;
+	URI uri2 = null;
+	try {
+	    uri1 = new URI((String)params.getParameter("onto1"));
+	    uri2 = new URI((String)params.getParameter("onto2"));
+	} catch (Exception e) {
+	    return new ErrorMsg(newId(),mess,myId,mess.getSender(),"MalformedURI problem",(Parameters)null);
+	}; //done below
+	// This useless and is done only for launching the error
+	//OWLOntology onto1 = reachable( uri1 );
+	//OWLOntology onto2 = reachable( uri2 );
+	//if ( onto1 == null ){
+	    // Unreachable
+	//    return new UnreachableOntology(newId(),mess,myId,mess.getSender(),(String)params.getParameter("onto1"),(Parameters)null);
+	//} else if ( onto2 == null ){
+	//    return new UnreachableOntology(newId(),mess,myId,mess.getSender(),(String)params.getParameter("onto2"),(Parameters)null);
+	//} else {
+	//    try {
+		// find it
+	//	Set alignments = alignmentCache.getAlignments( onto1.getLogicalURI(), onto2.getLogicalURI() );
+		Set alignments = alignmentCache.getAlignments( uri1, uri2 );
+		String msg = "";
+		for( Iterator it = alignments.iterator(); it.hasNext(); ){
+		    //ids.put( ((Alignment)it.next()).getExtension( "id" ) );
+		    msg += ((Alignment)it.next()).getExtension( "id" );
+		    msg += " ";
+		}
+		return new AlignmentIds(newId(),mess,myId,mess.getSender(),msg,(Parameters)null);
+		//    } catch (Exception e) { // URI problems in gLU
+		//e.printStackTrace();
+		//return new ErrorMsg(newId(),mess,myId,mess.getSender(),"getlogicalURI problem on the ontologies",(Parameters)null);
+		//}
+		//}
+    }
 
-    //\prul{align-success}
-    //{a - request ( align (O, O', n, P)) \rightarrow S}
-	//{\langle O, O', A\rangle \Leftarrow Retrieve(n)\\A'\Leftarrow Align (O,O',A,P)\\ n'\Leftarrow Store(O, O', A')\\ S - inform (n') \rightarrow a}
-	//{\begin{matrix}\neg Find(O,O',n,P) \wedge\\ reachable(O)\wedge reachable(O')\wedge\\ conform(P) \wedge Retrieve(n)\not=\emptyset\end{matrix}}
+    // ABSOLUTELY NOT IMPLEMENTED
+    // Implements: find
+    public Message find(Message mess){
+    //\prul{search-success}{a - request ( find (O, T) ) \rightarrow S}{O' \Leftarrow Match(O,T)\\S - inform (O') \rightarrow a}{reachable(O)\wedge Match(O,T)\not=\emptyset}
 
-//\prul{align-library}
-//{a - request ( align (O, O', n, P)) \rightarrow S}
-    //{n' \Leftarrow Find(O,O',n,O)\\ S - inform (n') \rightarrow a}
-    //{Find(O,O',n,O)\not= \emptyset}
+    //\prul{search-void}{a - request ( find (O, T) ) \rightarrow S}{S - failure (nomatch) \rightarrow a}{reachable(O)\wedge Match(O,T)=\emptyset}
 
-    //\prul{align-unreachable}{a - request ( align (O, O', n, P)) \rightarrow S}{S - failure ( unreachable  ( O ) ) \rightarrow a}{\neg reachable(O)}
+    //\prul{search-unreachable}{a - request ( find (O, T) ) \rightarrow S}{S - failure ( unreachable (O) ) \rightarrow a}{\neg reachable(O)}
+	return new OntologyURI(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
+    }
 
-    //\prul{align-unreachable}{a - request ( align (O, O', n, P)) \rightarrow S}{S - failure ( unreachable  ( O' ) ) \rightarrow a}{\neg reachable(O')}
+    // Implements: translate
+    public Message translate(Message mess){
 
-    //\prul{align-unknown}{a - request ( align (O, O', n, P)) \rightarrow S}{ S -  failure (unknown(n)) \rightarrow a }{\neg Retrieve(n)}
+//\prul{translate-success}{a - request ( translate ( M, n)) \rightarrow S}{\langle O, O', A\rangle \Leftarrow Retrieve(n)\\m'\Leftarrow Translate(m,A)\\S - inform ( m' ) \rightarrow a}{Retrieve(n)\not=\emptyset}
 
-    //\prul{align-nonconform}{a - request ( align (O, O', n, P)) \rightarrow S}{S - failure ( nonconform  ( P ) ) \rightarrow a}{\neg conform(P)}
-	return new Message(mess.getId(),mess,mess.getSender(),"dummy//",(Parameters)null);
+//\prul{translate-unknown}{a - request ( translate ( M, n)) \rightarrow S}{S - failure ( unknown (n) )  \rightarrow a}{Retrieve(n)=\emptyset}
+	return new TranslatedMessage(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
     }
 
-    public Message find(Message mess){
+    // DONE
+    // Implements: render
+    public Message render( Message mess ){
+	Parameters params = mess.getParameters();
+	// Retrieve the alignment
+	String id = (String)params.getParameter("id");
+	Alignment al = null;
+	try {
+	    al = alignmentCache.getAlignment( id );
+	} catch (Exception e) {
+	    return new UnknownAlignment(newId(),mess,myId,mess.getSender(),id,(Parameters)null);
+	}
+	// Render it
+	String method = (String)params.getParameter("method");
+	AlignmentVisitor renderer = null;
+	// Redirect the output in a String
+	ByteArrayOutputStream result = new ByteArrayOutputStream(); 
+	PrintWriter writer = null;
+	try { 
+	    writer = new PrintWriter (
+			  new BufferedWriter(
+			       new OutputStreamWriter( result, "UTF-8" )), true);
+	    try {
+		Object[] mparams = {(Object) writer };
+		java.lang.reflect.Constructor[] rendererConstructors =
+		    Class.forName(method).getConstructors();
+		renderer =
+		    (AlignmentVisitor) rendererConstructors[0].newInstance(mparams);
+	    } catch (Exception ex) {
+		// should return the message
+		return new UnknownMethod(newId(),mess,myId,mess.getSender(),method,(Parameters)null);
+	    }
+	    al.render(renderer);
+	    writer.flush();
+	    writer.close();
+	} catch (Exception e) {
+	    // These are exceptions related to I/O
+	    writer.flush();
+	    writer.close();
+	    System.err.println(result.toString());
+	    e.printStackTrace();
+	}
 
-    //\prul{search-success}{a - request ( find (O, T) ) \rightarrow S}{O' \Leftarrow Match(O,T)\\S - inform (O') \rightarrow a}{reachable(O)\wedge Match(O,T)\not=\emptyset}
+	return new RenderedAlignment(newId(),mess,myId,mess.getSender(),result.toString(),(Parameters)null);
+    }
 
-    //\prul{search-void}{a - request ( find (O, T) ) \rightarrow S}{S - failure (nomatch) \rightarrow a}{reachable(O)\wedge Match(O,T)=\emptyset}
+    /*********************************************************************
+     * Extended protocol primitives
+     *********************************************************************/
+
+    // DONE
+    // Implementation specific
+    public Message store( Message mess ){
+	String id = mess.getContent();
+	try {
+	    alignmentCache.storeAlignment( id );
+	} catch (Exception e) {
+	    return new UnknownAlignment(newId(),mess,myId,mess.getSender(),id,(Parameters)null);
+	}
+	return new AlignmentId(newId(),mess,myId,mess.getSender(),id,(Parameters)null);
+    }
 
-    //\prul{search-unreachable}{a - request ( find (O, T) ) \rightarrow S}{S - failure ( unreachable (O) ) \rightarrow a}{\neg reachable(O)}
-	return new Message(mess.getId(),mess,mess.getSender(),"dummy//",(Parameters)null);
+    public Message getmetadata(Message mess){
+
+    //\prul{get-processor-success}{a - request ( metadata ( n )) \rightarrow S}{\langle O, O', A\rangle \Leftarrow Retrieve(n)\\P\Leftarrow Metadata(A)\\S - inform ( P~language:~l ) \rightarrow a}{Retrieve(n)\not=\emptyset}
+
+    //\prul{get-processor-unknown}{a - request ( metadata ( n )) \rightarrow S}{S - failure ( unknown (n) ) \rightarrow a}{Retrieve(n)=\emptyset}
+
+	return new RenderedAlignment(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
     }
 
-    public Message isAligned(Message mess){
-	String o1 = null;
-	String o2 = null;
-	
-	if ( !reachable( o1 ) ){
-	    return new Message(mess.getId(),mess,mess.getSender(),"unreachable//"+o1,(Parameters)null);
-	} else if ( !reachable( o2 ) ){
-	    return new Message(mess.getId(),mess,mess.getSender(),"unreachable//"+o2,(Parameters)null);
-	} else {
-	    //List als = getAligned( o1, o2 );
-	    //if ( als != null ){
-	    //	return new Message(mess.getId(),mess,mess.getSender(),"true",(Parameters)null);
-	    //} else {
-		return new Message(mess.getId(),mess,mess.getSender(),"nomatch",(Parameters)null);
-		//}
+    /*********************************************************************
+     * Extra alignment primitives
+     *
+     * All these primitives must create a new alignment and return its Id
+     * There is no way an alignment server could modify an alignment
+     *********************************************************************/
+
+    public Message cut( Message mess ){
+	return new AlignmentId(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
+    }
+
+    public Message harden( Message mess ){
+	return new AlignmentId(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
+    }
+
+    public Message inverse( Message mess ){
+	Parameters params = mess.getParameters();
+	// Retrieve the alignment
+	String id = (String)params.getParameter("id");
+	Alignment al = null;
+	try {
+	    al = alignmentCache.getAlignment( id );
+	} catch (Exception e) {
+	    return new UnknownAlignment(newId(),mess,myId,mess.getSender(),"unknown/Alignment/"+id,(Parameters)null);
+	}
+	if ( params.getParameter("id") == null ){
+	    // Copy the alignment
 	}
+	// Invert it
+	try { al.inverse(); }
+	catch (AlignmentException e) {
+	    return new ErrorMsg(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
+	}
+	return new AlignmentId(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
+    }
 
-    //\prul{query-align-unreachable}{a - query-if ( is-align ( O, O' )) \rightarrow S}{S -  failure ( unreachable(O') ) \rightarrow a}{\neg reachable(O')}
+    public Message meet( Message mess ){
+	// Retrieve alignments
+	return new AlignmentId(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
     }
 
-    public Message store(Message mess){
+    public Message join( Message mess ){
+	// Retrieve alignments
+	return new AlignmentId(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
+    }
 
-    //\prul{store-alignment}
-    //{a - request ( store (O, O', A)) \rightarrow S}
-    //{n\Leftarrow Store(O, O', A)\\ S - inform (n) \rightarrow a}
-    //{}
-	return new Message(mess.getId(),mess,mess.getSender(),"dummy//",(Parameters)null);
+    public Message compose( Message mess ){
+	// Retrieve alignments
+	return new AlignmentId(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
     }
 
+    /*********************************************************************
+     * Network of alignment server implementation
+     *********************************************************************/
+
+    // Implements: reply-with
     public Message replywith(Message mess){
 
     //\prul{redirect}{a - request ( q(x)~reply-with:~i) \rightarrow S}{
     //Q \Leftarrow Q\cup\{\langle a, i, !i', q(x), S'\rangle\}\		\
     //S - request( q( R(x) )~reply-with:~i')\rightarrow S'}{S'\in C(q)}
-	return new Message(mess.getId(),mess,mess.getSender(),"dummy//",(Parameters)null);
+	return new Message(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
     }
 
+    // Implements: reply-to
     public Message replyto(Message mess){
 
     //\prul{handle-return}{S' - inform ( y~reply-to:~i') \rightarrow S}{
@@ -167,54 +460,43 @@ public class AServProtocolManager {
     //Q \Leftarrow Q-\{\langle a, i, i', _, S'\rangle\}\	\
     //R \Leftarrow R\cup\{\langle a, !y', y, S'\rangle\}\		\
     //S - inform( R^{-1}(y)~reply-to:~i)\rightarrow a}{\langle a, i, i', _, S'\rangle \in Q, surr(y)}
-	return new Message(mess.getId(),mess,mess.getSender(),"dummy//",(Parameters)null);
+	return new Message(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
     }
 
+    // Implements: failure
     public Message failure(Message mess){
 
     //\prul{failure-return}{S' - failure ( y~reply-to:~i') \rightarrow S}{
     //Q \Leftarrow Q-\{\langle a, i, i', _, S'\rangle\}\		\
     //S - failure( R^{-1}(y)~reply-to:~i)\rightarrow a}{\langle a, i, i', _, S'\rangle \in Q}
-	return new Message(mess.getId(),mess,mess.getSender(),"dummy//",(Parameters)null);
-    }
-
-    public Message translate(Message mess){
-
-//\prul{translate-success}{a - request ( translate ( M, n)) \rightarrow S}{\langle O, O', A\rangle \Leftarrow Retrieve(n)\\m'\Leftarrow Translate(m,A)\\S - inform ( m' ) \rightarrow a}{Retrieve(n)\not=\emptyset}
-
-//\prul{translate-unknown}{a - request ( translate ( M, n)) \rightarrow S}{S - failure ( unknown (n) )  \rightarrow a}{Retrieve(n)=\emptyset}
-	return new Message(mess.getId(),mess,mess.getSender(),"dummy//",(Parameters)null);
+	return new Message(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
     }
 
-    public Message render(Message mess){
+    /*********************************************************************
+     * Utilities
+     *********************************************************************/
 
-    //\prul{get-processor-success}{a - request ( render ( n, l )) \rightarrow S}{\langle O, O', A\rangle \Leftarrow Retrieve(n)\\P\Leftarrow Render(A,l)\\S - inform ( P~language:~l ) \rightarrow a}{l\in L\wedge Retrieve(n)\not=\emptyset}
-
-    //\prul{get-processor-unknown}{a - request ( render ( n, l )) \rightarrow S}{S - failure ( unknown (n) ) \rightarrow a}{Retrieve(n)=\emptyset}
-
-    //\prul{get-processor-failure}{a - request ( render ( n, l )) \rightarrow S}{S -  failure ( unsupported ( l )) \rightarrow a}{l\not\in L}
-	return new Message(mess.getId(),mess,mess.getSender(),"dummy//",(Parameters)null);
+    public OWLOntology reachable( URI uri ){
+	try { return loadOntology( uri ); }
+	catch (Exception e) {
+	    return (OWLOntology)null;
+	}
     }
 
-    public Message getmetadata(Message mess){
-
-    //\prul{get-processor-success}{a - request ( metadata ( n )) \rightarrow S}{\langle O, O', A\rangle \Leftarrow Retrieve(n)\\P\Leftarrow Metadata(A)\\S - inform ( P~language:~l ) \rightarrow a}{Retrieve(n)\not=\emptyset}
-
-    //\prul{get-processor-unknown}{a - request ( metadata ( n )) \rightarrow S}{S - failure ( unknown (n) ) \rightarrow a}{Retrieve(n)=\emptyset}
-
-	return new Message(mess.getId(),mess,mess.getSender(),"dummy//",(Parameters)null);
+    public OWLOntology loadOntology(URI uri)
+	throws ParserException, OWLException {
+	// Test if not loaded...
+	OWLOntology parsedOnt = null;
+	OWLRDFParser parser = new OWLRDFParser();
+	parser.setOWLRDFErrorHandler(handler);
+	parser.setConnection(OWLManager.getOWLConnection());
+	parsedOnt = parser.parseOntology(uri);
+	loadedOntologies.put(uri.toString(), parsedOnt);
+	return parsedOnt;
     }
 
-    public boolean reachable( String ontology ){
-	return true;
+    // this should be done at some point...
+    private void unloadOntology( OWLOntology o ){
     }
-    /*
-    public List getAligned( String o1, String o2 ){
-	List a = (List)aligned.get( o1 );
-	// for all the aligned of o1
-	// if there are some in o2
-	// then get it
-	return a;
-	}*/
 
 }
diff --git a/src/fr/inrialpes/exmo/align/service/AlignmentId.java b/src/fr/inrialpes/exmo/align/service/AlignmentId.java
new file mode 100644
index 0000000000000000000000000000000000000000..2670b4ae17f5c572450381b0ffe8e50ebab332d3
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/service/AlignmentId.java
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2006
+ *
+ * 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.service;
+
+import org.semanticweb.owl.align.Parameters;
+
+/**
+ * Contains the messages that should be sent according to the protocol
+ */
+
+public class AlignmentId extends Success {
+
+    public AlignmentId ( int surr, Message rep, String from, String to, String cont, Parameters param ) {
+	super( surr, rep, from, to, cont, param );
+    }
+    public static String HTMLString = "Alignment ID: ";
+}
diff --git a/src/fr/inrialpes/exmo/align/service/AlignmentIds.java b/src/fr/inrialpes/exmo/align/service/AlignmentIds.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5da39380fb43cddc98fe777b491601a867a8151
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/service/AlignmentIds.java
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2006
+ *
+ * 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.service;
+
+import org.semanticweb.owl.align.Parameters;
+
+/**
+ * Contains the messages that should be sent according to the protocol
+ */
+
+public class AlignmentIds extends Success {
+
+    public AlignmentIds ( int surr, Message rep, String from, String to, String cont, Parameters param ) {
+	super( surr, rep, from, to, cont, param );
+    }
+    public static String HTMLString = "Alignment IDs: ";
+}
diff --git a/src/fr/inrialpes/exmo/align/service/AlignmentService.java b/src/fr/inrialpes/exmo/align/service/AlignmentService.java
index e74619c8893f6fca6a9c6640a5c18655d5cdd1e3..fa70361b29da093b873f664b034e574f06c0c39e 100644
--- a/src/fr/inrialpes/exmo/align/service/AlignmentService.java
+++ b/src/fr/inrialpes/exmo/align/service/AlignmentService.java
@@ -121,9 +121,9 @@ public class AlignmentService {
 	    AlignmentServiceProfile serv = (AlignmentServiceProfile)constructor.newInstance( null );
 	    try {
 		serv.init( params, manager );
-		if ( debug > 0 ) System.err.println(name+" launched on ");
+		if ( debug > 0 ) System.err.println(name+" launched on http://localhost:"+params.getParameter( "http" )+"/html/");
 	    } catch ( AServException ex ) {
-		System.err.println( "Couldn't start "+name+" server:\n");
+		System.err.println( "Couldn't start "+name+" server on http://localhost:"+params.getParameter( "http" )+"/html/:\n");
 		ex.printStackTrace();
 	    }
 	    services.put( name, serv );
diff --git a/src/fr/inrialpes/exmo/align/service/Cache.java b/src/fr/inrialpes/exmo/align/service/Cache.java
index 1587a5ff8e159cb4f1a0f9b0bc784a5fcab6016b..c251ba4149cd28d6892a0b198b2e0af31775a4f8 100644
--- a/src/fr/inrialpes/exmo/align/service/Cache.java
+++ b/src/fr/inrialpes/exmo/align/service/Cache.java
@@ -27,10 +27,10 @@ import org.semanticweb.owl.align.Alignment;
 
 public interface Cache {
     void init() throws SQLException;
-    Alignment getMetadata( String id );
+    Alignment getMetadata( String id ) throws Exception;
     Alignment getAlignment( String id ) throws Exception;
     Set getAlignments( URI uri );
     Set getAlignments( URI uri1, URI uri2 );
-    void recordAlignment( Alignment alignment, boolean force );
+    String recordNewAlignment( Alignment alignment, boolean force );
     void storeAlignment( String id ) throws Exception;
 }
diff --git a/src/fr/inrialpes/exmo/align/service/CacheImpl.java b/src/fr/inrialpes/exmo/align/service/CacheImpl.java
index 82c403a1a831b2c03acefa866e309cd1a1edd6e0..55242eaa6af5c5480d9814cdfa002663c43be3b8 100644
--- a/src/fr/inrialpes/exmo/align/service/CacheImpl.java
+++ b/src/fr/inrialpes/exmo/align/service/CacheImpl.java
@@ -2,6 +2,7 @@
  * $Id$
  *
  * Copyright (C) XX, 2006
+ * Copyright (C) INRIA Rhône-Alpes, 2006
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -21,6 +22,7 @@
 package fr.inrialpes.exmo.align.service;
 
 import java.util.Enumeration;
+import java.util.Iterator;
 import java.util.Hashtable;
 import java.util.Vector;
 import java.util.Set;
@@ -58,6 +60,7 @@ import org.semanticweb.owl.align.Cell;
  * It stores the alignment when requested
  * It 
  */
+
 public class CacheImpl implements Cache {
     Hashtable alignmentTable = null;
     Hashtable ontologyTable = null;
@@ -96,6 +99,16 @@ public class CacheImpl implements Cache {
      * loads the alignment descriptions from the database and put them in the
      * alignmentTable hashtable
      * index them under the ontology URIs
+     *
+     * Beware, the Alignment API has two attributes:
+     * onto1 is the OWLOntology object
+     * uri1 is the URI object from which loading the ontologies
+     * In the database we store:
+     * owlontology1 the URI string of the ontology
+     * file1 the URI string from which loading the ontologies
+     * uri1 which should be the same as the last one...
+     * Since alignments are indexed by the URI of the ontologies, we use
+     * the "ouri1" temporary extension to contain this URI.
      */
     private void loadAlignments( boolean force ) throws SQLException {
 	String query = null;
@@ -107,11 +120,9 @@ public class CacheImpl implements Cache {
 	    // Retrieve the alignment ids
 	    query = "select id " + "from alignment";
 	    rs = (ResultSet) st.executeQuery(query);
-	    //System.err.println("1234");
 	    while(rs.next()) {
 		id = rs.getString("id");
 		idInfo.add(id);	
-		//System.err.println(id);
 	    }
 	    
 	    // For each alignment id store metadata
@@ -123,6 +134,10 @@ public class CacheImpl implements Cache {
 	}
     }
 
+    protected Enumeration listAlignments() {
+	return alignmentTable.elements();
+    }
+
     /**
      * loads the description of alignments from the database and set them
      * in an alignment object
@@ -136,29 +151,34 @@ public class CacheImpl implements Cache {
 		
 	try {
 	    // Get basic ontology metadata
-	    query = "select * "+"from alignment "+"where id = " + id;
+	    query = "select * from alignment where id = '" + id  +"'";
 	    rs = (ResultSet) st.executeQuery(query);
 	    while(rs.next()) {
-		result.setFile1(new URI(rs.getString("uri1"))); 
-		result.setFile2(new URI(rs.getString("uri2"))); 
+		// Either uri1 or file1
+		result.setFile1( new URI(rs.getString("uri1")) ); 
+		result.setFile2( new URI(rs.getString("uri2")) );
+		result.setExtension( "ouri1", rs.getString("owlontology1") );
+		result.setExtension( "ouri2", rs.getString("owlontology2") );
 		result.setLevel(rs.getString("level"));
 		result.setType(rs.getString("type"));	
 	    }
 
 	    // Get extension metadata
-	    query = "select * "+"from extension "+"where id = " + id;
+	    query = "select * from extension where id = '" + id + "'";
 	    rs = (ResultSet) st.executeQuery(query);
 	    while(rs.next()) {
 		tag = rs.getString("tag");
 		method = rs.getString("method");
 		result.setExtension(tag, method);
 	    }
-	} catch (Exception e) {
-	    System.err.println("No problem");
-	    System.err.println(e.toString());
+	} catch (Exception e) { // URI exception that should not occur
+	    System.err.println("Unlikely URI exception!");
+	    e.printStackTrace();
 	    return null;
 	}
-	result.setExtension("fr.inrialpes.exmo.align.service.stored", "DATE");
+	// should be there
+	//result.setExtension("fr.inrialpes.exmo.align.service.stored", "DATE");
+	// not yet cached
 	result.setExtension("fr.inrialpes.exmo.align.service.cached", "");
 	return result;
     }
@@ -185,19 +205,20 @@ public class CacheImpl implements Cache {
 	o1 = loadOntology(result.getFile1());
 	o2 = loadOntology(result.getFile2());
 	result.setOntology1(o1);
-	result.setOntology1(o2);
+	result.setOntology2(o2);
 	
 	// Get extension metadata
-	query = "select * "+"from extension "+"where id = " + id;
-	rs = (ResultSet) st.executeQuery(query);
-	while(rs.next()) {
-	    tag = rs.getString("tag");
-	    method = rs.getString("method");
-	    result.setExtension(tag, method);
-	}
+	// JE: this has been done already by getDescription (in all cases)
+	//query = "select * from extension where id = '" + id + "'";
+	//rs = (ResultSet) st.executeQuery(query);
+	//while(rs.next()) {
+	//    tag = rs.getString("tag");
+	//    method = rs.getString("method");
+	//    result.setExtension(tag, method);
+	//}
 	
 	// Get cells
-	query = "select * "+"from cell "+"where id = " + id;
+	query = "select * from cell where id = '" + id + "'";
 	rs = (ResultSet) st.executeQuery(query);
 	while(rs.next()) {
 	    ent1 = (OWLEntity) o1.getClass(new URI(rs.getString("uri1")));
@@ -207,41 +228,40 @@ public class CacheImpl implements Cache {
 	    cell.setId(rs.getString("cell_id"));
 	    cell.setSemantics(rs.getString("semantics"));
 	}
-	result.setExtension("fr.inrialpes.exmo.align.service.stored", "DATE");
-	// Put the date here
-	result.setExtension("fr.inrialpes.exmo.align.service.cached", "DATE");
+	// It is here
+	//result.setExtension("fr.inrialpes.exmo.align.service.stored", "DATE");
+	// reset
+	resetCacheStamp(result);
 
 	return result;
     }
 
     private String generateAlignmentId() {
 	// Generate an id based on a URI prefix + Date + random number
-    Date date;
-    String id;
-    date = new Date();
-    id = "http://blavlacestmoi" + date.getTime() + randomNum();
+	Date date;
+	String id;
+	date = new Date();
+	id = "http://localhost:8089/" + date.getTime() + "/" + randomNum();
 	return id;
     }
     
     private int randomNum() {
-    Random rand = new Random(System.currentTimeMillis());
-    return Math.abs(rand.nextInt(1000)); 
+	Random rand = new Random(System.currentTimeMillis());
+	return Math.abs(rand.nextInt(1000)); 
     }
 
     //**********************************************************************
     /**
      * retrieve alignment metadata from id
+     * This is more difficult because we return the alignment we have 
+     * disreagarding if it is complete o only metadata
      */
-    public Alignment getMetadata( String id ) {
-	Alignment result = null;		
-//	String query = null;
-	
-	result = (Alignment)alignmentTable.get( id );
+    public Alignment getMetadata( String id ) throws Exception {
+	Alignment result = (Alignment)alignmentTable.get( id );
 	
-// Raise an exception if no result (by Seungkeun)
-	if(result == null) {
-		System.out.println("Metadata Loading Error in CacheImpl.getMetadata");
-	}		
+	if ( result == null )
+	    throw new Exception("getMetadata: Cannot find alignment");
+
 	return result;
     }
 	
@@ -249,18 +269,16 @@ public class CacheImpl implements Cache {
      * retrieve full alignment from id (and cache it)
      */
     public Alignment getAlignment( String id ) throws Exception {
-	Alignment result = null;		
-//	String query = null;
-	
-	result = (Alignment)alignmentTable.get( id );
+	Alignment result = (Alignment)alignmentTable.get( id );
 	
-//	 Raise an exception if no result
-	if(result == null) { 
-		System.out.println("Metadata Loading Error in CacheImpl.getMetadata");
-	}		
-	else if ( result.getExtension("fr.inrialpes.exmo.align.service.cached") == "" && result.getExtension("fr.inrialpes.exmo.align.service.stored") != "") {
+	if ( result == null )
+	    throw new Exception("getAlignment: Cannot find alignment");
+
+	// If not cached, retrieve it now
+	if ( result.getExtension("fr.inrialpes.exmo.align.service.cached") == "" 
+	     && result.getExtension("fr.inrialpes.exmo.align.service.stored") != "") {
 	    retrieveAlignment( id, result );
-	}	
+	}
 	
 	return result;
     }
@@ -271,37 +289,80 @@ public class CacheImpl implements Cache {
     }
 
     public Set getAlignments( URI uri1, URI uri2 ) {
-	// Crete the set and compare
-	return (Set)ontologyTable.get( uri1 );
+	// Create the set and compare
+	Set result = new HashSet();
+	Set potentials = (Set)ontologyTable.get( uri1 );
+	if ( potentials != null ) {
+	    for( Iterator it = potentials.iterator(); it.hasNext(); ) {
+		Alignment al = (Alignment)it.next();
+		// This is not the best because URI are not resolved here...
+		if ( al.getExtension("ouri2").equals( uri2.toString() ) ) result.add( al );
+	    }
+	}
+	return result;
     }
 
     /**
      * records newly created alignment
      */
-    public void recordAlignment( Alignment alignment, boolean force ){
-	recordAlignment( generateAlignmentId(), alignment, force );
+    public String recordNewAlignment( Alignment alignment, boolean force ){
+	return recordNewAlignment( generateAlignmentId(), alignment, force );
     }
 
     /**
      * records alignment identified by id
      */
-    public void recordAlignment( String id, Alignment alignment, boolean force ){
-	if ( force || alignmentTable.get( id ) == null ) {
-	    Set s1 = (Set)ontologyTable.get( alignment.getFile1() );
-	    if ( s1 == null ) {
-		s1 = new HashSet();
-		ontologyTable.put( alignment.getFile1(), s1 );
-	    }
-	    s1.add( alignment );
-	    Set s2 = (Set)ontologyTable.get( alignment.getFile2() );
-	    if ( s2 == null ) {
-		s2 = new HashSet();
-		ontologyTable.put( alignment.getFile1(), s2 );
+    public String recordNewAlignment( String id, Alignment alignment, boolean force ){
+	// Set the Ontology URIs
+	try {
+	    alignment.setExtension("ouri1", ((OWLOntology)alignment.getOntology1()).getLogicalURI().toString());
+	    alignment.setExtension("ouri2", ((OWLOntology)alignment.getOntology2()).getLogicalURI().toString());
+	} catch (OWLException e) {
+	    System.err.println("Unexpected OWL Exception");
+	    e.printStackTrace();
+	}
+	// Index
+	recordAlignment( id, alignment, force );
+	// Not yet stored
+	alignment.setExtension("fr.inrialpes.exmo.align.service.stored", "");
+	// Cached now
+	resetCacheStamp(alignment);
+	return id;
+    }
+
+    /**
+     * records alignment identified by id
+     */
+    public String recordAlignment( String id, Alignment alignment, boolean force ){
+	// record the Id!
+	if ( alignment.getExtension("id") == null )
+	    alignment.setExtension( "id", id );
+	// Store it
+	try {
+	    URI ouri1 = new URI( alignment.getExtension("ouri1") );
+	    URI ouri2 = new URI( alignment.getExtension("ouri2") );
+	    if ( force || alignmentTable.get( id ) == null ) {
+		Set s1 = (Set)ontologyTable.get( ouri1 );
+		if ( s1 == null ) {
+		    s1 = new HashSet();
+		    ontologyTable.put( ouri1, s1 );
+		}
+		s1.add( alignment );
+		Set s2 = (Set)ontologyTable.get( ouri2 );
+		if ( s2 == null ) {
+		    s2 = new HashSet();
+		    ontologyTable.put( ouri2, s2 );
+		}
+		s2.add( alignment );
+		alignmentTable.put( id, alignment );
 	    }
-	    s2.add( alignment );
-	    alignmentTable.put( id, alignment );
+	    return id;
+	} catch (Exception e) {
+	    System.err.println("Unlikely URI exception!");
+	    e.printStackTrace();
+	    return (String)null;
 	}
-    }		
+    }
 
     //**********************************************************************
     public void storeAlignment( String id ) throws Exception {
@@ -310,12 +371,23 @@ public class CacheImpl implements Cache {
 
 	alignment = getAlignment( id );
 
+	// We store stored date
+	alignment.setExtension("fr.inrialpes.exmo.align.service.stored", new Date().toString());
+	// We empty cached date
+	alignment.setExtension("fr.inrialpes.exmo.align.service.cached", "");
+
 	try {
-	    OWLOntology O1 = (OWLOntology)alignment.getOntology1();
-	    OWLOntology O2 = (OWLOntology)alignment.getOntology2();
-	    String s_O1 = O1.getLogicalURI().toString();
-	    String s_O2 = O2.getLogicalURI().toString();
+	    // owlontology attribute
+	    // JE: This cannot work if the ontology is not loaded!
+	    // which should not be the case but who knows?
+	    //OWLOntology O1 = (OWLOntology)alignment.getOntology1();
+	    //OWLOntology O2 = (OWLOntology)alignment.getOntology2();
+	    //String s_O1 = O1.getLogicalURI().toString();
+	    //String s_O2 = O2.getLogicalURI().toString();
+	    String s_O1 = alignment.getExtension("ouri1");
+	    String s_O2 = alignment.getExtension("ouri2");
 	    
+	    // file attribute
 	    String s_File1 = null;
 	    String s_File2 = null;
 	    if (alignment.getFile1() != null) 
@@ -323,22 +395,25 @@ public class CacheImpl implements Cache {
 	    if (alignment.getFile2() != null) 
 		s_File2 = alignment.getFile2().toString();
 	    
-	    String s_uri1 = O1.getPhysicalURI().toString();
-	    String s_uri2 = O2.getPhysicalURI().toString();
+	    // uri attribute
+	    // JE: This cannot work if the ontology is not loaded!
+	    // which should not be the case but who knows?
+	    String s_uri1 = ((OWLOntology)alignment.getOntology1()).getPhysicalURI().toString();
+	    String s_uri2 = ((OWLOntology)alignment.getOntology2()).getPhysicalURI().toString();
 	    
 	    String type = alignment.getType();
 	    String level = alignment.getLevel();
 			
 	    query = "insert into alignment " + 
 		"(id, owlontology1, owlontology2, type, level, file1, file2, uri1, uri2) " +
-		"values (" + id + ",'" +  s_O1 + "','" + s_O2 + "','" + type + "','" + level + "','" + s_File1 + "','" + s_File2 + "','" + s_uri1 + "','" + s_uri2 + "')";
+		"values ('" + id + "','" +  s_O1 + "','" + s_O2 + "','" + type + "','" + level + "','" + s_File1 + "','" + s_File2 + "','" + s_uri1 + "','" + s_uri2 + "')";
 	    st.executeUpdate(query);
 	    for( Enumeration e = alignment.getExtensions().getNames() ; e.hasMoreElements() ; ){
 		String tag = (String)e.nextElement();
 		String s_method = alignment.getExtension(tag);
 		query = "insert into extension " + 
 		    "(id, tag, method) " +
-		    "values (" + id + ",'" +  tag + "','" + s_method + "')";
+		    "values ('" + id + "','" +  tag + "','" + s_method + "')";
 		st.executeUpdate(query);
 	    }
 	    
@@ -360,7 +435,7 @@ public class CacheImpl implements Cache {
 			temp[5] =  ((BasicRelation)c.getRelation()).getRelation();	
 			query = "insert into cell " + 
 			    "(id, cell_id, uri1, uri2, measure, semantics, relation) " +
-			    "values (" + id + ",'" + temp[0] + "','" + temp[1] + "','" + temp[2] + "','" + temp[3] + "','" + temp[4] + "','" + temp[5] + "')";
+			    "values ('" + id + "','" + temp[0] + "','" + temp[1] + "','" + temp[2] + "','" + temp[3] + "','" + temp[4] + "','" + temp[5] + "')";
 			st.executeUpdate(query);
 		    }
 				    
@@ -371,10 +446,26 @@ public class CacheImpl implements Cache {
 	} catch (Exception e) {
 	    System.err.println(e.toString());
 	}
+	// we reset cached date
+	resetCacheStamp(alignment);
+    }
+
+    //**********************************************************************
+    public void resetCacheStamp( Alignment result ){
+	result.setExtension("fr.inrialpes.exmo.align.service.cached", new Date().toString() );
+    }
+
+    public void cleanUpCache() {
+	// for each alignment in the table
+	// set currentDate = Date();
+	// if ( DateFormat.parse( result.getExtension("fr.inrialpes.exmo.align.service.cached") ).before( ) ) {
+	// - for each ontology if no other alignment => unload
+	// - clean up cells
+	// }
     }
 
     //**********************************************************************
-    public static OWLOntology loadOntology( URI uri ) throws OWLException {
+    public OWLOntology loadOntology( URI uri ) throws OWLException {
 	OWLRDFParser parser = new OWLRDFParser();
 	parser.setConnection(OWLManager.getOWLConnection());
 	return parser.parseOntology(uri);
diff --git a/src/fr/inrialpes/exmo/align/service/ErrorMsg.java b/src/fr/inrialpes/exmo/align/service/ErrorMsg.java
new file mode 100644
index 0000000000000000000000000000000000000000..89d1f406ce0b8ddb11ce4ab5f614d1b0857ca094
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/service/ErrorMsg.java
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2006
+ *
+ * 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.service;
+
+import org.semanticweb.owl.align.Parameters;
+
+/**
+ * Contains the messages that should be sent according to the protocol
+ */
+
+public class ErrorMsg extends Message {
+
+    public ErrorMsg ( int surr, Message rep, String from, String to, String cont, Parameters param ) {
+	super( surr, rep, from, to, cont, param );
+    }
+    public static String HTMLString = "Generic error: ";
+}
diff --git a/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java b/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java
index 3884c7bed0ba681a63949d26ef6db1ac904ccddc..a1c1f97328698fc74681689ac91a570a71bf20a6 100644
--- a/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java
+++ b/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java
@@ -86,9 +86,6 @@ import java.lang.Integer;
 /**
  * HTMLAServProfile: an HTML provile for the Alignement server
  * It embeds an HTTP server.
- *
- * See the end of the source file for distribution license
- * (Modified BSD licence)
  */
 
 public class HTMLAServProfile implements AlignmentServiceProfile {
@@ -97,6 +94,10 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
     private int debug = 0;
     private AServProtocolManager manager;
 
+    private String myId;
+    private String serverId;
+    private int localId = 0;
+
     /**
      * Some HTTP response status codes
      */
@@ -141,10 +142,13 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 	} catch (Exception e) {
 	    throw new AServException ( "Cannot launch HTTP Server" , e );
 	}
+	myId = "LocalHTMLInterface";
+	serverId = "dummy";
+	localId = 0;
     }
 
     /**
-     * JE//: should certainly do more than that!
+     * Je//: should certainly do more than that!
      */
     public void close(){
     }
@@ -177,9 +181,23 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 	e = parms.propertyNames();
 	while ( e.hasMoreElements()) {
 	    String value = (String)e.nextElement();
-	    System.out.println( "  PRM: '" + value + "' = '" +parms.getProperty( value ) + "'" );
+	    //System.err.println( "  PRM: '" + value + "' = '" +parms.getProperty( value ) + "'" );
 	}
 	*/
+
+	// Convert parms to parameters
+	Parameters params = new BasicParameters();
+	Enumeration e = parms.propertyNames();
+	while ( e.hasMoreElements()) {
+	    String value = (String)e.nextElement();
+	    if ( debug > 1 ) System.err.println( "  PRM: '" + value + "' = '" +parms.getProperty( value ) + "'" );
+	    if ( value.startsWith( "paramn" ) ){
+		params.setParameter( parms.getProperty( value ),
+				     parms.getProperty( "paramv"+value.substring( 6 ) ) );
+	    } else if ( !value.startsWith( "paramv" ) ) {
+		params.setParameter( value, parms.getProperty( value ) );
+	    }
+	}
 	
 	int start = 0;
 	if ( uri.charAt(0) == '/' ) start = 1;
@@ -190,28 +208,53 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 	    start = end+1;
 	} else {
 	    oper = uri.substring( start );
+	    start = uri.length();
 	}
 	if ( oper.equals( "aserv" ) ){
-	    return protocolAnswer( uri, uri.substring(start), header );
+	    return protocolAnswer( uri, uri.substring(start), header, params );
 	} else if ( oper.equals( "admin" ) ){
-	    return adminAnswer( uri, uri.substring(start), header );
+	    return adminAnswer( uri, uri.substring(start), header, params );
 	} else if ( oper.equals( "html" ) ){
-	    return htmlAnswer( uri, uri.substring(start), header );
+	    return htmlAnswer( uri, uri.substring(start), header, params );
 	} else {
 	    return serveFile( uri, header, new File("."), true );
 	}
     }
 
-    // ==================================================
-    // Connection with protocol
-    public Response adminAnswer( String uri, String perf, Properties header ) {
-	System.err.println("ADMIN["+perf+"]");
+    /**
+     * HTTP administration interface
+     * Allows some limited administration of the server through HTTP
+     */
+    public Response adminAnswer( String uri, String perf, Properties header, Parameters params ) {
+	if ( debug > 0 ) System.err.println("ADMIN["+perf+"]");
 	String msg = "";
-	if ( perf.equals("shutdown") ){
-	    msg = "Server shut down";
+        if ( perf.equals("listalignments") ){
+	    msg = "<h1>Stored alignments</h1><ul compact=\"1\">";
+	    for( Enumeration e = manager.alignments(); e.hasMoreElements(); ){
+		String id = ((Alignment)e.nextElement()).getExtension("id");
+		msg += "<li><a href=\"../html/retrieve?method=fr.inrialpes.exmo.align.impl.renderer.HTMLRendererVisitor&id="+id+"\">"+id+"</a></li>";
+	    }
+	    msg += "</ul>";
+	} else if ( perf.equals("listmethods") ){
+	    msg = "<h1>Available methods</h1><ul compact=\"1\">";
+	    for( Iterator it = manager.listmethods().iterator(); it.hasNext(); ) {
+		msg += "<li>"+it.next()+"</li>";
+	    }
+	    msg += "</ul>";
+	} else if ( perf.equals("listrenderers") ) {
+	    msg = "<h1>Available renderers</h1><ul compact=\"1\">";
+	    for( Iterator it = manager.listrenderers().iterator(); it.hasNext(); ) {
+		msg += "<li>"+it.next()+"</li>";
+	    }
+	    msg += "</ul>";
+	} else if ( perf.equals("prmsqlquery") ){
+	    msg = "<h1>SQL query</h1><form action=\"sqlquery\">Provide an id: <input type=\"textarea\" name=\"id\" size=\"60\"/> (sql)<br /><small>An SQL SELECT query</small><br /><input type=\"submit\" value=\"Query\"/></form>";
 	} else if ( perf.equals("sqlquery") ){
-	    msg = perf;
-	} else if ( perf.equals("relaunch") ){
+	    msg = "Not available yet";
+	} else if ( perf.equals("shutdown") ){
+	    manager.close();
+	    msg = "Server shut down";
+	} else if ( perf.equals("prmreset") ){
 	    msg = perf;
 	} else if ( perf.equals("addservice") ){
 	    msg = perf;
@@ -221,68 +264,171 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 	    msg = perf;
 	} else if ( perf.equals("listservices") ){
 	    msg = perf;
-	} else if ( perf.equals("listmethods") ){
-	    msg = perf;
-	} else if ( perf.equals("listrenderers") ){
-	    msg = perf;
+	} else if ( perf.equals("") ) {
+	    msg = "<h1>Alignement server administration</h1><ul compact=\"1\">";
+	    msg += "<li><form action=\"listalignments\"><input type=\"submit\" value=\"Available alignments\"/></form></li>";
+	    msg += "<li><form action=\"listmethods\"><input type=\"submit\" value=\"Available methods\"/></form></li>";
+	    msg += "<li><form action=\"listrenderers\"><input type=\"submit\" value=\"Available renderers\"/></form></li>";
+	    msg += "<li><form action=\"prmsqlquery\"><input type=\"submit\" value=\"SQL Query\"/></form></li>";
+	    msg += "<li><form action=\"prmreset\"><input type=\"submit\" value=\"Reset server\"/></form></li>";
+	    msg += "<li><form action=\"shutdown\"><input type=\"submit\" value=\"shutdown\"/></form></li>";
+	    msg += "<li><form action=\"../html/\"><input type=\"submit\" value=\"User interface\"/></form></li>";
+	    msg += "</ul>";
 	} else {
 	    msg = "Cannot understand: "+perf;
 	}
-	return new Response( HTTP_OK, MIME_HTML, msg );
+	return new Response( HTTP_OK, MIME_HTML, "<html><head></head><body>"+msg+"<hr /><center><small><a href=\".\">Alignment server administration</a></small></center></body></html>" );
     }
 
-    public Response protocolAnswer( String uri, String perf, Properties header ) {
+    /**
+     * HTTP protocol implementation
+     * each call of the protocol is a direct URL
+     * and the answer is through the resulting page (RDF? SOAP? HTTP?)
+     * Not implemented yet
+     * but reserved if appears useful
+     */
+    public Response protocolAnswer( String uri, String perf, Properties header, Parameters params ) {
 	System.err.println("ASERV["+perf+"]");
 	String msg = "";
 	return new Response( HTTP_OK, MIME_HTML, msg );
 
     }
 
-    public Response htmlAnswer( String uri, String perf, Properties header ) {
-	System.err.println("HTML["+perf+"]");
-	// Parse the performative
-	// Call the manager
-	// with the performatives
-	// and the arguments
-	//manager.perf( this, args );
-	// What is the result of the 
+    /**
+     * User friendly HTTP interface
+     * uses the protocol but offers user-targeted interaction
+     */
+    public Response htmlAnswer( String uri, String perf, Properties header, Parameters params ) {
+	//System.err.println("HTML["+perf+"]");
 	String msg = "";
-	if ( perf.equals("listmethods") ){
-	    msg = "<h1>Available methods</h1><ul compact=\"1\">";
-	    for( Iterator it = manager.listmethods().iterator(); it.hasNext(); ) {
-		msg += "<li>"+it.next()+"</li>";
+	if ( perf.equals("prmstore") ) {
+	    msg = "<h1>Store an alignement</h1><form action=\"store\">Provide an id: <input type=\"text\" name=\"id\" size=\"60\"/> (id)<br /><small>The id is that of the alignment as known by the server (load it before)</small><br /><input type=\"submit\" value=\"Store\"/></form>";
+	} else if ( perf.equals("store") ) {
+	    // here should be done the switch between store and load/store
+	    String id = (String)params.getParameter("id");
+	    String url = (String)params.getParameter("url");
+	    if ( url != null && !url.equals("") ) { // Load the URL
+		Message answer = manager.load( new Message(newId(),(Message)null,myId,serverId,"", params) );
+		if ( answer instanceof ErrorMsg ) {
+		    msg = testErrorMessages( answer );
+		} else {
+		    id = answer.getContent();
+		}
 	    }
-	    msg += "</ul>";
-	} else if ( perf.equals("listrenderers") ) {
-	    msg = "<h1>Available renderers</h1><ul compact=\"1\">";
-	    for( Iterator it = manager.listrenderers().iterator(); it.hasNext(); ) {
-		msg += "<li>"+it.next()+"</li>";
+	    if ( id != null ){ // Store it
+		Message answer = manager.store( new Message(newId(),(Message)null,myId,serverId,id, params) );
+		if ( answer instanceof ErrorMsg ) {
+		    msg = testErrorMessages( answer );
+		} else {
+		    msg = "<h1>Alignment stored</h1>With id " + id;
+		}
 	    }
-	    msg += "</ul>";
-	} else if ( perf.equals("align") ) {
-	    msg ="<form action=\"getalign\">Ontology 1: <input type=\"text\" name=\"onto1\" size=\"80\"/> (uri)<br />Ontology 2: <input type=\"text\" name=\"onto2\" size=\"80\"/> (uri)<br /><input type=\"submit\" value=\"Find\"/><br />Methods: <select name=\"method\">";
+	} else if ( perf.equals("prmalign") ) {
+	    msg ="<h1>Align ontologies</h1><form action=\"align\">Ontology 1: <input type=\"text\" name=\"onto1\" size=\"80\"/> (uri)<br />Ontology 2: <input type=\"text\" name=\"onto2\" size=\"80\"/> (uri)<br /><small>These are the URL of places where to find these ontologies. They must be reachable by the server (i.e., file:// URI are acceptable if they are on the server)</small><br /><!--input type=\"submit\" name=\"action\" value=\"Find\"/><br /-->Methods: <select name=\"method\">";
 	    for( Iterator it = manager.listmethods().iterator(); it.hasNext(); ) {
 		String id = (String)it.next();
 		msg += "<option value=\""+id+"\">"+id+"</option>";
 	    }
-	    msg += "</select><br /><input type=\"submit\" value=\"Align\"/></form>";
-	} else if ( perf.equals("getalign") ) {
-	    // Depends if Find or Align
-	    msg = "<form action=\"process\">Ontology 1: <input type=\"text\" name=\"onto1\" size=\"80\"/> (uri)<br />Ontology 2: <input type=\"text\" name=\"onto2\" size=\"80\"/> (uri)<br /><input type=\"submit\" value=\"Store\"/><br />Renderers: <select name=\"method\">";
+	    msg += "</select><br />Initial alignment: <input type=\"text\" name=\"init\" size=\"60\"/> (id)<br /><small>The id is that of the alignment as known by the server (load it before)</small>";
+	    msg += "<br /><input type=\"submit\" name=\"action\" value=\"Align\"/><br />";
+	    msg += "Additional parameters:<br /><input type=\"text\" name=\"paramn1\" size=\"15\"/> = <input type=\"text\" name=\"paramv1\" size=\"65\"/><br /><input type=\"text\" name=\"paramn2\" size=\"15\"/> = <input type=\"text\" name=\"paramv2\" size=\"65\"/><br /><input type=\"text\" name=\"paramn3\" size=\"15\"/> = <input type=\"text\" name=\"paramv3\" size=\"65\"/><br /><input type=\"text\" name=\"paramn4\" size=\"15\"/> = <input type=\"text\" name=\"paramv4\" size=\"65\"/></form>";
+	} else if ( perf.equals("align") ) {
+	    Message answer = manager.align( new Message(newId(),(Message)null,myId,serverId,"", params) );
+	    if ( answer instanceof ErrorMsg ) {
+		msg = testErrorMessages( answer );
+	    } else {
+		msg = "<h1>Alignement results</h1>";
+		msg += displayAnswer( answer );
+	    }
+	} else if ( perf.equals("prmfind") ) {
+	    msg ="<h1>Find alignments between ontologies</h1><form action=\"find\">Ontology 1: <input type=\"text\" name=\"onto1\" size=\"80\"/> (uri)<br />Ontology 2: <input type=\"text\" name=\"onto2\" size=\"80\"/> (uri)<br /><small>These are the URI identifying the ontologies. Not those of places where to upload them.</small><br /><input type=\"submit\" name=\"action\" value=\"Find\"/></form>";
+	} else if ( perf.equals("find") ) {
+	    Message answer = manager.existingAlignments( new Message(newId(),(Message)null,myId,serverId,"", params) );
+	    if ( answer instanceof ErrorMsg ) {
+		msg = testErrorMessages( answer );
+	    } else {
+		msg = "<h1>Found alignments</h1>";
+		msg += displayAnswer( answer );
+	    }
+	} else if ( perf.equals("prmretrieve") ) {
+	    msg = "<h1>Retrieve alignment</h1><form action=\"retrieve\">Alignment id: <input type=\"text\" name=\"id\" size=\"60\"/> (id)<br /><small>The id is that of the alignment as known by the server (load it before)</small><br />Rendering: <select name=\"method\">";
 	    for( Iterator it = manager.listrenderers().iterator(); it.hasNext(); ) {
 		String id = (String)it.next();
 		msg += "<option value=\""+id+"\">"+id+"</option>";
 	    }
-	    msg += "<br /></select><input type=\"submit\" value=\"Render\"/></form>";
-	} else if ( perf.equals("process") ) {
-	    // Depends if Store or Render
-	    msg = "Alignment stored";
+	    msg += "</select><br /><input type=\"submit\" value=\"get alignement\"/></form>";
+	} else if ( perf.equals("retrieve") ) {
+	    Message answer = manager.render( new Message(newId(),(Message)null,myId,serverId,"", params) );
+	    if ( answer instanceof ErrorMsg ) {
+		msg = testErrorMessages( answer );
+	    } else {
+		// Depending on the type we should change the MIME type
+		// This should be returned in answer.getParameters()
+		return new Response( HTTP_OK, MIME_HTML, answer.getContent() );
+	    }
+	    // Metadata not done yet
+	} else if ( perf.equals("prmmetadata") ) {
+	    msg = "<h1>Retrieve alignment metadata</h1><form action=\"metadata\">Alignment id: <input type=\"text\" name=\"id\" size=\"60\"/> (id)<br /><small>The id is that of the alignment as known by the server (load it before)</small><br />Rendering: <select name=\"method\">";
+	    for( Iterator it = manager.listrenderers().iterator(); it.hasNext(); ) {
+		String id = (String)it.next();
+		msg += "<option value=\""+id+"\">"+id+"</option>";
+	    }
+	    msg += "</select><br /><input type=\"submit\" value=\"get metadata\"/></form>";
+	} else if ( perf.equals("metadata") ) {
+	    Message answer = manager.render( new Message(newId(),(Message)null,myId,serverId,"", params) );
+	    //System.err.println("Content: "+answer.getContent());
+	    if ( answer instanceof ErrorMsg ) {
+		msg = testErrorMessages( answer );
+	    } else {
+		// Depending on the type we should change the MIME type
+		return new Response( HTTP_OK, MIME_HTML, answer.getContent() );
+	    }
+	    // render
+	    // Alignment in HTML can be rendre or metadata+tuples
+	} else if ( perf.equals("prmload") ) {
+	    // Should certainly be good to offer store as well
+	    msg = "<h1>Load an alignment</h1><form action=\"load\">Alignment URL: <input type=\"text\" name=\"url\" size=\"80\"/> (uri)<br /><small>This is the URL of the place where to find this alignment. It must be reachable by the server (i.e., file:// URI is acceptable if it is on the server).</small><br /><input type=\"submit\" value=\"Load alignment\"/></form>";
+	} else if ( perf.equals("load") ) {
+	    // load
+	    Message answer = manager.load( new Message(newId(),(Message)null,myId,serverId,"", params) );
+	    if ( answer instanceof ErrorMsg ) {
+		msg = testErrorMessages( answer );
+	    } else {
+		msg = "<h1>Alignment loaded</h1>The alignment id is ";
+		msg += answer.getContent();
+	    }
+	} else if ( perf.equals("prmtranslate") ) {
+	} else if ( perf.equals("translate") ) {
+	    // translate( mess )
+	} else if ( perf.equals("") ) {
+	    msg = "<h1>Available commands</h1><ul compact=\"1\">";
+	    msg += "<li><form action=\"prmfind\"><input type=\"submit\" value=\"Find an alignment for ontologies\"/></form></li>";
+	    msg += "<li><form action=\"prmalign\"><input type=\"submit\" value=\"Compute an alignment for ontologies\"/></form></li>";
+	    msg += "<li><form action=\"prmload\"><input type=\"submit\" value=\"Load alignments\"/></form></li>";
+	    msg += "<li><form action=\"prmstore\"><input type=\"submit\" value=\"Store an alignment in the server\"/></form></li>";
+	    msg += "<li><form action=\"prmretrieve\"><input type=\"submit\" value=\"Retrieve an alignment from its id\"/></form></li>";
+	    msg += "<li><form action=\"../admin/\"><input type=\"submit\" value=\"Server management\"/></form></li>";
+	    msg += "</ul>";
 	} else {
 	    msg = "Cannot understand command "+perf;
 	}
-	return new Response( HTTP_OK, MIME_HTML, msg="<html><head></head><body>"+msg+"</body></html>" );
+	return new Response( HTTP_OK, MIME_HTML, "<html><head></head><body>"+msg+"<hr /><center><small><a href=\".\">Alignment server</a></small></center></body></html>" );
+    }
+
+    // ===============================================
+    // Util
+
+    private String testErrorMessages( Message answer ) {
+	return "<h1>Alignement error</h1>"+answer.HTMLString+answer.getContent();
+    }
+
+    private String displayAnswer ( Message answer ) {
+	// seems a bit static...
+	return answer.HTMLString+answer.getContent();
     }
 
+    private int newId() { return localId++; }
+
     // ==================================================
     // HTTP Machinery
 
diff --git a/src/fr/inrialpes/exmo/align/service/Message.java b/src/fr/inrialpes/exmo/align/service/Message.java
index 5d78288ca337d1cf9d598b3a407980e0231d6d82..cb4c09a5be14f1664e7380662381497e5d805977 100644
--- a/src/fr/inrialpes/exmo/align/service/Message.java
+++ b/src/fr/inrialpes/exmo/align/service/Message.java
@@ -35,14 +35,20 @@ public class Message {
     String content = "";
     Parameters parameters = null;
 
-    public Message ( int surr, Message rep, String to, String cont, Parameters param ) {
+    public Message ( int surr, Message rep, String from, String to, String cont, Parameters param ) {
 	surrogate = surr;
 	inReplyTo = rep;
 	receiver = to;
+	sender = from;
 	content = cont;
 	parameters = param;
     }
 
+    public static String HTMLString = "Message: ";
+    public String htmlString(){
+	return "<h1>Message</h1><dl><dt>id:</dt><dd>"+surrogate+"</dd><dt>sender:</dt><dd>"+sender+"</dd><dt>receiver:</dt><dd>"+receiver+"</dd><dt>in-reply-to:</dt><dd>"+inReplyTo+"</dd><dt>content:</dt><dd>"+content+"</dd></dl>";
+    }
+
     public int getId () {
 	return surrogate;
     }
diff --git a/src/fr/inrialpes/exmo/align/service/NonConformParameters.java b/src/fr/inrialpes/exmo/align/service/NonConformParameters.java
new file mode 100644
index 0000000000000000000000000000000000000000..44f7bf7bcb24a4f985bdffbf3a95d8534c2d46f6
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/service/NonConformParameters.java
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2006
+ *
+ * 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.service;
+
+import org.semanticweb.owl.align.Parameters;
+
+/**
+ * Contains the messages that should be sent according to the protocol
+ */
+
+public class NonConformParameters extends ErrorMsg {
+    public NonConformParameters ( int surr, Message rep, String from, String to, String cont, Parameters param ) {
+	super( surr, rep, from, to, cont, param );
+    }
+
+    public static String HTMLString = "Non conform parameters: ";
+    public String htmlString(){
+	return "<h1>Non conform parameters</h1><dl><dt>id:</dt><dd>"+surrogate+"</dd><dt>sender:</dt><dd>"+sender+"</dd><dt>receiver:</dt><dd>"+receiver+"</dd><dt>in-reply-to:</dt><dd>"+inReplyTo+"</dd><dt>content:</dt><dd>"+content+"</dd></dl>";
+    }
+    
+}
diff --git a/src/fr/inrialpes/exmo/align/service/OntologyURI.java b/src/fr/inrialpes/exmo/align/service/OntologyURI.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d133793ffd6db08e7470df2cf3550442d827ac6
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/service/OntologyURI.java
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2006
+ *
+ * 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.service;
+
+import org.semanticweb.owl.align.Parameters;
+
+/**
+ * Contains the messages that should be sent according to the protocol
+ */
+
+public class OntologyURI extends Success {
+
+    public OntologyURI ( int surr, Message rep, String from, String to, String cont, Parameters param ) {
+	super( surr, rep, from, to, cont, param );
+    }
+    public static String HTMLString = "Ontology URI: ";
+}
diff --git a/src/fr/inrialpes/exmo/align/service/RenderedAlignment.java b/src/fr/inrialpes/exmo/align/service/RenderedAlignment.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a86a5dc0ff01d9a060e89d0d8705dca52a670fc
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/service/RenderedAlignment.java
@@ -0,0 +1,34 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2006
+ *
+ * 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.service;
+
+import org.semanticweb.owl.align.Parameters;
+
+/**
+ * Contains the messages that should be sent according to the protocol
+ */
+
+public class RenderedAlignment extends Success {
+
+    public RenderedAlignment ( int surr, Message rep, String from, String to, String cont, Parameters param ) {
+	super( surr, rep, from, to, cont, param );
+    }
+}
diff --git a/src/fr/inrialpes/exmo/align/service/Success.java b/src/fr/inrialpes/exmo/align/service/Success.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b87964d6117e1df82187d6a4014b1ca0e80c026
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/service/Success.java
@@ -0,0 +1,34 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2006
+ *
+ * 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.service;
+
+import org.semanticweb.owl.align.Parameters;
+
+/**
+ * Contains the messages that should be sent according to the protocol
+ */
+
+public class Success extends Message {
+
+    public Success ( int surr, Message rep, String from, String to, String cont, Parameters param ) {
+	super( surr, rep, from, to, cont, param );
+    }
+}
diff --git a/src/fr/inrialpes/exmo/align/service/UnknownAlignment.java b/src/fr/inrialpes/exmo/align/service/UnknownAlignment.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef40150e9430fa872c6b4bea4c810d8d897ea6ee
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/service/UnknownAlignment.java
@@ -0,0 +1,34 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2006
+ *
+ * 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.service;
+
+import org.semanticweb.owl.align.Parameters;
+
+/**
+ * Contains the messages that should be sent according to the protocol
+ */
+
+public class UnknownAlignment extends ErrorMsg {
+    public UnknownAlignment ( int surr, Message rep, String from, String to, String cont, Parameters param ) {
+	super( surr, rep, from, to, cont, param );
+    }
+    public static String HTMLString = "Unknown alignment: ";
+}
diff --git a/src/fr/inrialpes/exmo/align/service/UnknownMethod.java b/src/fr/inrialpes/exmo/align/service/UnknownMethod.java
new file mode 100644
index 0000000000000000000000000000000000000000..3411c52f4359eb9b585d71e911b93f52db9c5c2d
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/service/UnknownMethod.java
@@ -0,0 +1,34 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2006
+ *
+ * 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.service;
+
+import org.semanticweb.owl.align.Parameters;
+
+/**
+ * Contains the messages that should be sent according to the protocol
+ */
+
+public class UnknownMethod extends ErrorMsg {
+    public UnknownMethod ( int surr, Message rep, String from, String to, String cont, Parameters param ) {
+	super( surr, rep, from, to, cont, param );
+    }
+    public static String HTMLString = "Unknown method: ";
+}
diff --git a/src/fr/inrialpes/exmo/align/service/UnreachableOntology.java b/src/fr/inrialpes/exmo/align/service/UnreachableOntology.java
new file mode 100644
index 0000000000000000000000000000000000000000..c73de0f6484e1efbf17d0111fb6ae805880d08c1
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/service/UnreachableOntology.java
@@ -0,0 +1,34 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA Rhône-Alpes, 2006
+ *
+ * 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.service;
+
+import org.semanticweb.owl.align.Parameters;
+
+/**
+ * Contains the messages that should be sent according to the protocol
+ */
+
+public class UnreachableOntology extends ErrorMsg {
+    public UnreachableOntology ( int surr, Message rep, String from, String to, String cont, Parameters param ) {
+	super( surr, rep, from, to, cont, param );
+    }
+    public static String HTMLString = "Unreachable ontology: ";
+}
diff --git a/src/fr/inrialpes/exmo/align/service/dbschema.sql b/src/fr/inrialpes/exmo/align/service/dbschema.sql
index 9c318529175f482a0cd243268e49743f96ff364f..54e8c7d62cde6f46004df931a051b1d309ecac3f 100644
--- a/src/fr/inrialpes/exmo/align/service/dbschema.sql
+++ b/src/fr/inrialpes/exmo/align/service/dbschema.sql
@@ -45,9 +45,10 @@ create table cell(
    relation varchar(5));
 
 
-// cell method
+// extension info
 
-create table method(
+create table extension(
    id varchar(100),
-   tag varchar(20),
-   extension varchar(100));
+   tag varchar(100),
+   method varchar(500));
+