diff --git a/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java b/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java
index 6dc265371d0de918e64ab2dc7275ff9df6f41334..c84a8d31ff723a505e5d5a74c44a7976012cc14f 100644
--- a/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java
+++ b/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java
@@ -1,7 +1,8 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA Rh�ne-Alpes, 2003-2004
+ * Copyright (C) INRIA Rh�ne-Alpes, 2003-2005
+ * Copyright (C) CNR Pisa, 2005
  *
  * 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
@@ -18,19 +19,16 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-//Raph: are things to change for dealing with multiple cell
-// for one objects
-
 package fr.inrialpes.exmo.align.impl;
 
 import java.lang.ClassNotFoundException;
 import java.util.Hashtable;
-//Raph: 
 import java.util.HashSet;
 import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 import java.util.ArrayList;
 import java.io.PrintStream;
 import java.io.PrintWriter;
@@ -55,8 +53,11 @@ import org.semanticweb.owl.align.Relation;
  * collections. Each ontology has a number of classes, properties and
  * individuals, along with a number of axioms asserting information about those
  * objects.
+ *
+ * NOTE(JE): hashtabale are indexed by URI.
+ * This is strange, but there might be a reason
  * 
- * @author J�r�me Euzenat, David Loup
+ * @author J�r�me Euzenat, David Loup, Rapha�l Troncy
  * @version $Id$
  */
 
@@ -65,6 +66,9 @@ public class BasicAlignment implements Alignment {
 	visitor.visit(this);
     }
 
+    /* Set to true for rejecting the use of deprecated (non deterministic) primitives */
+    private boolean STRICT_IMPLEMENTATION = false;
+
     protected int debug = 0;
 
     protected String level = "0";
@@ -102,8 +106,12 @@ public class BasicAlignment implements Alignment {
     }
 
     public int nbCells() {
-	// Raph: this is now wrong: I need multi-enumeration
-	return hash1.size();
+	//-return hash1.size();
+	int sum = 0;
+	for ( Enumeration e = hash1.elements(); e.hasMoreElements(); ) {
+	    sum = sum + ((HashSet)e.nextElement()).size();
+	}
+	return sum;
     }
 
     /** Alignment methods * */
