diff --git a/src/fr/inrialpes/exmo/align/impl/BasicCell.java b/src/fr/inrialpes/exmo/align/impl/BasicCell.java
index ad3c9fdfcce1e383384e987af8b146686f11972d..165192d2714a4d84598b2f91226362bb0322e70c 100644
--- a/src/fr/inrialpes/exmo/align/impl/BasicCell.java
+++ b/src/fr/inrialpes/exmo/align/impl/BasicCell.java
@@ -22,16 +22,15 @@
 package fr.inrialpes.exmo.align.impl; 
 
 import java.net.URI;
+import java.util.Enumeration;
 
 import org.xml.sax.ContentHandler;
 
-//*/3.0
-//import org.semanticweb.owl.model.OWLEntity;
-
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.Cell;
 import org.semanticweb.owl.align.Relation;
+import org.semanticweb.owl.align.Parameters;
 
 /**
  * Represents an ontology alignment correspondence. 
@@ -45,32 +44,15 @@ public class BasicCell implements Cell, Comparable {
         visitor.visit( this );
     }
 
-    String id = null;
-    String semantics = null;
-    //*/3.0
-    //OWLEntity object1 = null;
-    //OWLEntity object2 = null;
-    Object object1 = null;
-    Object object2 = null;
-    Relation relation = null;
-    double strength = 0;
+    protected String id = null;
+    protected String semantics = null;
+    protected Object object1 = null;
+    protected Object object2 = null;
+    protected Relation relation = null;
+    protected double strength = 0;
+    protected Parameters extensions = null;    
 
     /** Creation **/
-    //    public BasicCell( Object ob1, Object ob2 ) throws AlignmentException {
-    //	new BasicCell( (String)null, ob1, ob2, "=", 0 );
-    //    };
-
-//*/3.0
-//    public BasicCell( Object ob1, Object ob2, String rel, double m ) throws AlignmentException {
-//	throw new AlignmentException("BasicCell: must take two OWLEntity as argument");
-//    }
-//    public BasicCell( OWLEntity ob1, OWLEntity ob2, String rel, double m ) throws AlignmentException {
-//    public BasicCell( String id, Object ob1, Object ob2, String rel, double m ) throws AlignmentException {
-//	new BasicCell( id, ob1, ob2, BasicRelation.createRelation(rel), m );
-//    };
-
-//*/3.0
-//    public BasicCell( OWLEntity ob1, OWLEntity ob2, Relation rel, double m ) throws AlignmentException {
     public BasicCell( String id, Object ob1, Object ob2, Relation rel, double m ) throws AlignmentException {
 	setId( id ); 
 	object1 = ob1;
@@ -78,6 +60,7 @@ public class BasicCell implements Cell, Comparable {
 	relation = rel;
 	// No exception, just keep 0?
 	if ( m >= 0 && m <= 1 ) strength = m;
+	// extensions is only created on demand, otherwise, it is too expensive
     };
 
     // the strength must be compared with regard to abstract types
@@ -124,21 +107,9 @@ public class BasicCell implements Cell, Comparable {
 	}
     }
     public void setObject1( Object ob ) throws AlignmentException {
-//*/3.0
-//	if ( ob instanceof OWLEntity ) {
-//	    object1 = (OWLEntity)ob;
-//	} else {
-//	    throw new AlignmentException("BasicCell.setObject1: must have an OWLEntity as argument");
-//	}
 	object1 = ob;
     }
     public void setObject2( Object ob ) throws AlignmentException {
-//*/3.0
-//	if ( ob instanceof OWLEntity ) {
-//	    object2 = (OWLEntity)ob;
-//	} else {
-//	    throw new AlignmentException("BasicCell.setObject2: must have an OWLEntity as argument");
-//	}
 	object2 = ob;
     }
     public Relation getRelation(){ return relation; };
@@ -146,9 +117,36 @@ public class BasicCell implements Cell, Comparable {
     public double getStrength(){ return strength; };
     public void setStrength( double m ){ strength = m; };
 
+    public Parameters getExtensions(){ return extensions; }
+    public void setExtensions( Parameters p ){
+	extensions = p;
+    }
+
+    public void setExtension( String label, String value ) {
+	if ( extensions == null )
+	    extensions = new BasicParameters();
+	extensions.setParameter( label, value );
+    };
+
+    public String getExtension( String label ) {
+	if ( extensions != null ) {
+	    return (String)extensions.getParameter( label );
+	} else {
+	    return (String)null;
+	}
+    };
+
     public Cell inverse() throws AlignmentException {
-	return (Cell)new BasicCell( (String)null, object2, object1, relation.inverse(), strength );
+	Cell result = (Cell)new BasicCell( (String)null, object2, object1, relation.inverse(), strength );
+	if ( extensions != null ) {
+	    for ( Enumeration e = extensions.getNames() ; e.hasMoreElements(); ){
+		String label = (String)e.nextElement();
+		result.setExtension( label, getExtension( label ) );
+	    }
+	}
+	result.getExtensions().unsetParameter( "id" );
 	// The sae should be done for the measure
+	return result;
     }
 
     /** Housekeeping **/
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/HTMLRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/HTMLRendererVisitor.java
index 4331283a9e8a51b117c85e276cb9b73c695b3645..255ba11eee68fa092e519b8f3734f849be064409 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/HTMLRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/HTMLRendererVisitor.java
@@ -52,7 +52,7 @@ public class HTMLRendererVisitor implements AlignmentVisitor
     }
 
     public void visit( Alignment align ) throws AlignmentException {
-	//alignment = align;
+	alignment = align;
 	writer.print("<html>\n<head></head>\n<body>\n");
 	writer.print("<h1></h1>\n");
 	writer.print("<h2>Alignment metadata</h2>\n");
@@ -72,7 +72,7 @@ public class HTMLRendererVisitor implements AlignmentVisitor
 	}
 	writer.print("</table>\n");
 	writer.print("<h2>Correspondences</h2>\n");
-	writer.print("<table><tr><td>Id</td><td>object1</td><td>relation</td><td>strength</td><td>object2</td></tr>\n");
+	writer.print("<table><tr><td>object1</td><td>relation</td><td>strength</td><td>object2</td><td>Id</td></tr>\n");
 	for( Enumeration e = align.getElements() ; e.hasMoreElements(); ){
 	    Cell c = (Cell)e.nextElement();
 	    c.accept( this );
@@ -80,17 +80,26 @@ public class HTMLRendererVisitor implements AlignmentVisitor
 	writer.print("</table>\n");
 	writer.print("</body>\n</html>\n");
     }
+
     public void visit( Cell cell ) throws AlignmentException {
 	this.cell = cell;
 	writer.print("  <tr>");
-	if ( cell.getId() != null ) writer.print("<td>"+cell.getId()+"</td>");
-	else writer.print("<td></td>");
 	writer.print("<td>"+cell.getObject1AsURI().toString()+"</td><td>");
 	cell.getRelation().accept( this );
 	writer.print("</td><td>"+cell.getStrength()+"</td>");
-	writer.print("<td>"+cell.getObject2AsURI().toString()+"</td></tr>");
+	writer.print("<td>"+cell.getObject2AsURI().toString()+"</td>");
+	if ( cell.getId() != null ) {
+	    String id = cell.getId();
+	    // Would be useful to test for the Alignment URI
+	    if ( id.startsWith( (String)alignment.getExtension( "id" ) ) ){
+		writer.print("<td>"+id.substring( id.indexOf( '#' ) )+"</td>");
+	    } else {
+		writer.print("<td>"+id+"</td>");
+	    }
+	} else writer.print("<td></td>");
 	//if ( !cell.getSemantics().equals("first-order") )
 	//	writer.print("      <semantics>"+cell.getSemantics()+"</semantics>\n");
+	writer.println("</tr>");
     }
     public void visit( Relation rel ) {
 	rel.write( writer );
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
index 56a94e6303f2802b73c267db44b76248e4a2448d..6a1b16d5534a47b8ba2be9ab6b67237891d12e5d 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
@@ -23,11 +23,6 @@ package fr.inrialpes.exmo.align.impl.renderer;
 import java.util.Enumeration;
 import java.io.PrintWriter;
 
-//*/3.0
-//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;
@@ -68,51 +63,56 @@ public class RDFRendererVisitor implements AlignmentVisitor
 	    String tag = (String)e.nextElement();
 	    writer.print("  <"+tag+">"+align.getExtension(tag)+"</"+tag+">\n");
 	}