@@ -148,153 +156,260 @@ public class BasicAlignment implements Alignment {
     public void setFile2(URI u) { uri2 = u; };
 
     public Enumeration getElements() { 
-	//Raph: This should be a multi Enumeration:
-	return hash1.elements(); 
+	//-return hash1.elements(); 
+	return new MEnumeration( hash1 );
+    }
+
+    public ArrayList getArrayElements() {
+	ArrayList array = new ArrayList();
+	for (Enumeration e = getElements(); e.hasMoreElements(); ) {
+	    array.add( (BasicCell)e.nextElement() );
+	}
+	return array;
     }
 
-    /*
-     * Please note that all the following methods must be changed because they
-     * consider that only ONE Entity can be aligned with another !!
-     * A number of modifications are considered in the //Raph:
-     */
     /** Cell methods **/
-    public Cell addAlignCell(Object ob1, Object ob2, String relation,
-			     double measure) throws AlignmentException {
-	if ( !( ob1 instanceof OWLEntity && ob2 instanceof OWLEntity ) )
-	    throw new AlignmentException("addAlignCell: arguments must be OWLEntities");
-	    Cell cell = (Cell) new BasicCell((OWLEntity)ob1, (OWLEntity)ob2,
-					     relation, measure);
-	    addCell( (OWLEntity)ob1, (OWLEntity)ob2, cell );
-	    return cell;
+    //-public Cell addAlignCell(Object ob1, Object ob2, String relation,
+    //			     double measure) throws AlignmentException {
+    //	if ( !( ob1 instanceof OWLEntity && ob2 instanceof OWLEntity ) )
+    //	    throw new AlignmentException("addAlignCell: arguments must be OWLEntities");
+    //	    Cell cell = (Cell) new BasicCell((OWLEntity)ob1, (OWLEntity)ob2,
+    //					     relation, measure);
+    //	    addCell( (OWLEntity)ob1, (OWLEntity)ob2, cell );
+    //	    return cell;
+    //};
+    public Cell addAlignCell(Object ob1, Object ob2, String relation, double measure) throws AlignmentException {
+ 
+        if ( !( ob1 instanceof OWLEntity && ob2 instanceof OWLEntity ) )
+            throw new AlignmentException("addAlignCell: arguments must be OWLEntities");
+        try {
+            Cell cell = (Cell) new BasicCell((OWLEntity) ob1, (OWLEntity) ob2, relation, measure);
+            HashSet s1 = (HashSet)hash1.get((Object)(((OWLEntity)ob1).getURI()));
+            if (s1 == null) {
+                s1 = new HashSet();
+                hash1.put((Object)(((OWLEntity)ob1).getURI()),s1);
+            }
+            s1.add(cell);
+            HashSet s2 = (HashSet)hash2.get((Object)(((OWLEntity)ob2).getURI()));
+            if (s2 == null) {
+                s2 = new HashSet(); 
+                hash2.put((Object)(((OWLEntity)ob2).getURI()),s2);
+            } 
+            s2.add(cell);
+            return cell;
+        } catch (OWLException e) {
+            throw new AlignmentException("getURI problem", e);
+        }
     };
 
     public Cell addAlignCell(Object ob1, Object ob2) throws AlignmentException {
 	return addAlignCell( ob1, ob2, "=", 1. );
     }
 
-    public void addCell( OWLEntity ob1, OWLEntity ob2, Cell cell ) throws AlignmentException {
-	try {
-	    //Raph: 
-	    //HashSet s1 = hash1.get((Object)(((OWLEntity)ob1).getURI()));
-	    //if ( s1 == null ){
-	    //	s1 = new HashSet();
-	    //	hash1.put((Object)(((OWLEntity)ob1).getURI()),s1);
-	    //}
-	    //s1.add(cell);
-	    hash1.put((Object)(((OWLEntity)ob1).getURI()), cell);
-	    //Raph: 
-	    //HashSet s1 = hash1.get((Object)(((OWLEntity)ob1).getURI()));
-	    //if ( s2 == null ){
-	    //	s2 = new HashSet();
-	    //	hash2.put((Object)(((OWLEntity)ob2).getURI()),s2);
-	    //}
-	    //s2.add(cell);
-	    hash2.put((Object)(((OWLEntity)ob2).getURI()), cell);
-	} catch (OWLException e) {
-	    throw new AlignmentException("getURI problem", e);
-	}
+    //-
+    //public void addCell( OWLEntity ob1, OWLEntity ob2, Cell cell ) throws AlignmentException {
+    //	try {
+    //	    hash1.put((Object)(((OWLEntity)ob1).getURI()), cell);
+    //	    hash2.put((Object)(((OWLEntity)ob2).getURI()), cell);
+    //	} catch (OWLException e) {
+    //	    throw new AlignmentException("getURI problem", e);
+    //	}
+    //}
+    protected void addCell( Cell c ) throws AlignmentException {
+        try {
+            HashSet s1 = (HashSet)hash1.get(((OWLEntity)c.getObject1()).getURI());
+	    if( s1 != null ){
+		s1.add( c ); // I must check that there is no one here
+	    } else {
+		s1 = new HashSet();
+		hash1.put(((OWLEntity)c.getObject1()).getURI(),s1);
+		s1.add( c );
+	    }
+
+            HashSet s2 = (HashSet)hash2.get(((OWLEntity)c.getObject2()).getURI());
+	    if( s2 != null ){
+		s2.add( c ); // I must check that there is no one here
+	    } else {
+		s2 = new HashSet();
+		hash2.put(((OWLEntity)c.getObject2()).getURI(),s2);
+		s2.add( c );
+	    }
+
+        } catch (OWLException ex) {
+            throw new AlignmentException("getURI problem", ex);
+        }
     }
 
-    // Raph:
-    public Iterator getAlignCells1(Object ob) throws AlignmentException {
+    // Beware, the catch applies both for getURI and OWLException
+    public Set getAlignCells1(Object ob) throws AlignmentException {
 	if ( ob instanceof OWLEntity ){
-	    HashSet s = null;
-	    try { s = (HashSet)hash1.get(((OWLEntity)ob).getURI()); }
-	    catch (OWLException e) { throw new AlignmentException("getURI problem", e); }
-	    if ( s == null ) { return null; }
-	    else { return s.iterator(); }
+	    try{ return (HashSet)hash1.get(((OWLEntity)ob).getURI());
+	    } catch (Exception e) { return null;}
 	} else {
-	    throw new AlignmentException("getAlignCell1: argument must be OWLEntity");
+	    throw new AlignmentException("getAlignCells1: argument must be OWLEntity");
+	}
+    }
+    public Set getAlignCells2(Object ob) throws AlignmentException {
+	if ( ob instanceof OWLEntity ){
+	    try{ return (HashSet)hash2.get(((OWLEntity)ob).getURI());
+	    } catch (Exception e) { return null;}
+	} else {
+	    throw new AlignmentException("getAlignCells1: argument must be OWLEntity");
 	}
     }
 
+    // Deprecated: implement as the one retrieving the highest strength correspondence (
     public Cell getAlignCell1(Object ob) throws AlignmentException {
-	if ( ob instanceof OWLEntity ){
-	    try { return (Cell) hash1.get(((OWLEntity) ob).getURI()); }
-	    catch (OWLException e) { throw new AlignmentException("getURI problem", e); }
+	if ( STRICT_IMPLEMENTATION == true ){
+	    throw new AlignmentException("getAlignCell1: deprecated (use getAlignCells1 instead)");
 	} else {
-	    throw new AlignmentException("getAlignCell1: argument must be OWLEntity");
+	    if ( ob instanceof OWLEntity ){
+		try { 
+		    Set s2 = (Set)hash1.get(((OWLEntity) ob).getURI());
+		    Cell bestCell = null;
+		    double bestStrength = 0.;
+		    if ( s2 != null ) {
+			for( Iterator it2 = s2.iterator(); it2.hasNext(); ){
+			    Cell c = (Cell)it2.next();
+			    double val = c.getStrength();
+			    if ( val > bestStrength ) {
+				bestStrength = val;
+				bestCell = c;
+			    }
+			}
+		    }
+		    return bestCell;
+		} catch (OWLException e) { throw new AlignmentException("getURI problem", e); }
+	    } else {
+		throw new AlignmentException("getAlignCell1: argument must be OWLEntity");
+	    }
 	}
     }
 
     public Cell getAlignCell2(Object ob) throws AlignmentException {
-	if ( ob instanceof OWLEntity ){
-	    try { return (Cell) hash2.get(((OWLEntity) ob).getURI()); }
-	    catch (OWLException e) { throw new AlignmentException("getURI problem", e); }
+	if ( STRICT_IMPLEMENTATION == true ){
+	    throw new AlignmentException("getAlignCell2: deprecated (use getAlignCells2 instead)");
 	} else {
-	    throw new AlignmentException("getAlignCell2: argument must be OWLEntity");
+	    if ( ob instanceof OWLEntity ){
+		try { 
+		    Set s1 = (Set)hash2.get(((OWLEntity) ob).getURI());
+		    Cell bestCell = null;
+		    double bestStrength = 0.;
+		    if ( s1 != null ){
+			for( Iterator it1 = s1.iterator(); it1.hasNext(); ){
+			    Cell c = (Cell)it1.next();
+			    double val = c.getStrength();
+			    if ( val > bestStrength ) {
+				bestStrength = val;
+				bestCell = c;
+			    }
+			}
+		    }
+		    return bestCell;
+		} catch (OWLException e) { throw new AlignmentException("getURI problem", e); }
+	    } else {
+		throw new AlignmentException("getAlignCell2: argument must be OWLEntity");
+	    }
 	}
     }
 
+    //- Deprecated
     public Object getAlignedObject1(Object ob) throws AlignmentException {
 	Cell c = getAlignCell1(ob);
 	if (c != null) return c.getObject2();
 	else return null;
     };
 
+    //- Deprecated
     public Object getAlignedObject2(Object ob) throws AlignmentException {
 	Cell c = getAlignCell2(ob);
 	if (c != null) return c.getObject1();
 	else return null;
     };
 
+    //- Deprecated
     public Relation getAlignedRelation1(Object ob) throws AlignmentException {
 	Cell c = getAlignCell1(ob);
 	if (c != null) return c.getRelation();
 	else return (Relation) null;
     };
 
+    //- Deprecated
     public Relation getAlignedRelation2(Object ob) throws AlignmentException {
 	Cell c = getAlignCell2(ob);
 	if (c != null) return c.getRelation();
 	else return (Relation) null;
     };
 
+    //- Deprecated
     public double getAlignedStrength1(Object ob) throws AlignmentException {
 	Cell c = getAlignCell1(ob);
 	if (c != null) return c.getStrength();
 	else return 0;
     };
 
+    //- Deprecated
     public double getAlignedStrength2(Object ob) throws AlignmentException {
 	Cell c = getAlignCell2(ob);
 	if (c != null) return c.getStrength();
 	else return 0;
     };
 
-    //Raph:
+    //-
+    //public void removeAlignCell(Cell c) throws AlignmentException {
+    //try {
+    //    HashSet s1 = (HashSet)hash1.get(((OWLEntity)c.getObject1()).getURI());
+    //    HashSet s2 = (HashSet)hash2.get(((OWLEntity)c.getObject2()).getURI());
+    //    s1.remove(c);
+    //    s2.remove(c);
+    //} catch (OWLException ex) {
+    //    throw new AlignmentException("getURI problem", ex);
+    //}
+    //}
+
     public void removeAlignCell(Cell c) throws AlignmentException {
-	try {
-	    HashSet s1 = (HashSet)hash1.get(((OWLEntity)c.getObject1()).getURI());
-	    HashSet s2 = (HashSet)hash2.get(((OWLEntity)c.getObject2()).getURI());
-	    s1.remove(c);
-	    s2.remove(c);
-	} catch (OWLException ex) {
-	    throw new AlignmentException("getURI problem", ex);
-	}
+        try {
+            HashSet s1 = (HashSet)hash1.get(((OWLEntity)c.getObject1()).getURI());
+            HashSet s2 = (HashSet)hash2.get(((OWLEntity)c.getObject2()).getURI());
+            s1.remove(c);
+            s2.remove(c);
+            if (s1.isEmpty())
+                hash1.remove(((OWLEntity) c.getObject1()).getURI());
+            if (s2.isEmpty())
+                hash2.remove(((OWLEntity) c.getObject2()).getURI());
+        } catch (OWLException ex) {
+            throw new AlignmentException("getURI problem", ex);
+        }
     }
 
     /***************************************************************************
      * The cut function suppresses from an alignment all the cell over a
      * particulat threshold
      **************************************************************************/
+    //-public void cut2(double threshold) throws AlignmentException {
+    //	for (Enumeration e = hash1.keys(); e.hasMoreElements();) {
+    //	    Cell c = (Cell) hash1.get(e.nextElement());
+    //	    if (c.getStrength() < threshold) {
+    //		// Beware, this suppresses all cells with these keys
+    //		// There is only one of them
+    //		try {
+    //		    //Raph:
+    //		    //removeAlignCell( c );
+    //		    hash1.remove(((OWLEntity) c.getObject1()).getURI());
+    //		    hash2.remove(((OWLEntity) c.getObject2()).getURI());
+    //		} catch (OWLException ex) {
+    //		    throw new AlignmentException("getURI problem", ex);
+    //		}
+    //	    }
+    //	} //end for
+    //   };
     public void cut2(double threshold) throws AlignmentException {
-	for (Enumeration e = hash1.keys(); e.hasMoreElements();) {
-	    Cell c = (Cell) hash1.get(e.nextElement());
-	    if (c.getStrength() < threshold) {
-		// Beware, this suppresses all cells with these keys
-		// There is only one of them
-		try {
-		    //Raph:
-		    //removeAlignCell( c );
-		    hash1.remove(((OWLEntity) c.getObject1()).getURI());
-		    hash2.remove(((OWLEntity) c.getObject2()).getURI());
-		} catch (OWLException ex) {
-		    throw new AlignmentException("getURI problem", ex);
-		}
-	    }
-	} //end for
-    };
+	for (Enumeration e = getElements(); e.hasMoreElements(); ) {
+	    Cell c = (Cell)e.nextElement();
+	    if (c.getStrength() < threshold)
+		removeAlignCell( c );
+	}
+    }
 
 
     /***************************************************************************
@@ -313,13 +428,63 @@ public class BasicAlignment implements Alignment {
      * - getting the under n% of the best (prop)
      * - getting the n best values
      **************************************************************************/
-    public void cut( String method, double threshold ) throws AlignmentException {
+    //-public void cut( String method, double threshold ) throws AlignmentException {
+    //	// Check that threshold is a percent
+    //	if ( threshold > 1. || threshold < 0. )
+    //	    throw new AlignmentException( "Not a percentage or threshold : "+threshold );
+    //	// Create a sorted list of cells
+    //	// Raph: this will not work anymore
+    //	List buffer = new ArrayList( hash1.values() );
+    //	Collections.sort( buffer );
+    //	int size = buffer.size();
+    //	boolean found = false;
+    //	int i = 0;
+    //	// Depending on the method, find the limit
+    //	if ( method.equals("hard") ){
+    //	    for( i=0; i < size && !found ; i++ ) {
+    //		if ( ((Cell)buffer.get(i)).getStrength() <= threshold ) found = true;
+    //	    }
+    //	} else if ( method.equals("span") ){
+    //	    double max = ((Cell)buffer.get(0)).getStrength() -threshold;
+    //	    for( i=0; i < size && !found ; i++ ) {
+    //		if ( ((Cell)buffer.get(i)).getStrength() <= max ) found = true;
+    //	    }
+    //	} else if ( method.equals("prop") ){
+    //	    double max = ((Cell)buffer.get(0)).getStrength() * (1-threshold);
+    //	    for( i=0; i < size && !found ; i++ ) {
+    //		if ( ((Cell)buffer.get(i)).getStrength() <= max ) found = true;
+    //	    }
+    //	} else if ( method.equals("perc") ){
+    //	    i = (new Double(size*threshold)).intValue();
+    //	} else if ( method.equals("best") ){
+    //	    i=(new Double(threshold)).intValue();
+    //	} else throw new AlignmentException( "Not a cut specification : "+method );
+    //	// Flush the structure
+    //	for( size-- ; size > i ; size-- ) buffer.remove(size);
+    //	// Introduce the result back in the structure
+    //	size = i;
+    //	hash1.clear();
+    //	hash2.clear();
+    //	try {
+    //	    for( i = 0; i < size; i++ ) {
+    //		Cell c = (Cell)buffer.get(i);
+    //		hash1.put((Object) (((OWLEntity)c.getObject1()).getURI()), c);
+    //		hash2.put((Object) (((OWLEntity)c.getObject2()).getURI()), c);
+    //	    }
+    //	} catch (OWLException e) {
+    //	    throw new AlignmentException("getURI problem", e);
+    //	}
+    //    };
+    public void cut( String method, double threshold ) throws AlignmentException
+    {
 	// Check that threshold is a percent
 	if ( threshold > 1. || threshold < 0. )
 	    throw new AlignmentException( "Not a percentage or threshold : "+threshold );
 	// Create a sorted list of cells
+	// For sure with sorted lists, we could certainly do far better
 	// Raph: this will not work anymore
-	List buffer = new ArrayList( hash1.values() );
+	//List buffer = new ArrayList( hash1.values() );
+	List buffer = getArrayElements();
 	Collections.sort( buffer );
 	int size = buffer.size();
 	boolean found = false;
@@ -350,37 +515,43 @@ public class BasicAlignment implements Alignment {
 	size = i;
 	hash1.clear();
 	hash2.clear();
-	try {
-	    for( i = 0; i < size; i++ ) {
-		Cell c = (Cell)buffer.get(i);
-		hash1.put((Object) (((OWLEntity)c.getObject1()).getURI()), c);
-		hash2.put((Object) (((OWLEntity)c.getObject2()).getURI()), c);
-	    }
-	} catch (OWLException e) {
-	    throw new AlignmentException("getURI problem", e);
+	for( i = 0; i < size; i++ ) {
+	    addCell( (Cell)buffer.get(i) );
+	    // OLD Stuff pre-v2
+	    //hash1.put((Object) (((OWLEntity)c.getObject1()).getURI()), c);
+	    //hash2.put((Object) (((OWLEntity)c.getObject2()).getURI()), c);
 	}
     };
 
     /***************************************************************************
      * The harden function acts like threshold but put all weights to 1.
      **************************************************************************/
+    //-public void harden(double threshold) throws AlignmentException {
+    //	for (Enumeration e = hash1.keys(); e.hasMoreElements();) {
+    //	    Cell c = (Cell) hash1.get(e.nextElement());
+    //	    if (c.getStrength() < threshold) {
+    //		// Beware, this suppresses all cells with these keys
+    //		// There is only one of them
+    //		try {
+    //		    hash1.remove(((OWLEntity) c.getObject1()).getURI());
+    //		    hash2.remove(((OWLEntity) c.getObject2()).getURI());
+    //		} catch (OWLException ex) {
+    //		    throw new AlignmentException("getURI problem", ex);
+    //		}
+    //	    } else {
+    //		c.setStrength(1.);
+    //	    }
+    //	} //end for
+    //    };
     public void harden(double threshold) throws AlignmentException {
-	for (Enumeration e = hash1.keys(); e.hasMoreElements();) {
-	    Cell c = (Cell) hash1.get(e.nextElement());
-	    if (c.getStrength() < threshold) {
-		// Beware, this suppresses all cells with these keys
-		// There is only one of them
-		try {
-		    hash1.remove(((OWLEntity) c.getObject1()).getURI());
-		    hash2.remove(((OWLEntity) c.getObject2()).getURI());
-		} catch (OWLException ex) {
-		    throw new AlignmentException("getURI problem", ex);
-		}
-	    } else {
+	for (Enumeration e = getElements(); e.hasMoreElements();) {
+	    Cell c = (Cell)e.nextElement();
+	    if (c.getStrength() < threshold)
+		removeAlignCell( c );
+	    else
 		c.setStrength(1.);
-	    }
-	} //end for
-    };
+	}
+    }
 
    /**
      * The second alignment is meet with the first one meaning that for
@@ -446,22 +617,28 @@ public class BasicAlignment implements Alignment {
     };
 
     /**
-     * Incorporate the cell of the alignment into it own alignment. Note: for
+     * Incorporate the cells of the alignment into its own alignment. Note: for
      * the moment, this does not copy but really incorporates. So, if hardening
      * or cutting, are applied, then the ingested alignmment will be modified as
      * well.
      */
+    //-
+    //protected void ingest(Alignment alignment) throws AlignmentException {
+    //	for (Enumeration e = alignment.getElements(); e.hasMoreElements();) {
+    //	    Cell c = (Cell) e.nextElement();
+    //	    try {
+    //		hash1.put((Object) ((OWLEntity) c.getObject1()).getURI(), c);
+    //		hash2.put((Object) ((OWLEntity) c.getObject2()).getURI(), c);
+    //	    } catch (OWLException ex) {
+    //		throw new AlignmentException("getURI problem", ex);
+    //	    }
+    //	}
+    //    };
     protected void ingest(Alignment alignment) throws AlignmentException {
 	for (Enumeration e = alignment.getElements(); e.hasMoreElements();) {
-	    Cell c = (Cell) e.nextElement();
-	    try {
-		hash1.put((Object) ((OWLEntity) c.getObject1()).getURI(), c);
-		hash2.put((Object) ((OWLEntity) c.getObject2()).getURI(), c);
-	    } catch (OWLException ex) {
-		throw new AlignmentException("getURI problem", ex);
-	    }
-	}
-    };
+	    addCell((Cell)e.nextElement());
+	};
+    }
 
     /**
      * This should be rewritten in order to generate the axiom ontology instead
@@ -472,3 +649,30 @@ public class BasicAlignment implements Alignment {
 	accept(renderer);
     }
 }
+
+class MEnumeration implements Enumeration {
+    private Enumeration set = null; // The enumeration of sets
+    private Iterator current = null; // The current set's enumeration
+
+    MEnumeration( Hashtable s ){
+	set = s.elements();
+	while( set.hasMoreElements() && current == null ){
+	    current = ((Set)set.nextElement()).iterator();
+	    if( !current.hasNext() ) current = null;
+	}
+    }
+    public boolean hasMoreElements(){
+	return ( current != null);
+    }
+    public Object nextElement(){
+	Object val = current.next();
+	if( !current.hasNext() ){
+	    current = null;
+	    while( set.hasMoreElements() && current == null ){
+		current = ((Set)set.nextElement()).iterator();
+		if( !current.hasNext() ) current = null;
+	    }
+	}
+	return val;
+    }
+}