-	//	try {
-	    if ( align.getFile1() != null )
-		writer.print("  <onto1>"+align.getFile1().toString()+"</onto1>\n");
-	    if ( align.getFile2() != null )
-		writer.print("  <onto2>"+align.getFile2().toString()+"</onto2>\n");
-	    writer.print("  <uri1>");
-	    writer.print( align.getOntology1URI().toString() );
-	    writer.print("</uri1>\n");
-	    writer.print("  <uri2>");
-	    writer.print( align.getOntology2URI().toString() );
-	    writer.print("</uri2>\n");
+	if ( align.getFile1() != null )
+	    writer.print("  <onto1>"+align.getFile1().toString()+"</onto1>\n");
+	if ( align.getFile2() != null )
+	    writer.print("  <onto2>"+align.getFile2().toString()+"</onto2>\n");
+	writer.print("  <uri1>");
+	writer.print( align.getOntology1URI().toString() );
+	writer.print("</uri1>\n");
+	writer.print("  <uri2>");
+	writer.print( align.getOntology2URI().toString() );
+	writer.print("</uri2>\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); }
+	for( Enumeration e = align.getElements() ; e.hasMoreElements(); ){
+	    Cell c = (Cell)e.nextElement();
+	    c.accept( this );
+	} //end for
 	writer.print("</Alignment>\n");
 	writer.print("</rdf:RDF>\n");
     }
     public void visit( Cell cell ) throws AlignmentException {
 	this.cell = cell;
-	//OWLOntology onto1 = (OWLOntology)alignment.getOntology1();
-	//	try {
 	    if ( cell.getObject1AsURI() != null &&
 		 cell.getObject2AsURI() != null ){
 	    writer.print("  <map>\n");
 	    writer.print("    <Cell");
 	    if ( cell.getId() != null ){
-		writer.print(" rdf:about=\"#"+cell.getId()+"\"");
+		writer.print(" rdf:about=\""+cell.getId()+"\"");
 	    }
 	    writer.print(">\n      <entity1 rdf:resource='");
 	    writer.print( cell.getObject1AsURI().toString() );
 	    writer.print("'/>\n      <entity2 rdf:resource='");
 	    writer.print( cell.getObject2AsURI().toString() );
-	    writer.print("'/>\n      <measure rdf:datatype='http://www.w3.org/2001/XMLSchema#float'>");
+	    writer.print("'/>\n      <relation>");
+	    cell.getRelation().accept( this );
+	    writer.print("</relation>\n");
+	    writer.print("      <measure rdf:datatype='http://www.w3.org/2001/XMLSchema#float'>");
 	    writer.print( cell.getStrength() );
 	    writer.print("</measure>\n");
-	    if ( !cell.getSemantics().equals("first-order") )
+	    if ( cell.getSemantics() != null &&
+		 !cell.getSemantics().equals("") &&
+		 !cell.getSemantics().equals("first-order") )
 		writer.print("      <semantics>"+cell.getSemantics()+"</semantics>\n");
-	    writer.print("      <relation>");
-	    cell.getRelation().accept( this );
-	    writer.print("</relation>\n    </Cell>\n  </map>\n");
 	    }
-	    //	} catch ( OWLException e) { throw new AlignmentException( "getURI problem", e ); }
+	    if ( cell.getExtensions() != null ) {
+		// could certainly be done better
+		for ( Enumeration e = cell.getExtensions().getNames() ; e.hasMoreElements(); ){
+		    String label = (String)e.nextElement();
+		    writer.print("      <"+label+">"+cell.getExtension(label)+"</"+label+">\n");
+		}
+	    }
+	    writer.print("    </Cell>\n  </map>\n");
     }
     public void visit( Relation rel ) {
 	rel.write( writer );
diff --git a/src/fr/inrialpes/exmo/align/parser/AlignmentParser.java b/src/fr/inrialpes/exmo/align/parser/AlignmentParser.java
index 80c18e9e54064d6b5d809819ffdd609268030dfc..eaa380bc14e8f42b1e5692d0a58b4e76a1044a26 100644
--- a/src/fr/inrialpes/exmo/align/parser/AlignmentParser.java
+++ b/src/fr/inrialpes/exmo/align/parser/AlignmentParser.java
@@ -38,18 +38,13 @@ import java.lang.Integer;
 import java.lang.Double;
 import java.util.Hashtable;
 
-//*/3.0
-//import org.semanticweb.owl.util.OWLManager;
-//import org.semanticweb.owl.model.OWLOntology;
-//import org.semanticweb.owl.model.OWLEntity;
-//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.align.Alignment;
 import org.semanticweb.owl.align.Cell;
 import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.Parameters;
+
 import fr.inrialpes.exmo.align.impl.URIAlignment;
+import fr.inrialpes.exmo.align.impl.BasicParameters;
 
 /**
  * This class allows the creation of a parser for an Alignment file.
@@ -75,15 +70,11 @@ public class AlignmentParser extends DefaultHandler {
     /**
      * the first Ontology 
      */
-    //*/3.0
-    // OWLOntology onto1 = null;
     Object onto1 = null;
     
     /**
      * the second Ontology 
      */
-    //*/3.0
-    // OWLOntology onto2 = null;
     Object onto2 = null;
 
     /**
@@ -97,8 +88,6 @@ public class AlignmentParser extends DefaultHandler {
      * This is a pitty but the idea of creating a particular alignment
      * is not in accordance with using an interface.
      */
-    //*/3.0
-    //protected BasicAlignment alignment = null;
     protected URIAlignment alignment = null;
     
     /**
@@ -109,15 +98,11 @@ public class AlignmentParser extends DefaultHandler {
     /**
      * the first entity of a cell
      */
-    //*/3.0
-    //protected OWLEntity cl1 = null;
     protected Object cl1 = null;
     
     /**
      * the second entity of a cell
      */
-    //*/3.0
-    //protected OWLEntity cl2 = null;
     protected Object cl2 = null;
     
     /**
@@ -140,6 +125,11 @@ public class AlignmentParser extends DefaultHandler {
      */
     protected String sem = null;
 
+    /**
+     * Cell extensions (default null)
+     */
+    protected Parameters extensions = null;
+
     /**
      * the measure content as text...
      */
@@ -151,7 +141,8 @@ public class AlignmentParser extends DefaultHandler {
     protected SAXParser parser = null;
 
     /**
-     * The parsing level, if equal to 2 we are in the Alignment
+     * The parsing level, if equal to 3 we are in the Alignment
+     * if equal to 5 we are in a cell
      * and can find metadata
      */
     protected int parselevel = 0;
@@ -211,82 +202,58 @@ public class AlignmentParser extends DefaultHandler {
 	    System.err.println("startElement AlignmentParser : " + pName);
 	parselevel++;
 	if(namespaceURI.equals("http://knowledgeweb.semanticweb.org/heterogeneity/alignment"))  {
-		    //*/3.0
-	    //try {
-		if (pName.equals("relation")) {
-		} else if (pName.equals("semantics")) {
-		} else if (pName.equals("measure")) {
-		} else if (pName.equals("entity2")) {
-		    if(debugMode > 2) 
-			System.err.println(" resource = " + atts.getValue("rdf:resource"));
-		    //*/3.0
-		    //cl2 = (OWLEntity)getEntity( onto2, atts.getValue("rdf:resource") );
-		    try {
-			cl2 = new URI( atts.getValue("rdf:resource") );
-		    } catch (URISyntaxException e) {
-			throw new SAXException("Malformed URI: "+atts.getValue("rdf:resource"));
-		    }
-		} else if (pName.equals("entity1")) {
-		    if(debugMode > 2) 
-			System.err.println(" resource = " + atts.getValue("rdf:resource"));
-		    //*/3.0
-		    //cl1 = (OWLEntity)getEntity( onto1, atts.getValue("rdf:resource") );
-		    try {
-			cl1 = new URI( atts.getValue("rdf:resource") );
-		    } catch (URISyntaxException e) {
-			throw new SAXException("Malformed URI: "+atts.getValue("rdf:resource"));
-		    }
-		} else if (pName.equals("Cell")) {
-		    if ( alignment == null )
-			{ throw new SAXException("No alignment provided"); };
-		    if ( atts.getValue("rdf:ID") != null ){
-			id = atts.getValue("rdf:ID");
-		    } else if ( atts.getValue("rdf:about") != null ){
-			id = atts.getValue("rdf:about");
-		    }
-		    sem = null;
-		    measure = null;
-		    relation = null;
-		    cl1 = null;
-		    cl2 = null;
-		} else if (pName.equals("map")) {
-		    try {
-			//*/3.0
-			//if ( onto2 == null ){
-			//    onto2 = loadOntology( alignment.getFile2() );
-			//    if ( onto2 == null ) {
-			//	throw new SAXException("Cannot find ontology"+alignment.getFile2());
-			//    }
-			//}
-			alignment.setOntology2( onto2 );
-			//*/3.0
-			//if ( onto1 == null ){
-			//    onto1 = loadOntology( alignment.getFile1() );
-			//    if ( onto1 == null ) {
-			//	throw new SAXException("Cannot find ontology"+alignment.getFile1());
-			//    }
-			//}
-			alignment.setOntology1( onto1 );
-		    } catch ( AlignmentException e ) {
-			throw new SAXException("Catched alignment exception", e );
-		    }
-		} else if (pName.equals("onto2")) {
-		} else if (pName.equals("onto1")) {
-		} else if (pName.equals("uri2")) {
-		} else if (pName.equals("uri1")) {
-		} else if (pName.equals("type")) {
-		} else if (pName.equals("level")) {
-		} else if (pName.equals("xml")) {
-		} else if (pName.equals("Alignment")) {
-		    //*/3.0
-		    //alignment = new BasicAlignment();
-		    alignment = new URIAlignment();
-		} else {
-		    if ( debugMode > 0 ) System.err.println("[AlignmentParser] Unknown element name : "+pName);
-		    //throw new SAXException("[AlignmentParser] Unknown element name : "+pName);
-		};
-		//*/3.0
-		//} catch ( OWLException e ) { throw new SAXException("[AlignmentParser] OWLException raised"); }; 
+	    if (pName.equals("relation")) {
+	    } else if (pName.equals("semantics")) {
+	    } else if (pName.equals("measure")) {
+	    } else if (pName.equals("entity2")) {
+		if(debugMode > 2) 
+		    System.err.println(" resource = " + atts.getValue("rdf:resource"));
+		try {
+		    cl2 = new URI( atts.getValue("rdf:resource") );
+		} catch (URISyntaxException e) {
+		    throw new SAXException("Malformed URI: "+atts.getValue("rdf:resource"));
+		}
+	    } else if (pName.equals("entity1")) {
+		if(debugMode > 2) 
+		    System.err.println(" resource = " + atts.getValue("rdf:resource"));
+		try {
+		    cl1 = new URI( atts.getValue("rdf:resource") );
+		} catch (URISyntaxException e) {
+		    throw new SAXException("Malformed URI: "+atts.getValue("rdf:resource"));
+		}
+	    } else if (pName.equals("Cell")) {
+		if ( alignment == null )
+		    { throw new SAXException("No alignment provided"); };
+		if ( atts.getValue("rdf:ID") != null ){
+		    id = atts.getValue("rdf:ID");
+		} else if ( atts.getValue("rdf:about") != null ){
+		    id = atts.getValue("rdf:about");
+		}
+		sem = null;
+		measure = null;
+		relation = null;
+		extensions = null;
+		cl1 = null;
+		cl2 = null;
+	    } else if (pName.equals("map")) {
+		try {
+		    alignment.setOntology2( onto2 );
+		    alignment.setOntology1( onto1 );
+		} catch ( AlignmentException e ) {
+		    throw new SAXException("Catched alignment exception", e );
+		}
+	    } else if (pName.equals("onto2")) {
+	    } else if (pName.equals("onto1")) {
+	    } else if (pName.equals("uri2")) {
+	    } else if (pName.equals("uri1")) {
+	    } else if (pName.equals("type")) {
+	    } else if (pName.equals("level")) {
+	    } else if (pName.equals("xml")) {
+	    } else if (pName.equals("Alignment")) {
+		alignment = new URIAlignment();
+	    } else {
+		if ( debugMode > 0 ) System.err.println("[AlignmentParser] Unknown element name : "+pName);
+	    };
 	} else if(namespaceURI.equals("http://www.w3.org/1999/02/22-rdf-syntax-ns#"))  {
 	    if ( !pName.equals("RDF") ) {
 		throw new SAXException("[AlignmentParser] unknown element name: "+pName); };
@@ -295,21 +262,10 @@ public class AlignmentParser extends DefaultHandler {
 	}
     }
 
-    //*/3.0
-    //private OWLEntity getEntity( OWLOntology ontology, String name ) throws OWLException, SAXException {
     private Object getEntity( Object ontology, String name ) throws SAXException {
-	URI uri = null;
-
-	try { uri = new URI(name);}
-	catch (URISyntaxException e) {throw new SAXException("[AlignmentParser] bad URI syntax : "+name);}
-
-	//*/3.0
-	//OWLEntity result = (OWLEntity)ontology.getClass( uri );
-	//if ( result == null ) result = (OWLEntity)ontology.getDataProperty( uri );
-	//if ( result == null ) result = (OWLEntity)ontology.getObjectProperty( uri );
-	//if ( result == null ) result = (OWLEntity)ontology.getIndividual( uri );
-	//return result;
-	return uri;
+	try { return new URI( name );}
+	catch (URISyntaxException e) {
+	    throw new SAXException("[AlignmentParser] bad URI syntax : "+name);}
     }
 
     /**
@@ -322,7 +278,7 @@ public class AlignmentParser extends DefaultHandler {
     }
 
     /*
-    // Change proposed by Sabine Massmann
+    // Patch proposed by Sabine Massmann
     // If to be integrated, then put it in the proper place
     // There is no reasons to test for Double in characters
    public void characters(char ch[], int start, int length) {
@@ -385,18 +341,15 @@ public class AlignmentParser extends DefaultHandler {
 			cell = alignment.addAlignCell( cl1, cl2, relation, Double.parseDouble(measure) );}
 		    if ( id != null ) cell.setId( id );
 		    if ( sem != null ) cell.setSemantics( sem );
+		    if ( extensions != null ) cell.setExtensions( extensions );
 		} else if (pName.equals("map")) {
 		} else if (pName.equals("uri1")) {
-		    //*/3.0
-		    //onto1 = (OWLOntology)ontologies.get( content );
 		    try {
 			onto1 = new URI( content );
 		    } catch (URISyntaxException e) {
 			throw new SAXException("uri1: malformed URI");
 		    }
 		} else if (pName.equals("uri2")) {
-		    //*/3.0
-		    //onto2 = (OWLOntology)ontologies.get( content );
 		    try {
 			onto2 = new URI( content );
 		    } catch (URISyntaxException e) {
@@ -421,54 +374,33 @@ public class AlignmentParser extends DefaultHandler {
 		    //	{ throw new SAXException("Non parseable alignment"); }
 		} else if (pName.equals("Alignment")) {
 		} else {
-		    if ( debugMode > 0 )
+		    if ( parselevel == 3 ){
+			alignment.setExtension( pName, content );
+		    } else if ( parselevel == 5 ) {
+			if ( extensions == null ) extensions = new BasicParameters();
+			//cell.setExtension( pName, content );
+			extensions.setParameter( pName, content );
+		    } else //if ( debugMode > 0 )
 			System.err.println("[AlignmentParser] Unknown element name : "+pName);
 		    //throw new SAXException("[AlignmentParser] Unknown element name : "+pName);
 		};
-		//*/3.0
 	    } catch ( AlignmentException e ) { throw new SAXException("[AlignmentParser] OWLException raised"); };
 	} else if(namespaceURI.equals("http://www.w3.org/1999/02/22-rdf-syntax-ns#"))  {
 	    if ( !pName.equals("RDF") ) {
 		throw new SAXException("[AlignmentParser] unknown element name: "+pName); };
 	} else {
-	    if ( parselevel == 2 ){
+	    if ( parselevel == 3 ){
 		alignment.setExtension( pName, content );
+	    } else if ( parselevel == 5 ) {
+		if ( extensions == null ) extensions = new BasicParameters();
+		//cell.setExtension( pName, content );
+		extensions.setParameter( pName, content );
 	    } else throw new SAXException("[AlignmentParser] Unknown namespace : "+namespaceURI);
 	}
 	parselevel--;
     } //end endElement
     
     /** Can be used for loading the ontology if it is not available **/
-    //*/3.0
-    /*
-    private OWLOntology loadOntology( URI ref ) throws SAXException, OWLException {
-	OWLOntology parsedOnt = null;
-	OWLRDFParser parser = new OWLRDFParser();
-	OWLRDFErrorHandler 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.out.println("WARNING: " + message);
-		}
-	    };
-	parser.setOWLRDFErrorHandler( handler );
-	parser.setConnection( OWLManager.getOWLConnection() );
-	try {
-	    parsedOnt = parser.parseOntology( ref );
-	    ontologies.put( ref.toString(), parsedOnt );
-	    return parsedOnt;
-	} catch ( Exception e ) {
-	    throw new SAXException("[AlignmentParser] Error during parsing : "+ref);
-	}
-    }
-*/
  
 }//end class
     
diff --git a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java
index 162d3c776076a07fdf3e4b09b55ec30abcb8776d..40ddf0deb013f7513c9b3822e178deb691b7b889 100644
--- a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java
+++ b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java
@@ -181,7 +181,12 @@ public class AServProtocolManager {
 	return alignmentCache.listAlignments();
     }
 
-    /*********************************************************************
+    public String query( String query ){
+	//return alignmentCache.query( query );
+	return "Not available yet";
+    }
+
+   /*********************************************************************
      * Basic protocol primitives
      *********************************************************************/
 
@@ -447,6 +452,7 @@ public class AServProtocolManager {
 	} catch (Exception e) {
 	    return new UnknownAlignment(newId(),mess,myId,mess.getSender(),id,(Parameters)null);
 	}
+	// JE: Other possibility is to render the metadata through XMLMetadataRendererVisitor into content...
 	// Put all the local metadata in parameters
 	Parameters params = new BasicParameters();
 	params.setParameter( "file1", al.getFile1() );
@@ -531,6 +537,22 @@ public class AServProtocolManager {
 	return new AlignmentId(newId(),mess,myId,mess.getSender(),"dummy//",(Parameters)null);
     }
 
+    public boolean storedAlignment( Message mess ) {
+	// Retrieve the alignment
+	String id = (String)mess.getParameters().getParameter("id");
+	Alignment al = null;
+	try {
+	    al = alignmentCache.getAlignment( id );
+	} catch (Exception e) {
+	    return false;
+	}
+	if ( al.getExtension("fr.inrialpes.exmo.align.service.stored") != null && al.getExtension("fr.inrialpes.exmo.align.service.stored") != "" ) {
+	    return true;
+	} else {
+	    return false;
+	}
+    }
+
     /*********************************************************************
      * Network of alignment server implementation
      *********************************************************************/
diff --git a/src/fr/inrialpes/exmo/align/service/CacheImpl.java b/src/fr/inrialpes/exmo/align/service/CacheImpl.java
index 650b4abdb89370320a8fc419148a4bf28b434f72..96be7d29008c5196831acc9ae1373dc7c310e3eb 100644
--- a/src/fr/inrialpes/exmo/align/service/CacheImpl.java
+++ b/src/fr/inrialpes/exmo/align/service/CacheImpl.java
@@ -62,15 +62,23 @@ public class CacheImpl implements Cache {
     String port = null;
     int rights = 1; // writing rights in the database (default is 1)
 	
-    final int VERSION = 300; // Version of the API to be stored in the database
+    final int VERSION = 302; // Version of the API to be stored in the database
+    /* 300: initial database format
+       301: added alignment id as primary key
+       302: changed cached/stored/ouri tag forms
+     */
 
-    Statement st = null;
-    ResultSet rs = null;
+    Statement st = null; // JE: not sure that this should persist
     Connection conn = null;
 	
     final int CONNECTION_ERROR = 1;
     final int SUCCESS = 2;
     final int INIT_ERROR = 3;
+
+    final String CACHED = "http://exmo.inrialpes.fr/align/service:cached";
+    final String STORED = "http://exmo.inrialpes.fr/align/service:stored";
+    final String OURI1 = "http://exmo.inrialpes.fr/align/service:ouri1";
+    final String OURI2 = "http://exmo.inrialpes.fr/align/service:ouri2";
 	
     //**********************************************************************
     public CacheImpl( DBService service ) {
@@ -93,7 +101,7 @@ public class CacheImpl implements Cache {
 	port = (String)p.getParameter("http"); // bad idea
 	host = (String)p.getParameter("host");
 	// test if a database is here, otherwise create it
-	rs = (ResultSet)st.executeQuery("SHOW TABLES LIKE 'server'");
+	ResultSet rs = (ResultSet)st.executeQuery("SHOW TABLES LIKE 'server'");
 	if ( !rs.next() ) initDatabase();
 	// register by the database
 	st.executeUpdate("INSERT INTO server (host, port, edit, version) VALUES ('"+host+"','"+port+"','"+rights+"',"+VERSION+")");
@@ -131,7 +139,7 @@ public class CacheImpl implements Cache {
 	
 	if (force) {
 	    // Retrieve the alignment ids
-	    rs = (ResultSet) st.executeQuery("SELECT id FROM alignment");
+	    ResultSet rs = (ResultSet) st.executeQuery("SELECT id FROM alignment");
 	    while(rs.next()) {
 		id = rs.getString("id");
 		idInfo.add(id);	
@@ -156,6 +164,7 @@ public class CacheImpl implements Cache {
      */
     protected Alignment retrieveDescription( String id ){
 	String query;
+	ResultSet rs;
 	String tag;
 	String method;
 
@@ -169,8 +178,8 @@ public class CacheImpl implements Cache {
 		// Either uri1 or file1
 		result.setFile1( new URI( rs.getString("file1") ) ); 
 		result.setFile2( new URI( rs.getString("file2") ) );
-		result.setExtension( "ouri1", rs.getString("owlontology1") );
-		result.setExtension( "ouri2", rs.getString("owlontology2") );
+		result.setExtension( OURI1, rs.getString("owlontology1") );
+		result.setExtension( OURI2, rs.getString("owlontology2") );
 		result.setLevel(rs.getString("level"));
 		result.setType(rs.getString("type"));	
 	    }
@@ -189,9 +198,9 @@ public class CacheImpl implements Cache {
 	    return null;
 	}
 	// should be there
-	//result.setExtension("fr.inrialpes.exmo.align.service.stored", "DATE");
+	//result.setExtension(STORED, "DATE");
 	// not yet cached
-	result.setExtension("fr.inrialpes.exmo.align.service.cached", "");
+	result.setExtension(CACHED, "");
 	return result;
     }
 
@@ -200,35 +209,48 @@ public class CacheImpl implements Cache {
      * alignmentTable hastable
      * 
      * should be invoked when:
-     * 	( result.getExtension("fr.inrialpes.exmo.align.service.cached") == ""
-     * && result.getExtension("fr.inrialpes.exmo.align.service.stored") != "") {
+     * 	( result.getExtension(CACHED) == ""
+     * && result.getExtension(STORED) != "") {
 
      */
-    protected Alignment retrieveAlignment( String id, Alignment result ) throws SQLException, AlignmentException, URISyntaxException {
+    protected Alignment retrieveAlignment( String id, Alignment alignment ) throws SQLException, AlignmentException, URISyntaxException {
 	String query;
 	URI ent1 = null, ent2 = null;
 	Cell cell = null;
 
-	result.setOntology1( new URI( result.getExtension( "ouri1" ) ) );
-	result.setOntology2( new URI( result.getExtension( "ouri2" ) ) );
+	alignment.setOntology1( new URI( alignment.getExtension( OURI1 ) ) );
+	alignment.setOntology2( new URI( alignment.getExtension( OURI2 ) ) );
 
 	// Get cells
 	query = "SELECT * FROM cell WHERE id = '" + id + "'";
-	rs = (ResultSet) st.executeQuery(query);
+	ResultSet rs = (ResultSet) st.executeQuery(query);
 	while(rs.next()) {
 	    ent1 = new URI(rs.getString("uri1"));
 	    ent2 = new URI(rs.getString("uri2"));
 	    if(ent1 == null || ent2 == null) break;
-	    cell = result.addAlignCell(ent1, ent2, rs.getString("relation"), Double.parseDouble(rs.getString("measure")));
+	    cell = alignment.addAlignCell(ent1, ent2, rs.getString("relation"), Double.parseDouble(rs.getString("measure")));
 	    cell.setId(rs.getString("cell_id"));
 	    cell.setSemantics(rs.getString("semantics"));
+
+	}
+
+	// JE: I must now retrieve all the extensions
+	for( Enumeration e = alignment.getElements() ; e.hasMoreElements(); ){
+	    cell = (Cell)e.nextElement();
+	    String cid = cell.getId();
+	    if ( cid != null && !cid.equals("") ){
+		query = "SELECT * FROM extension WHERE id = '" + cid + "'";
+		ResultSet rse = (ResultSet) st.executeQuery(query);
+		while ( rse.next() ){
+		    cell.setExtension( rse.getString("tag"), 
+				       rse.getString("method") );
+		}
+	    }
 	}
-	// It is here
-	//result.setExtension("fr.inrialpes.exmo.align.service.stored", "DATE");
 	// reset
-	resetCacheStamp(result);
+	resetCacheStamp(alignment);
 
-	return result;
+	return alignment;
     }
 
     private String generateAlignmentId() {
@@ -236,6 +258,16 @@ public class CacheImpl implements Cache {
 	return "http://"+host+":"+port+"/alid/" + new Date().getTime() + "/" + randomNum();
     }
     
+    private String generateCellId( String alId ) {
+	// Generate an id based on a URI prefix + Date + random number
+	int end = alId.indexOf("/alid/");
+	if ( end == -1 || alId.indexOf( '#' ) != -1 ) {
+	    return "http://"+host+":"+port+"/cellid/" + new Date().getTime() + "/" + randomNum();
+	} else {
+	    return alId + "#" + randomNum();
+	}
+    }
+    
     private int randomNum() {
 	Random rand = new Random(System.currentTimeMillis());
 	return Math.abs(rand.nextInt(1000)); 
@@ -265,8 +297,8 @@ public class CacheImpl implements Cache {
 	    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") != "") {
+	if ( result.getExtension(CACHED) == "" 
+	     && result.getExtension(STORED) != "") {
 	    retrieveAlignment( id, result );
 	}
 	
@@ -285,7 +317,7 @@ public class CacheImpl implements Cache {
 	    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 );
+		if ( al.getExtension(OURI2).equals( uri2.toString() ) ) result.add( al );
 	    }
 	}
 	return result;
@@ -306,12 +338,12 @@ public class CacheImpl implements Cache {
      */
     public String recordNewAlignment( String id, Alignment al, boolean force ) throws AlignmentException {
 	Alignment alignment = al;
-	alignment.setExtension("ouri1", alignment.getOntology1URI().toString());
-	alignment.setExtension("ouri2", alignment.getOntology2URI().toString());
+	alignment.setExtension(OURI1, alignment.getOntology1URI().toString());
+	alignment.setExtension(OURI2, alignment.getOntology2URI().toString());
 	// Index
 	recordAlignment( id, alignment, force );
 	// Not yet stored
-	alignment.setExtension("fr.inrialpes.exmo.align.service.stored", "");
+	alignment.setExtension(STORED, "");
 	// Cached now
 	resetCacheStamp(alignment);
 	return id;
@@ -326,8 +358,8 @@ public class CacheImpl implements Cache {
 	    alignment.setExtension( "id", id );
 	// Store it
 	try {
-	    URI ouri1 = new URI( alignment.getExtension("ouri1") );
-	    URI ouri2 = new URI( alignment.getExtension("ouri2") );
+	    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 ) {
@@ -389,13 +421,13 @@ public class CacheImpl implements Cache {
 	alignment = getAlignment( id );
 
 	// We store stored date
-	alignment.setExtension("fr.inrialpes.exmo.align.service.stored", new Date().toString());
+	alignment.setExtension(STORED, new Date().toString());
 	// We empty cached date
-	alignment.setExtension("fr.inrialpes.exmo.align.service.cached", "");
+	alignment.setExtension(CACHED, "");
 
 	try {
-	    String s_O1 = alignment.getExtension("ouri1");
-	    String s_O2 = alignment.getExtension("ouri2");
+	    String s_O1 = alignment.getExtension(OURI1);
+	    String s_O2 = alignment.getExtension(OURI2);
 	    
 	    // file attribute
 	    String s_File1 = null;
@@ -427,24 +459,43 @@ public class CacheImpl implements Cache {
 	    
 	    for( Enumeration e = alignment.getElements() ; e.hasMoreElements(); ){
 		Cell c = (Cell)e.nextElement();
-		String temp[] = new String[10];
-		    if ( c.getObject1() != null && c.getObject2() != null ){
-			if ( c.getId() != null ){
-			    temp[0] = c.getId();
-			} 
-			else temp[0] = "";
-			temp[1] = c.getObject1AsURI().toString();
-			temp[2] = c.getObject2AsURI().toString();
-			temp[3] = c.getStrength() + "";
-			if ( !c.getSemantics().equals("first-order") )
-			    temp[4] = c.getSemantics();
-			else temp[4] = "";
-			temp[5] =  ((BasicRelation)c.getRelation()).getRelation();	
-			query = "INSERT INTO cell " + 
-			    "(id, cell_id, uri1, uri2, measure, semantics, relation) " +
-			    "VALUES ('" + quote(id) + "','" + quote(temp[0]) + "','" + quote(temp[1]) + "','" + quote(temp[2]) + "','" + quote(temp[3]) + "','" + quote(temp[4]) + "','" + quote(temp[5]) + "')";
+		String cellid = null;
+		if ( c.getObject1() != null && c.getObject2() != null ){
+		    cellid = c.getId();
+		    if ( cellid != null ){
+			if ( cellid.startsWith("#") ) {
+			    cellid = alignment.getExtension("id") + cellid;
+			}
+		    } else if ( c.getExtensions() != null ) {
+			// JE: In case of extensions create an ID
+			c.setId( generateCellId( id ) );
+			cellid = c.getId();
+		    }
+		    else cellid = "";
+		    String uri1 = c.getObject1AsURI().toString();
+		    String uri2 = c.getObject2AsURI().toString();
+		    String strength = c.getStrength() + ""; // crazy Java
+		    String sem;
+		    if ( !c.getSemantics().equals("first-order") )
+			sem = c.getSemantics();
+		    else sem = "";
+		    String rel =  ((BasicRelation)c.getRelation()).getRelation();	
+		    query = "INSERT INTO cell " + 
+			"(id, cell_id, uri1, uri2, measure, semantics, relation) " +
+			"VALUES ('" + quote(id) + "','" + quote(cellid) + "','" + quote(uri1) + "','" + quote(uri2) + "','" + quote(strength) + "','" + quote(sem) + "','" + quote(rel) + "')";
+		    st.executeUpdate(query);
+		}
+		if ( cellid != null && !cellid.equals("") ) {
+		    // JE: I must now store all the extensions
+		    for( Enumeration e2 = c.getExtensions().getNames() ; e2.hasMoreElements() ; ){
+			String tag = (String)e2.nextElement();
+			String s_method = c.getExtension(tag);
+			query = "INSERT INTO extension " + 
+			    "(id, tag, method) " +
+			    "VALUES ('" + quote(cellid) + "','" +  quote(tag) + "','" + quote(s_method) + "')";
 			st.executeUpdate(query);
 		    }
+		}
 	    }
 	} catch (Exception e) { e.printStackTrace(); };
 	// We reset cached date
@@ -454,13 +505,13 @@ public class CacheImpl implements Cache {
     //**********************************************************************
     // CACHE MANAGEMENT (Not implemented yet)
     public void resetCacheStamp( Alignment result ){
-	result.setExtension("fr.inrialpes.exmo.align.service.cached", new Date().toString() );
+	result.setExtension(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( ) ) {
+	// if ( DateFormat.parse( result.getExtension(CACHED) ).before( ) ) {
 	// - for each ontology if no other alignment => unload
 	// - clean up cells
 	// }
@@ -489,7 +540,8 @@ public class CacheImpl implements Cache {
       file1 varchar(250),
       file2 varchar(250),
       uri1 varchar(250),
-      uri2 varchar(250));
+      uri2 varchar(250),
+      primary key (id));
 
       # cell info
 
@@ -513,7 +565,7 @@ public class CacheImpl implements Cache {
 
     public void initDatabase() throws SQLException {
 	// Create tables
-	st.executeUpdate("CREATE TABLE alignment (id VARCHAR(100), owlontology1 VARCHAR(250), owlontology2 VARCHAR(250), type VARCHAR(5), level VARCHAR(1), file1 VARCHAR(250), file2 VARCHAR(250), uri1 VARCHAR(250), uri2 VARCHAR(250))");
+	st.executeUpdate("CREATE TABLE alignment (id VARCHAR(100), owlontology1 VARCHAR(250), owlontology2 VARCHAR(250), type VARCHAR(5), level VARCHAR(1), file1 VARCHAR(250), file2 VARCHAR(250), uri1 VARCHAR(250), uri2 VARCHAR(250), primary key (id))");
 	st.executeUpdate("CREATE TABLE cell(id VARCHAR(100), cell_id VARCHAR(250), uri1 VARCHAR(250), uri2 VARCHAR(250), semantics VARCHAR(30), measure VARCHAR(20), relation VARCHAR(5))");
 	st.executeUpdate("CREATE TABLE extension(id VARCHAR(100), tag VARCHAR(100), method VARCHAR(500))");
 	st.executeUpdate("CREATE TABLE server (host VARCHAR(50), port VARCHAR(5), edit BOOLEAN, version VARCHAR(5))");
diff --git a/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java b/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java
index 0d001cef2d9cc1a4c106c6153fd72c7f0ed4c948..1bce196e5753dd94084be4e0d995ba63aea1ecbe 100644
--- a/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java
+++ b/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java
@@ -247,7 +247,7 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 	if ( debug > 0 ) System.err.println("ADMIN["+perf+"]");
 	String msg = "";
         if ( perf.equals("listalignments") ){
-	    msg = "<h1>Stored alignments</h1><ul compact=\"1\">";
+	    msg = "<h1>Available 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>";
@@ -272,9 +272,10 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 	    }
 	    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>";
+	    msg = "<h1>SQL query</h1><form action=\"sqlquery\">Query: <input type=\"textarea\" name=\"query\" rows=\"8\"size=\"60\"/> (sql)<br /><small>An SQL SELECT query</small><br /><input type=\"submit\" value=\"Query\"/></form>";
 	} else if ( perf.equals("sqlquery") ){
-	    msg = "Not available yet";
+	    String answer = manager.query( (String)params.getParameter("query") );
+	    msg = "<pre>"+answer+"</pre>";
 	} else if ( perf.equals("about") ){
 	    msg = about();
 	} else if ( perf.equals("shutdown") ){
@@ -282,6 +283,8 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 	    msg = "Server shut down";
 	} else if ( perf.equals("prmreset") ){
 	    msg = perf;
+	} else if ( perf.equals("prmflush") ){
+	    msg = perf;
 	} else if ( perf.equals("addservice") ){
 	    msg = perf;
 	} else if ( perf.equals("addmethod") ){
@@ -297,6 +300,7 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 	    msg += "<li><form action=\"listrenderers\"><input type=\"submit\" value=\"Available renderers\"/></form></li>";
 	    msg += "<li><form action=\"listservices\"><input type=\"submit\" value=\"Available services\"/></form></li>";
 	    msg += "<li><form action=\"prmsqlquery\"><input type=\"submit\" value=\"SQL Query\"/></form></li>";
+	    msg += "<li><form action=\"prmflush\"><input type=\"submit\" value=\"Flush caches\"/></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=\"..\"><input type=\"submit\" value=\"About\"/></form></li>";
@@ -321,7 +325,10 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 	    // JE: only those non stored please (retrieve metadata + stored)
 	    for( Enumeration e = manager.alignments(); e.hasMoreElements(); ){
 		String id = ((Alignment)e.nextElement()).getExtension("id");
+		params.setParameter("id", id);
+		if ( !manager.storedAlignment( new Message(newId(),(Message)null,myId,serverId,"", params ) ) ){
 		msg += "<option value=\""+id+"\">"+id+"</option>";
+		}
 	    }
 	    msg += "</select><br />";
 	    msg += "<input type=\"submit\" value=\"Store\"/></form>";
@@ -430,12 +437,6 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 		String id = ((Alignment)e.nextElement()).getExtension("id");
 		msg += "<option value=\""+id+"\">"+id+"</option>";
 	    }
-	    msg += "</select><br />";
-	    msg += "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) );
diff --git a/src/org/semanticweb/owl/align/Cell.java b/src/org/semanticweb/owl/align/Cell.java
index ec011f1f3dbd3f74f9fe2165fcf07e5a8429f492..3ae02ee60259489d04a29beeccb08ba30c0837d7 100644
--- a/src/org/semanticweb/owl/align/Cell.java
+++ b/src/org/semanticweb/owl/align/Cell.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA Rhône-Alpes, 2003-2005
+ * Copyright (C) INRIA Rhône-Alpes, 2003-2005, 2007
  *
  * 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
@@ -62,6 +62,15 @@ public interface Cell
     public void setStrength( double m );
     public boolean equals( Cell c );
 
+    /**
+     * Extensions are a way to read and add other information (metadata)
+     * to the Cell structure itself.
+     */
+    public Parameters getExtensions();
+    public void setExtensions( Parameters param );
+    public String getExtension( String label );
+    public void setExtension( String label, String value );
+
     public Cell inverse() throws AlignmentException;
 
     /** Housekeeping **/