[Arakhnę-Dev] [319] * Reimplement the Weak maps.

[ Thread Index | Date Index | More arakhne.org/dev Archives ]


Revision: 319
Author:   galland
Date:     2011-12-17 12:43:54 +0100 (Sat, 17 Dec 2011)
Log Message:
-----------
* Reimplement the Weak maps.
* Provide HashMap- and TreeMap-based implementation of the weak maps.
* Support Weak, Soft and Phantom references.

Modified Paths:
--------------
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java

Added Paths:
-----------
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractPhantomValueMap.java
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractReferencedValueMap.java
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractSoftValueMap.java
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakValueMap.java
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueHashMap.java
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueTreeMap.java
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueHashMap.java
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueTreeMap.java
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueHashMap.java
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueTreeMap.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractCollectionTestCase.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractMapTestCase.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractReferencableValueMapTestCase.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractTestCase.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractWeakCollectionTestCase.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueHashMapTest.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueTreeMapTest.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueHashMapTest.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueTreeMapTest.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueHashMapTest.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueTreeMapTest.java

Removed Paths:
-------------
    trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java
    trunk/arakhneRefs/src/test/java/org/arakhne/junit/
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java
    trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java

Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractPhantomValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractPhantomValueMap.java	                        (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractPhantomValueMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,63 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2009 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.ReferenceQueue;
+import java.util.Map;
+
+/**
+ * A <tt>Map</tt> implementation with <em>phantom values</em>. An entry in a
+ * <tt>AbstractPhantomValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or <code>null</code>.
+ * <p>
+ * This abstract implementation does not decide if the map is based on a tree or on a hashtable.
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public abstract class AbstractPhantomValueMap<K,V> extends AbstractReferencedValueMap<K,V> {
+	
+	/**
+     * Constructs an empty <tt>Map</tt>.
+     *
+     * @param  map is the map instance to use to store the entries.
+     * @throws IllegalArgumentException if the initial capacity is negative
+     *         or the load factor is nonpositive
+     */
+    public AbstractPhantomValueMap(Map<K,ReferencableValue<K,V>> map) {
+        super(map);
+    }
+
+    /** {@inheritDoc}
+	 */
+	@Override
+	protected final ReferencableValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
+		return new PhantomReferencedValue<K,V>(k, v, queue);
+	}
+
+}


Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractPhantomValueMap.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractReferencedValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractReferencedValueMap.java	                        (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractReferencedValueMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,902 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2009 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Array;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A <tt>Map</tt> implementation with <em>weak/soft values</em>. An entry in a
+ * <tt>AbstractReferencedValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or <code>null</code>.
+ * <p>
+ * This abstract implementation does not decide if the map is based on a tree or on a hashtable;
+ * it does not impose soft or weak references.
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public abstract class AbstractReferencedValueMap<K,V> extends AbstractMap<K,V> {
+
+	/** Defines the NULL object inside a WeakValueMap.
+	 * 
+	 * @see #maskNull(Object)
+	 */
+	protected static final Object NULL_VALUE = new Object();
+
+	/** Mask the null values given by the used of this map.
+	 * <p>
+	 * This method replaces the <code>null</code> value by
+	 * the internal representation {@link #NULL_VALUE}.
+	 *
+	 * @param <MV> is the type of the value.
+	 * @param value is the value given by the user of this map.
+	 * @return the internal representation of the value.
+	 * @see #unmaskNull(Object)
+	 */
+	@SuppressWarnings("unchecked")
+	protected static <MV> MV maskNull(MV value) {
+		return (value==null) ? (MV)NULL_VALUE : value;
+	}
+
+	/** Unmask the null values given by the used of this map.
+	 * <p>
+	 * This method replaces the internal representation
+	 * {@link #NULL_VALUE} of null values by its user representation
+	 * <code>null</code>.
+	 * 
+	 * @param <MV> is the type of the value.
+	 * @param value is the value given by the user of this map.
+	 * @return the internal representation of the value.
+	 * @see #maskNull(Object)
+	 */
+	protected static <MV> MV unmaskNull(MV value) {
+		return (value==NULL_VALUE) ? null : value;
+	}
+
+	/**
+	 * Reallocates the array being used within toArray when the iterator
+	 * returned more elements than expected, and finishes filling it from
+	 * the iterator.
+	 *
+	 * @param r the array, replete with previously stored elements
+	 * @param it the in-progress iterator over this collection
+	 * @return array containing the elements in the given array, plus any
+	 *         further elements returned by the iterator, trimmed to size
+	 */
+	@SuppressWarnings("unchecked")
+	static <T> T[] finishToArray(T[] r, Iterator<?> it) {
+		T[] rp = r;
+		int i = rp.length;
+		while (it.hasNext()) {
+			int cap = rp.length;
+			if (i == cap) {
+				int newCap = ((cap / 2) + 1) * 3;
+				if (newCap <= cap) { // integer overflow
+					if (cap == Integer.MAX_VALUE)
+						throw new OutOfMemoryError("Required array size too large"); //$NON-NLS-1$
+					newCap = Integer.MAX_VALUE;
+				}
+				rp = Arrays.copyOf(rp, newCap);
+			}
+			rp[++i] = (T)it.next();
+		}
+		// trim if overallocated
+		return (i == rp.length) ? rp : Arrays.copyOf(rp, i);
+	}
+
+	private boolean autoExpurge = false;
+	private final ReferenceQueue<V> queue = new ReferenceQueue<V>();
+
+	/** Internal map.
+	 */
+	protected final Map<K,ReferencableValue<K,V>> map;
+
+	/**
+	 * Constructs an empty <tt>Map</tt>.
+	 *
+	 * @param  map is the map instance to use to store the entries.
+	 * @throws IllegalArgumentException if the initial capacity is negative
+	 *         or the load factor is nonpositive
+	 */
+	public AbstractReferencedValueMap(Map<K,ReferencableValue<K,V>> map) {
+		this.map = map;
+	}
+
+	/** Clean the references that was marked as released inside
+	 * the queue.
+	 */
+	protected final void expurgeNow() {
+		if (this.autoExpurge)
+			expurge();
+		else
+			expurgeQueuedReferences();
+	}
+
+	/** Replies if this map expurge all the released references
+	 * even if they are not enqueued by the virtual machine
+	 * 
+	 * @return <code>true</code> is the values are deeply expurged when they
+	 * are released from the moemory, otherwise <code>false</code>
+	 */
+	public final boolean isDeeplyExpurge() {
+		return this.autoExpurge;
+	}
+
+	/** Set if this map expurge all the released references
+	 * even if they are not enqueued by the virtual machine
+	 * 
+	 * @param deeplyExpurge must be <code>true</code> to
+	 * expurge all the released values, otherwise <code>false</code>
+	 * to expurge only the enqueued values.
+	 * @return the old value of this flag
+	 */
+	public final boolean setDeeplyExpurge(boolean deeplyExpurge) {
+		boolean old = this.autoExpurge;
+		this.autoExpurge = deeplyExpurge;
+		return old;
+	}
+
+	/** Clean the references that was marked as released inside
+	 * the queue.
+	 */
+	public final void expurgeQueuedReferences() {
+		Reference<? extends V> o;
+		while((o = this.queue.poll()) != null) {
+			if (o instanceof ReferencableValue<?,?>) {
+				this.map.remove(((ReferencableValue<?,?>)o).getKey());
+			}
+			o.clear();
+		}
+	}
+
+	/** Clean the references that was released.
+	 */
+	public final void expurge() {
+		Reference<? extends V> o;
+
+		Iterator<Entry<K,ReferencableValue<K,V>>> iter = this.map.entrySet().iterator();
+		Entry<K,ReferencableValue<K,V>> entry;
+		ReferencableValue<K,V> value;
+		while (iter.hasNext()) {
+			entry = iter.next();
+			if (entry!=null) {
+				value = entry.getValue();
+				if ((value!=null)&&
+						((value.isEnqueued())||(value.get()==null))) {
+					value.enqueue();
+					value.clear();
+				}
+			}
+		}
+		entry = null;
+		value = null;
+
+		while((o = this.queue.poll()) != null) {
+			if (o instanceof ReferencableValue<?,?>) {
+				this.map.remove(((ReferencableValue<?,?>)o).getKey());
+			}
+			o.clear();
+		}
+	}
+
+	/** Create a storage object that permits to put the specified
+	 * elements inside this map.
+	 * 
+	 * @param k is the key associated to the value
+	 * @param v is the value
+	 * @param refQueue is the reference queue to use
+	 * @return the new storage object
+	 */
+	protected abstract ReferencableValue<K,V> makeValue(K k, V v, ReferenceQueue<V> refQueue);
+
+	/** Create a storage object that permits to put the specified
+	 * elements inside this map.
+	 * 
+	 * @param k is the key associated to the value
+	 * @param v is the value
+	 * @return the new storage object
+	 */
+	protected final ReferencableValue<K,V> makeValue(K k, V v) {
+		return makeValue(k, v, this.queue);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public final V put(K key, V value) {
+		expurgeNow();
+		ReferencableValue<K,V> ret = this.map.put(key, makeValue(key, value, this.queue));
+		if(ret == null) return null;
+		return ret.getValue();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public final Set<Entry<K,V>> entrySet() {
+		expurgeNow();
+		return new InnerEntrySet();
+	}	
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public final boolean equals(Object o) {
+		expurgeNow();
+		return super.equals(o);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public final int hashCode() {
+		expurgeNow();
+		return super.hashCode();
+	}
+
+	/**
+	 * This interface provides information about the pairs inside
+	 * a map with weak/soft reference values.
+	 * 
+	 * @param <K> is the type of the map keys.
+	 * @param <V> is the type of the map values.
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 */
+	protected static interface ReferencableValue<K,V> extends Entry<K,V> {
+
+		/**
+		 * @return if the value is enqueued into a reference queue.
+		 */
+		public boolean isEnqueued();
+
+		/**
+		 * @return the weak/soft reference.
+		 */
+		public V get();
+
+		/**
+		 * @return if the value was enqueued
+		 */
+		public boolean enqueue();
+
+		/**
+		 */
+		public void clear();
+
+	} // interface ReferencableValue
+
+	/**
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 */
+	private class InnerEntrySet implements Set<Entry<K,V>> {
+
+		/**
+		 */
+		public InnerEntrySet() {
+			//
+		}
+
+		@Override
+		public final boolean add(java.util.Map.Entry<K, V> e) {
+			K key = e.getKey();
+			V value = e.getValue();
+			return AbstractReferencedValueMap.this.map.put(key, makeValue(key, value)) == null;
+		}
+
+		@Override
+		public final boolean addAll(Collection<? extends java.util.Map.Entry<K, V>> c) {
+			boolean changed = true;
+			for(java.util.Map.Entry<K, V> entry : c) {
+				changed = add(entry) | changed;
+			}
+			return changed;
+		}
+
+		@Override
+		public final void clear() {
+			AbstractReferencedValueMap.this.map.clear();
+		}
+
+		@Override
+		public final boolean contains(Object o) {
+			if (o instanceof Entry<?,?>) {
+				try {
+					expurgeNow();
+					return AbstractReferencedValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
+				}
+				catch(AssertionError e) {
+					throw e;
+				}
+				catch(Throwable _) {
+					//
+				}
+			}
+			return false;
+		}
+
+		@Override
+		public final boolean containsAll(Collection<?> c) {
+			boolean ok;
+			expurgeNow();
+			for(Object o : c) {
+				ok = false;
+				if (o instanceof Entry<?,?>) {
+					try {
+						ok = AbstractReferencedValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
+					}
+					catch(AssertionError e) {
+						throw e;
+					}
+					catch(Throwable _) {
+						//
+					}
+				}
+				if (!ok) return false;
+			}
+			return true;
+		}
+
+		@Override
+		public final boolean isEmpty() {
+			expurgeNow();
+			return AbstractReferencedValueMap.this.map.isEmpty();
+		}
+
+		@Override
+		public final Iterator<java.util.Map.Entry<K, V>> iterator() {
+			return new InnerIterator();
+		}
+
+		@Override
+		public final boolean remove(Object o) {
+			if (o instanceof Entry<?,?>) {
+				try {
+					return AbstractReferencedValueMap.this.map.remove(((Entry<?,?>)o).getKey())!=null;
+				}
+				catch(AssertionError e) {
+					throw e;
+				}
+				catch(Throwable _) {
+					//
+				}
+			}
+			return false;
+		}
+
+		@Override
+		public final boolean removeAll(Collection<?> c) {
+			boolean changed = true;
+			for(Object o : c) {
+				changed = remove(o) || changed;
+			}
+			return changed;
+		}
+
+		@Override
+		public final boolean retainAll(Collection<?> c) {
+			expurgeNow();
+			Collection<K> keys = AbstractReferencedValueMap.this.map.keySet();
+			Iterator<K> iterator = keys.iterator();
+			K key;
+			boolean changed = false;
+			while (iterator.hasNext()) {
+				key = iterator.next();
+				if (!c.contains(key)) {
+					iterator.remove();
+					changed = true;
+				}
+			}
+			return changed;
+		}
+
+		@Override
+		public final int size() {
+			expurgeNow();
+			return AbstractReferencedValueMap.this.map.size();
+		}
+
+		@Override
+		public final Object[] toArray() {
+			expurgeNow();
+			Object[] tab = new Object[AbstractReferencedValueMap.this.map.size()];
+			return toArray(tab);
+		}
+
+		@SuppressWarnings("unchecked")
+		@Override
+		public final <T> T[] toArray(T[] a) {
+			expurgeNow();
+			// Estimate size of array; be prepared to see more or fewer elements
+			int size = AbstractReferencedValueMap.this.map.size();
+			T[] r = a.length >= size ? a :
+				(T[])Array.newInstance(a.getClass().getComponentType(), size);
+			Iterator<Entry<K,V>> it = iterator();
+
+			for (int i=0; i<r.length; ++i) {
+				if (!it.hasNext()) { // fewer elements than expected
+					if (a != r) {
+						return Arrays.copyOf(r, i);
+					}
+					r[i] = null; // null-terminate
+					return r;
+				}
+				r[i] = (T)it.next();
+			}
+			return it.hasNext() ? finishToArray(r, it) : r;
+		}
+
+	} // class InnerEntrySet
+
+	/**
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 */
+	private class InnerIterator implements Iterator<Entry<K,V>> {
+
+		private final Iterator<Entry<K,ReferencableValue<K,V>>> originalIterator;
+		private Entry<K,V> next = null;
+		private boolean nextSearchProceeded = false;
+		private boolean enableRemove = false;
+
+		public InnerIterator() {
+			this.originalIterator = AbstractReferencedValueMap.this.map.entrySet().iterator();
+		}
+
+		private void searchNext() {
+			if (!this.nextSearchProceeded) {
+				this.nextSearchProceeded = true;
+				this.next = null;
+				Entry<K,ReferencableValue<K,V>> originalNext;
+				ReferencableValue<K,V> wValue;
+				while (this.next==null && this.originalIterator.hasNext()) {
+					originalNext = this.originalIterator.next();
+					if (originalNext!=null) {
+						wValue = originalNext.getValue();
+						if (wValue!=null) {
+							this.next = new InnerEntry(
+									originalNext.getKey(),
+									wValue.getValue(),
+									originalNext);
+							return;
+						}
+						// Remove the original entry because the pointer was lost.
+						this.originalIterator.remove();
+					}
+				}
+			}	
+		}
+
+		@Override
+		public boolean hasNext() {
+			searchNext();
+			assert(this.nextSearchProceeded);
+			this.enableRemove = false;
+			return this.next!=null;
+		}
+
+		@Override
+		public java.util.Map.Entry<K, V> next() {
+			searchNext();
+			assert(this.nextSearchProceeded);
+			Entry<K,V> cnext = this.next;
+
+			// Reset the research flags
+			this.next = null;
+			this.nextSearchProceeded = false;
+			this.enableRemove = true;
+
+			return cnext;
+		}
+
+		@Override
+		public void remove() {
+			if (!this.enableRemove)
+				throw new IllegalStateException("you must not invoke the remove function between hasNext and next functions."); //$NON-NLS-1$
+			this.originalIterator.remove();
+		}
+
+	} // class InnerIterator
+
+	/**
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 */
+	private class InnerEntry implements Entry<K,V> {
+
+		private final Entry<K,ReferencableValue<K,V>> original;
+		private final K key;
+		private V value;
+
+		public InnerEntry(K k, V v, Entry<K,ReferencableValue<K,V>> o) {
+			this.original = o;
+			this.key = k;
+			this.value = v;
+		}
+
+		@Override
+		public K getKey() {
+			return this.key;
+		}
+
+		@Override
+		public V getValue() {
+			return this.value;
+		}
+
+		@Override
+		public V setValue(V value) {
+			this.value = value;
+			return this.original.getValue().setValue(value);
+		}
+
+	} // class InnerEntry
+
+	/**
+	 * Value stored in a {@link AbstractReferencedValueMap} inside a {@link SoftReference}.
+	 * 
+	 * @param <VK> is the type of the key associated to the value.
+	 * @param <VV> is the type of the value.
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 */
+	protected static class SoftReferencedValue<VK,VV> extends SoftReference<VV> implements ReferencableValue<VK,VV> {
+
+		private final VK k;
+
+		/**
+		 * @param k is the key.
+		 * @param v is the value.
+		 * @param queue is the memory-release listener.
+		 */
+		public SoftReferencedValue(VK k, VV v, ReferenceQueue<VV> queue) {
+			super(maskNull(v), queue);
+			this.k = k;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @return {@inheritDoc}
+		 */
+		@Override
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append('{');
+			VK key = getKey();
+			buffer.append(key==null ? null : key.toString());
+			buffer.append('=');
+			if (isEnqueued()) {
+				buffer.append("Q#"); //$NON-NLS-1$
+			}
+			else {
+				buffer.append("P#"); //$NON-NLS-1$
+			}
+			VV v = getValue();
+			buffer.append((v==null ? null : v.toString()));
+			buffer.append('}');
+			return buffer.toString();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public VK getKey() {
+			return this.k;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public VV getValue() {
+			return unmaskNull(get());
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public VV setValue(VV o) {
+			throw new UnsupportedOperationException();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @return {@inheritDoc}
+		 */
+		@Override
+		public int hashCode() { 
+			Object val = getValue();
+			return (getKey()==null   ? 0 : getKey().hashCode()) ^
+					(val==null ? 0 : val.hashCode()); 
+		}
+
+		/**
+		 * {@inheritDoc}
+		 *
+		 * @param o {@inheritDoc}
+		 * @return {@inheritDoc}
+		 */
+		@SuppressWarnings("unchecked")
+		@Override
+		public boolean equals(Object o) {
+			if (o instanceof Entry) {
+				Entry<VK,VV> e = (Entry<VK,VV>)o;
+				Object e1val = getValue();
+				Object e2val = e.getValue();
+				return  (getKey()==null ?
+						e.getKey()==null : getKey().equals(e.getKey()))  &&
+						(e1val==null ? e2val==null : e1val.equals(e2val));
+			}
+			return false;
+		}
+
+	} // class SoftReferencedValue
+
+	/**
+	 * Value stored in a {@link AbstractReferencedValueMap} inside a {@link WeakReference}.
+	 * 
+	 * @param <VK> is the type of the key associated to the value.
+	 * @param <VV> is the type of the value.
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 */
+	protected static class WeakReferencedValue<VK,VV> extends WeakReference<VV> implements ReferencableValue<VK,VV> {
+
+		private final VK k;
+
+		/**
+		 * @param k is the key.
+		 * @param v is the value.
+		 * @param queue is the memory-release listener.
+		 */
+		public WeakReferencedValue(VK k, VV v, ReferenceQueue<VV> queue) {
+			super(maskNull(v), queue);
+			this.k = k;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @return {@inheritDoc}
+		 */
+		@Override
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append('{');
+			VK key = getKey();
+			buffer.append(key==null ? null : key.toString());
+			buffer.append('=');
+			if (isEnqueued()) {
+				buffer.append("Q#"); //$NON-NLS-1$
+			}
+			else {
+				buffer.append("P#"); //$NON-NLS-1$
+			}
+			VV v = getValue();
+			buffer.append((v==null ? null : v.toString()));
+			buffer.append('}');
+			return buffer.toString();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public VK getKey() {
+			return this.k;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public VV getValue() {
+			return unmaskNull(get());
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public VV setValue(VV o) {
+			throw new UnsupportedOperationException();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @return {@inheritDoc}
+		 */
+		@Override
+		public int hashCode() { 
+			Object val = getValue();
+			return (getKey()==null   ? 0 : getKey().hashCode()) ^
+					(val==null ? 0 : val.hashCode()); 
+		}
+
+		/**
+		 * {@inheritDoc}
+		 *
+		 * @param o {@inheritDoc}
+		 * @return {@inheritDoc}
+		 */
+		@SuppressWarnings("unchecked")
+		@Override
+		public boolean equals(Object o) {
+			if (o instanceof Entry) {
+				Entry<VK,VV> e = (Entry<VK,VV>)o;
+				Object e1val = getValue();
+				Object e2val = e.getValue();
+				return  (getKey()==null ?
+						e.getKey()==null : getKey().equals(e.getKey()))  &&
+						(e1val==null ? e2val==null : e1val.equals(e2val));
+			}
+			return false;
+		}
+
+	} // class WeakReferencedValue
+
+	/**
+	 * Value stored in a {@link AbstractReferencedValueMap} inside a {@link PhantomReference}.
+	 * 
+	 * @param <VK> is the type of the key associated to the value.
+	 * @param <VV> is the type of the value.
+	 * @author $Author: galland$
+	 * @version $FullVersion$
+	 * @mavengroupid $GroupId$
+	 * @mavenartifactid $ArtifactId$
+	 */
+	protected static class PhantomReferencedValue<VK,VV> extends PhantomReference<VV> implements ReferencableValue<VK,VV> {
+
+		private final VK k;
+
+		/**
+		 * @param k is the key.
+		 * @param v is the value.
+		 * @param queue is the memory-release listener.
+		 */
+		public PhantomReferencedValue(VK k, VV v, ReferenceQueue<VV> queue) {
+			super(maskNull(v), queue);
+			this.k = k;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @return {@inheritDoc}
+		 */
+		@Override
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append('{');
+			VK key = getKey();
+			buffer.append(key==null ? null : key.toString());
+			buffer.append('=');
+			if (isEnqueued()) {
+				buffer.append("Q#"); //$NON-NLS-1$
+			}
+			else {
+				buffer.append("P#"); //$NON-NLS-1$
+			}
+			VV v = getValue();
+			buffer.append((v==null ? null : v.toString()));
+			buffer.append('}');
+			return buffer.toString();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public VK getKey() {
+			return this.k;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public VV getValue() {
+			return unmaskNull(get());
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public VV setValue(VV o) {
+			throw new UnsupportedOperationException();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @return {@inheritDoc}
+		 */
+		@Override
+		public int hashCode() { 
+			Object val = getValue();
+			return (getKey()==null   ? 0 : getKey().hashCode()) ^
+					(val==null ? 0 : val.hashCode()); 
+		}
+
+		/**
+		 * {@inheritDoc}
+		 *
+		 * @param o {@inheritDoc}
+		 * @return {@inheritDoc}
+		 */
+		@SuppressWarnings("unchecked")
+		@Override
+		public boolean equals(Object o) {
+			if (o instanceof Entry) {
+				Entry<VK,VV> e = (Entry<VK,VV>)o;
+				Object e1val = getValue();
+				Object e2val = e.getValue();
+				return  (getKey()==null ?
+						e.getKey()==null : getKey().equals(e.getKey()))  &&
+						(e1val==null ? e2val==null : e1val.equals(e2val));
+			}
+			return false;
+		}
+
+	} // class PhantomReferencedValue
+
+}


Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractReferencedValueMap.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractSoftValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractSoftValueMap.java	                        (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractSoftValueMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,63 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2009 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.ReferenceQueue;
+import java.util.Map;
+
+/**
+ * A <tt>Map</tt> implementation with <em>soft values</em>. An entry in a
+ * <tt>AbstractSoftValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or <code>null</code>.
+ * <p>
+ * This abstract implementation does not decide if the map is based on a tree or on a hashtable.
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public abstract class AbstractSoftValueMap<K,V> extends AbstractReferencedValueMap<K,V> {
+	
+	/**
+     * Constructs an empty <tt>Map</tt>.
+     *
+     * @param  map is the map instance to use to store the entries.
+     * @throws IllegalArgumentException if the initial capacity is negative
+     *         or the load factor is nonpositive
+     */
+    public AbstractSoftValueMap(Map<K,ReferencableValue<K,V>> map) {
+        super(map);
+    }
+
+    /** {@inheritDoc}
+	 */
+	@Override
+	protected final ReferencableValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
+		return new SoftReferencedValue<K,V>(k, v, queue);
+	}
+
+}


Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractSoftValueMap.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Deleted: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java	2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -1,551 +0,0 @@
-/* 
- * $Id: WeakValueMap.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
- * 
- * Copyright (C) 2005-2009 Stephane GALLAND This library 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 library 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 library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * This program is free software; you can redistribute it and/or modify
- */
-
-package org.arakhne.util.ref;
-
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.util.AbstractMap;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A <tt>Map</tt> implementation with <em>weak/soft values</em>. An entry in a
- * <tt>AbstractWeakSoftValueMap</tt> will automatically be removed when its value is no
- * longer in ordinary use or null.
- *
- * @param <K> is the type of the keys.
- * @param <V> is the type of the values.
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
-public abstract class AbstractWeakSoftValueMap<K,V> extends AbstractMap<K,V> {
-	
-	/** Defines the NULL object inside a WeakValueMap.
-	 * 
-	 * @see #maskNull(Object)
-	 */
-	protected static final Object NULL_VALUE = new Object();
-
-	/** Mask the null values given by the used of this map.
-	 * <p>
-	 * This method replaces the <code>null</code> value by
-	 * the internal representation {@link #NULL_VALUE}.
-	 *
-	 * @param <V> is the type of the value.
-	 * @param value is the value given by the user of this map.
-	 * @return the internal representation of the value.
-	 * @see #unmaskNull(Object)
-	 */
-	@SuppressWarnings("unchecked")
-	protected static <V> V maskNull(V value) {
-		return (value==null) ? (V)NULL_VALUE : value;
-	}
-
-	/** Unmask the null values given by the used of this map.
-	 * <p>
-	 * This method replaces the internal representation
-	 * {@link #NULL_VALUE} of null values by its user representation
-	 * <code>null</code>.
-	 * 
-	 * @param <V> is the type of the value.
-	 * @param value is the value given by the user of this map.
-	 * @return the internal representation of the value.
-	 * @see #maskNull(Object)
-	 */
-	protected static <V> V unmaskNull(V value) {
-		return (value==NULL_VALUE) ? null : value;
-	}
-
-	private boolean autoExpurge = false;
-	private final HashMap<K,WeakSoftValue<K,V>> map;
-	private final ReferenceQueue<V> queue = new ReferenceQueue<V>();
-
-    /**
-     * Constructs an empty <tt>HashMap</tt> with the specified initial
-     * capacity and load factor.
-     *
-     * @param  initialCapacity the initial capacity
-     * @param  loadFactor      the load factor
-     * @throws IllegalArgumentException if the initial capacity is negative
-     *         or the load factor is nonpositive
-     */
-    public AbstractWeakSoftValueMap(int initialCapacity, float loadFactor) {
-        this.map = new HashMap<K,WeakSoftValue<K,V>>(initialCapacity, loadFactor);
-    }
-
-    /**
-     * Constructs an empty <tt>HashMap</tt> with the specified initial
-     * capacity and the default load factor (0.75).
-     *
-     * @param  initialCapacity the initial capacity.
-     * @throws IllegalArgumentException if the initial capacity is negative.
-     */
-    public AbstractWeakSoftValueMap(int initialCapacity) {
-        this.map = new HashMap<K,WeakSoftValue<K,V>>(initialCapacity);
-    }
-
-    /**
-     * Constructs an empty <tt>HashMap</tt> with the default initial capacity
-     * (16) and the default load factor (0.75).
-     */
-    public AbstractWeakSoftValueMap() {
-        this.map = new HashMap<K,WeakSoftValue<K,V>>();
-    }
-
-    /**
-     * Constructs a new <tt>HashMap</tt> with the same mappings as the
-     * specified <tt>Map</tt>.  The <tt>HashMap</tt> is created with
-     * default load factor (0.75) and an initial capacity sufficient to
-     * hold the mappings in the specified <tt>Map</tt>.
-     *
-     * @param   m the map whose mappings are to be placed in this map
-     * @throws  NullPointerException if the specified map is null
-     */
-    public AbstractWeakSoftValueMap(Map<? extends K, ? extends V> m) {
-        this.map = new HashMap<K,WeakSoftValue<K,V>>();
-        putAll(m);
-    }	
-
-    /** Clean the references that was marked as released inside
-     * the queue.
-     */
-	protected final void expurgeNow() {
-		if (this.autoExpurge)
-			expurge();
-		else
-			expurgeQueuedReferences();
-	}
-	
-	/** Replies if this map expurge all the released references
-	 * even if they are not enqueued by the virtual machine
-	 * 
-	 * @return <code>true</code> is the values are deeply expurged when they
-	 * are released from the moemory, otherwise <code>false</code>
-	 */
-	public final boolean isDeeplyExpurge() {
-		return this.autoExpurge;
-	}
-	
-	/** Set if this map expurge all the released references
-	 * even if they are not enqueued by the virtual machine
-	 * 
-	 * @param deeplyExpurge must be <code>true</code> to
-	 * expurge all the released values, otherwise <code>false</code>
-	 * to expurge only the enqueued values.
-	 * @return the old value of this flag
-	 */
-	public final boolean setDeeplyExpurge(boolean deeplyExpurge) {
-		boolean old = this.autoExpurge;
-		this.autoExpurge = deeplyExpurge;
-		return old;
-	}
-	
-    /** Clean the references that was marked as released inside
-     * the queue.
-     */
-	public final void expurgeQueuedReferences() {
-		Reference<? extends V> o;
-		while((o = this.queue.poll()) != null) {
-			if (o instanceof WeakSoftValue<?,?>) {
-				this.map.remove(((WeakSoftValue<?,?>)o).getKey());
-			}
-			o.clear();
-		}
-	}
-
-	/** Clean the references that was released.
-     */
-	public final void expurge() {
-		Reference<? extends V> o;
-		
-		Iterator<Entry<K,WeakSoftValue<K,V>>> iter = this.map.entrySet().iterator();
-		Entry<K,WeakSoftValue<K,V>> entry;
-		WeakSoftValue<K,V> value;
-		while (iter.hasNext()) {
-			entry = iter.next();
-			if (entry!=null) {
-				value = entry.getValue();
-				if ((value!=null)&&
-					((value.isEnqueued())||(value.get()==null))) {
-					value.enqueue();
-					value.clear();
-				}
-			}
-		}
-		entry = null;
-		value = null;
-
-		while((o = this.queue.poll()) != null) {
-			if (o instanceof WeakSoftValue<?,?>) {
-				this.map.remove(((WeakSoftValue<?,?>)o).getKey());
-			}
-			o.clear();
-		}
-	}
-
-	/** Create a storage object that permits to put the specified
-	 * elements inside this map.
-	 * 
-	 * @param k is the key associated to the value
-	 * @param v is the value
-	 * @param refQueue is the reference queue to use
-	 * @return the new storage object
-	 */
-	protected abstract WeakSoftValue<K,V> makeValue(K k, V v, ReferenceQueue<V> refQueue);
-
-	/** Create a storage object that permits to put the specified
-	 * elements inside this map.
-	 * 
-	 * @param k is the key associated to the value
-	 * @param v is the value
-	 * @return the new storage object
-	 */
-	protected final WeakSoftValue<K,V> makeValue(K k, V v) {
-		return makeValue(k, v, this.queue);
-	}
-
-	/**
-     * {@inheritDoc}
-     */
-	@Override
-	public final V put(K key, V value) {
-		expurgeNow();
-		WeakSoftValue<K,V> ret = this.map.put(key, makeValue(key, value, this.queue));
-		if(ret == null) return null;
-		return ret.getValue();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public final Set<Entry<K,V>> entrySet() {
-		expurgeNow();
-		return new InnerEntrySet();
-	}	
-		
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-	public final boolean equals(Object o) {
-    	expurgeNow();
-    	return super.equals(o);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-	public final int hashCode() {
-    	expurgeNow();
-    	return hashCode();
-    }
-        
-	/**
-	 * This interface provides information about the pairs inside
-	 * a map with weak/soft reference values.
-	 * 
-	 * @param <K> is the type of the map keys.
-	 * @param <V> is the type of the map values.
-	 * @author $Author: galland$
-	 * @version $FullVersion$
-	 * @mavengroupid $GroupId$
-	 * @mavenartifactid $ArtifactId$
-	 */
-	protected interface WeakSoftValue<K,V> extends Entry<K,V> {
-		
-		/**
-		 * @return if the value is enqueued into a reference queue.
-		 */
-		public boolean isEnqueued();
-		
-		/**
-		 * @return the weak/soft reference.
-		 */
-		public V get();
-
-		/**
-		 * @return if the value was enqueued
-		 */
-		public boolean enqueue();
-
-		/**
-		 */
-		public void clear();
-
-	}
-
-	/**
-	 * @author $Author: galland$
-	 * @version $FullVersion$
-	 * @mavengroupid $GroupId$
-	 * @mavenartifactid $ArtifactId$
-	 */
-	@SuppressWarnings("synthetic-access")
-	private class InnerEntrySet implements Set<Entry<K,V>> {
-
-		public InnerEntrySet() {
-			//
-		}
-
-		@Override
-		public final boolean add(java.util.Map.Entry<K, V> e) {
-			K key = e.getKey();
-			V value = e.getValue();
-			return AbstractWeakSoftValueMap.this.map.put(key,
-					makeValue(key, value)) == null;
-		}
-
-		@Override
-		public final boolean addAll(Collection<? extends java.util.Map.Entry<K, V>> c) {
-			boolean ok = true;
-			for(java.util.Map.Entry<K, V> entry : c) {
-				ok = add(entry) && ok;
-			}
-			return ok;
-		}
-
-		@Override
-		public final void clear() {
-			AbstractWeakSoftValueMap.this.map.clear();
-		}
-
-		@Override
-		public final boolean contains(Object o) {
-			if (o instanceof Entry<?,?>) {
-				try {
-					expurgeNow();
-					return AbstractWeakSoftValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
-				}
-				catch(AssertionError e) {
-					throw e;
-				}
-				catch(Throwable _) {
-					//
-				}
-			}
-			return false;
-		}
-
-		@Override
-		public final boolean containsAll(Collection<?> c) {
-			boolean ok;
-			expurgeNow();
-			for(Object o : c) {
-				ok = false;
-				if (o instanceof Entry<?,?>) {
-					try {
-						ok = AbstractWeakSoftValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
-					}
-					catch(AssertionError e) {
-						throw e;
-					}
-					catch(Throwable _) {
-						//
-					}
-				}
-				if (!ok) return false;
-			}
-			return true;
-		}
-
-		@Override
-		public final boolean isEmpty() {
-			expurgeNow();
-			return AbstractWeakSoftValueMap.this.map.isEmpty();
-		}
-
-		@Override
-		public final Iterator<java.util.Map.Entry<K, V>> iterator() {
-			return new InnerIterator();
-		}
-
-		@Override
-		public final boolean remove(Object o) {
-			if (o instanceof Entry<?,?>) {
-				try {
-					return AbstractWeakSoftValueMap.this.map.remove(((Entry<?,?>)o).getKey())!=null;
-				}
-				catch(AssertionError e) {
-					throw e;
-				}
-				catch(Throwable _) {
-					//
-				}
-			}
-			return false;
-		}
-
-		@Override
-		public final boolean removeAll(Collection<?> c) {
-			boolean ok = true;
-			for(Object o : c) {
-				ok = remove(o) && ok;
-			}
-			return ok;
-		}
-
-		@Override
-		public final boolean retainAll(Collection<?> c) {
-			expurgeNow();
-			Collection<K> keys = AbstractWeakSoftValueMap.this.map.keySet();
-			Iterator<K> iterator = keys.iterator();
-			K key;
-			boolean changed = false;
-			while (iterator.hasNext()) {
-				key = iterator.next();
-				if (!c.contains(key)) {
-					iterator.remove();
-					changed = true;
-				}
-			}
-			return changed;
-		}
-
-		@Override
-		public final int size() {
-			expurgeNow();
-			return AbstractWeakSoftValueMap.this.map.size();
-		}
-
-		@Override
-		public final Object[] toArray() {
-			expurgeNow();
-			Object[] tab = new Object[AbstractWeakSoftValueMap.this.map.size()];
-			return toArray(tab);
-		}
-
-		@SuppressWarnings("unchecked")
-		@Override
-		public final <T> T[] toArray(T[] a) {
-			Entry<?,?>[] tab;
-			expurgeNow();
-			int count = AbstractWeakSoftValueMap.this.map.size();
-			if (a==null || a.length<count) {
-				tab = new Entry[count];
-			}
-			else {
-				tab = (Entry[])a;
-			}
-
-			Iterator<java.util.Map.Entry<K, V>> iterator = iterator();
-			int i = 0;
-			while (i<tab.length && iterator.hasNext()) {
-				tab[i] = iterator.next();
-			}
-			
-			return (T[])tab;
-		}
-		
-	}
-	
-	/**
-	 * @author $Author: galland$
-	 * @version $FullVersion$
-	 * @mavengroupid $GroupId$
-	 * @mavenartifactid $ArtifactId$
-	 */
-	private class InnerIterator implements Iterator<Entry<K,V>> {
-
-		private final Iterator<Entry<K,WeakSoftValue<K,V>>> originalIterator;
-		private Entry<K,V> next;
-		
-		@SuppressWarnings("synthetic-access")
-		public InnerIterator() {
-			this.originalIterator = AbstractWeakSoftValueMap.this.map.entrySet().iterator();
-			this.next = searchNext();
-		}
-		
-		private Entry<K,V> searchNext() {
-			Entry<K,WeakSoftValue<K,V>> originalNext;
-			WeakSoftValue<K,V> wValue;
-			Entry<K,V> cnext = null;
-			while (cnext==null && this.originalIterator.hasNext()) {
-				originalNext = this.originalIterator.next();
-				if (originalNext!=null) {
-					wValue = originalNext.getValue();
-					if (wValue!=null) {
-						cnext = new InnerEntry(wValue.getValue(), originalNext);
-					}
-				}
-			}
-			return cnext;
-		}
-		
-		@Override
-		public boolean hasNext() {
-			return this.next!=null;
-		}
-
-		@Override
-		public java.util.Map.Entry<K, V> next() {
-			Entry<K,V> cnext = this.next;
-			this.next = searchNext();
-			return cnext;
-		}
-
-		@Override
-		public void remove() {
-			this.originalIterator.remove();
-		}
-		
-	}
-
-	/**
-	 * @author $Author: galland$
-	 * @version $FullVersion$
-	 * @mavengroupid $GroupId$
-	 * @mavenartifactid $ArtifactId$
-	 */
-	private class InnerEntry implements Entry<K,V> {
-
-		private final Entry<K,WeakSoftValue<K,V>> original;
-		private V value;
-		
-		public InnerEntry(V v, Entry<K,WeakSoftValue<K,V>> o) {
-			this.original = o;
-			this.value = v;
-		}
-		
-		@Override
-		public K getKey() {
-			return this.original.getKey();
-		}
-
-		@Override
-		public V getValue() {
-			return this.value;
-		}
-
-		@Override
-		public V setValue(V value) {
-			this.value = value;
-			return this.original.getValue().setValue(value);
-		}
-
-	}
-	
-}

Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakValueMap.java	                        (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakValueMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,63 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2009 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.ReferenceQueue;
+import java.util.Map;
+
+/**
+ * A <tt>Map</tt> implementation with <em>weak values</em>. An entry in a
+ * <tt>AbstractWeakValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or <code>null</code>.
+ * <p>
+ * This abstract implementation does not decide if the map is based on a tree or on a hashtable.
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public abstract class AbstractWeakValueMap<K,V> extends AbstractReferencedValueMap<K,V> {
+	
+	/**
+     * Constructs an empty <tt>Map</tt>.
+     *
+     * @param  map is the map instance to use to store the entries.
+     * @throws IllegalArgumentException if the initial capacity is negative
+     *         or the load factor is nonpositive
+     */
+    public AbstractWeakValueMap(Map<K,ReferencableValue<K,V>> map) {
+        super(map);
+    }
+
+    /** {@inheritDoc}
+	 */
+	@Override
+	protected final ReferencableValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
+		return new WeakReferencedValue<K,V>(k, v, queue);
+	}
+
+}


Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakValueMap.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueHashMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueHashMap.java	                        (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueHashMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,115 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>phantom values</em>. An entry in a
+ * <tt>PhantomValueHashMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link HashMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the 
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class PhantomValueHashMap<K,V> extends AbstractSoftValueMap<K,V> {
+	
+    /**
+     * Constructs an empty <tt>HashMap</tt> with the specified initial
+     * capacity and load factor.
+     *
+     * @param  initialCapacity the initial capacity
+     * @param  loadFactor      the load factor
+     * @throws IllegalArgumentException if the initial capacity is negative
+     *         or the load factor is nonpositive
+     */
+    public PhantomValueHashMap(int initialCapacity, float loadFactor) {
+        super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity, loadFactor));
+    }
+
+    /**
+     * Constructs an empty <tt>HashMap</tt> with the specified initial
+     * capacity and the default load factor (0.75).
+     *
+     * @param  initialCapacity the initial capacity.
+     * @throws IllegalArgumentException if the initial capacity is negative.
+     */
+    public PhantomValueHashMap(int initialCapacity) {
+    	super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity));
+    }
+
+    /**
+     * Constructs an empty <tt>HashMap</tt> with the default initial capacity
+     * (16) and the default load factor (0.75).
+     */
+    public PhantomValueHashMap() {
+    	super(new HashMap<K,ReferencableValue<K,V>>());
+    }
+
+    /**
+     * Constructs a new <tt>HashMap</tt> with the same mappings as the
+     * specified <tt>Map</tt>.  The <tt>HashMap</tt> is created with
+     * default load factor (0.75) and an initial capacity sufficient to
+     * hold the mappings in the specified <tt>Map</tt>.
+     *
+     * @param   m the map whose mappings are to be placed in this map
+     * @throws  NullPointerException if the specified map is null
+     */
+    public PhantomValueHashMap(Map<? extends K, ? extends V> m) {
+    	super(new HashMap<K,ReferencableValue<K,V>>());
+    	putAll(m);
+    }	
+        
+}


Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueHashMap.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueTreeMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueTreeMap.java	                        (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueTreeMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,113 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.Comparator;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>phantom values</em>. An entry in a
+ * <tt>PhantomValueTreeMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link TreeMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the 
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class PhantomValueTreeMap<K,V> extends AbstractSoftValueMap<K,V> {
+	
+    /**
+     * Constructs an empty <tt>TreeMap</tt> with the specified comparator.
+     *
+     * @param comparator the comparator that will be used to order this map.
+     *        If <tt>null</tt>, the {@linkplain Comparable natural
+     *        ordering} of the keys will be used.
+     */
+    public PhantomValueTreeMap(Comparator<? super K> comparator) {
+    	super(new TreeMap<K,ReferencableValue<K,V>>(comparator));
+    }
+
+    /**
+     * Constructs an empty <tt>TreeMap</tt>.
+     */
+    public PhantomValueTreeMap() {
+    	super(new TreeMap<K,ReferencableValue<K,V>>());
+    }
+
+    /**
+     * Constructs a new <tt>TreeMap</tt> with the same mappings as the
+     * specified <tt>Map</tt>.
+     *
+     * @param   m the map whose mappings are to be placed in this map
+     * @throws  NullPointerException if the specified map is null
+     */
+    public PhantomValueTreeMap(Map<? extends K, ? extends V> m) {
+        super(new TreeMap<K,ReferencableValue<K,V>>());
+        putAll(m);
+    }	
+
+    /**
+     * Constructs a new <tt>TreeMap</tt> with the same mappings and
+     * comparator as the specified <tt>Map</tt>.
+     *
+     * @param   m the map whose mappings are to be placed in this map
+     * @throws  NullPointerException if the specified map is null
+     */
+    public PhantomValueTreeMap(SortedMap<K, ? extends V> m) {
+        super(new TreeMap<K,ReferencableValue<K,V>>(m.comparator()));
+        putAll(m);
+    }	
+        
+}


Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueTreeMap.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueHashMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueHashMap.java	                        (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueHashMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,115 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>soft values</em>. An entry in a
+ * <tt>SoftValueHashMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link HashMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the 
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class SoftValueHashMap<K,V> extends AbstractSoftValueMap<K,V> {
+	
+    /**
+     * Constructs an empty <tt>HashMap</tt> with the specified initial
+     * capacity and load factor.
+     *
+     * @param  initialCapacity the initial capacity
+     * @param  loadFactor      the load factor
+     * @throws IllegalArgumentException if the initial capacity is negative
+     *         or the load factor is nonpositive
+     */
+    public SoftValueHashMap(int initialCapacity, float loadFactor) {
+        super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity, loadFactor));
+    }
+
+    /**
+     * Constructs an empty <tt>HashMap</tt> with the specified initial
+     * capacity and the default load factor (0.75).
+     *
+     * @param  initialCapacity the initial capacity.
+     * @throws IllegalArgumentException if the initial capacity is negative.
+     */
+    public SoftValueHashMap(int initialCapacity) {
+    	super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity));
+    }
+
+    /**
+     * Constructs an empty <tt>HashMap</tt> with the default initial capacity
+     * (16) and the default load factor (0.75).
+     */
+    public SoftValueHashMap() {
+    	super(new HashMap<K,ReferencableValue<K,V>>());
+    }
+
+    /**
+     * Constructs a new <tt>HashMap</tt> with the same mappings as the
+     * specified <tt>Map</tt>.  The <tt>HashMap</tt> is created with
+     * default load factor (0.75) and an initial capacity sufficient to
+     * hold the mappings in the specified <tt>Map</tt>.
+     *
+     * @param   m the map whose mappings are to be placed in this map
+     * @throws  NullPointerException if the specified map is null
+     */
+    public SoftValueHashMap(Map<? extends K, ? extends V> m) {
+    	super(new HashMap<K,ReferencableValue<K,V>>());
+    	putAll(m);
+    }	
+        
+}


Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueHashMap.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java	2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -1,7 +1,10 @@
 /* 
- * $Id: SoftValueMap.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ * $Id$
  * 
- * Copyright (C) 2005-2007 Stephane GALLAND This library is free software; you can redistribute it and/or
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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.
@@ -19,16 +22,15 @@
 
 package org.arakhne.util.ref;
 
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
 import java.util.Map;
+import java.util.WeakHashMap;
 
 /**
  * A <tt>Map</tt> implementation with <em>soft values</em>. An entry in a
  * <tt>SoftValueMap</tt> will automatically be removed when its value is no
  * longer in ordinary use or null.
  * <p>
- * This class was inspirated from <code>WeakHashMap</code>
+ * This class was inspirated from {@link WeakHashMap}.
  * <p>
  * This class has a special flag which permits to control the
  * way how the released references are expurged: {@link #isDeeplyExpurge()},
@@ -58,8 +60,10 @@
  * @version $FullVersion$
  * @mavengroupid $GroupId$
  * @mavenartifactid $ArtifactId$
+ * @deprecated replace by {@link SoftValueHashMap}
  */
-public class SoftValueMap<K,V> extends AbstractWeakSoftValueMap<K,V> {
+@Deprecated
+public class SoftValueMap<K,V> extends SoftValueHashMap<K,V> {
 	
     /**
      * Constructs an empty <tt>HashMap</tt> with the specified initial
@@ -106,119 +110,4 @@
         super(m);
     }	
 
-	/** Create a storage object that permits to put the specified
-	 * elements inside this map.
-	 * 
-	 * @param k is the key associated to the value
-	 * @param v is the value
-	 * @param queue is the reference queue to use
-	 * @return the new storage object
-	 */
-	@Override
-	protected WeakSoftValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
-		return new Value<K,V>(k, v, queue);
-	}
-
-	/**
-	 * @author $Author: galland$
-	 * @version $FullVersion$
-	 * @mavengroupid $GroupId$
-	 * @mavenartifactid $ArtifactId$
-	 */
-	private static class Value<K,V> extends SoftReference<V> implements WeakSoftValue<K,V> {
-		
-		private final K k;
-
-		/**
-		 * @param k is the key.
-		 * @param v is the value.
-		 * @param queue is the memory-release listener.
-		 */
-		Value(K k, V v, ReferenceQueue<V> queue) {
-			super(maskNull(v), queue);
-			this.k = k;
-		}
-		
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @return {@inheritDoc}
-		 */
-		@Override
-		public String toString() {
-			StringBuffer buffer = new StringBuffer();
-			buffer.append('{');
-			K key = getKey();
-			buffer.append(key==null ? null : key.toString());
-			buffer.append('=');
-			if (isEnqueued()) {
-				buffer.append("Q#"); //$NON-NLS-1$
-			}
-			else {
-				buffer.append("P#"); //$NON-NLS-1$
-			}
-			V v = getValue();
-			buffer.append((v==null ? null : v.toString()));
-			buffer.append('}');
-			return buffer.toString();
-		}
-		
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public K getKey() {
-			return this.k;
-		}
-		
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public V getValue() {
-			return unmaskNull(get());
-		}
-		
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public V setValue(V o) {
-			throw new UnsupportedOperationException();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @return {@inheritDoc}
-		 */
-		@Override
-		public int hashCode() { 
-			Object val = getValue();
-			return (getKey()==null   ? 0 : getKey().hashCode()) ^
-				   (val==null ? 0 : val.hashCode()); 
-		}
-		
-		/**
-		 * {@inheritDoc}
-		 *
-		 * @param o {@inheritDoc}
-		 * @return {@inheritDoc}
-		 */
-		@SuppressWarnings("unchecked")
-		@Override
-		public boolean equals(Object o) {
-			if (o instanceof Entry) {
-				Entry<K,V> e = (Entry<K,V>)o;
-				Object e1val = getValue();
-				Object e2val = e.getValue();
-				return  (getKey()==null ?
-						e.getKey()==null : getKey().equals(e.getKey()))  &&
-						(e1val==null ? e2val==null : e1val.equals(e2val));
-			}
-			return false;
-		}
-
-	}
-        
 }

Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueTreeMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueTreeMap.java	                        (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueTreeMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,113 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.Comparator;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>soft values</em>. An entry in a
+ * <tt>SoftValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link TreeMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the 
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class SoftValueTreeMap<K,V> extends AbstractSoftValueMap<K,V> {
+	
+    /**
+     * Constructs an empty <tt>TreeMap</tt> with the specified comparator.
+     *
+     * @param comparator the comparator that will be used to order this map.
+     *        If <tt>null</tt>, the {@linkplain Comparable natural
+     *        ordering} of the keys will be used.
+     */
+    public SoftValueTreeMap(Comparator<? super K> comparator) {
+    	super(new TreeMap<K,ReferencableValue<K,V>>(comparator));
+    }
+
+    /**
+     * Constructs an empty <tt>TreeMap</tt>.
+     */
+    public SoftValueTreeMap() {
+    	super(new TreeMap<K,ReferencableValue<K,V>>());
+    }
+
+    /**
+     * Constructs a new <tt>TreeMap</tt> with the same mappings as the
+     * specified <tt>Map</tt>.
+     *
+     * @param   m the map whose mappings are to be placed in this map
+     * @throws  NullPointerException if the specified map is null
+     */
+    public SoftValueTreeMap(Map<? extends K, ? extends V> m) {
+        super(new TreeMap<K,ReferencableValue<K,V>>());
+        putAll(m);
+    }	
+
+    /**
+     * Constructs a new <tt>TreeMap</tt> with the same mappings and
+     * comparator as the specified <tt>Map</tt>.
+     *
+     * @param   m the map whose mappings are to be placed in this map
+     * @throws  NullPointerException if the specified map is null
+     */
+    public SoftValueTreeMap(SortedMap<K, ? extends V> m) {
+        super(new TreeMap<K,ReferencableValue<K,V>>(m.comparator()));
+        putAll(m);
+    }	
+        
+}


Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueTreeMap.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java	2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -1,7 +1,9 @@
 /* 
- * $Id: WeakArrayList.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ * $Id$
  * 
- * Copyright (C) 2005-2009 Stephane GALLAND This library is free software; you can redistribute it and/or
+ * Copyright (C) 2005-2009 Stephane GALLAND.
+ * 
+ * This library 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.

Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueHashMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueHashMap.java	                        (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueHashMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,115 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>weak values</em>. An entry in a
+ * <tt>WeakValueHashMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link HashMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the 
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class WeakValueHashMap<K,V> extends AbstractWeakValueMap<K,V> {
+	
+    /**
+     * Constructs an empty <tt>HashMap</tt> with the specified initial
+     * capacity and load factor.
+     *
+     * @param  initialCapacity the initial capacity
+     * @param  loadFactor      the load factor
+     * @throws IllegalArgumentException if the initial capacity is negative
+     *         or the load factor is nonpositive
+     */
+    public WeakValueHashMap(int initialCapacity, float loadFactor) {
+        super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity, loadFactor));
+    }
+
+    /**
+     * Constructs an empty <tt>HashMap</tt> with the specified initial
+     * capacity and the default load factor (0.75).
+     *
+     * @param  initialCapacity the initial capacity.
+     * @throws IllegalArgumentException if the initial capacity is negative.
+     */
+    public WeakValueHashMap(int initialCapacity) {
+    	super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity));
+    }
+
+    /**
+     * Constructs an empty <tt>HashMap</tt> with the default initial capacity
+     * (16) and the default load factor (0.75).
+     */
+    public WeakValueHashMap() {
+    	super(new HashMap<K,ReferencableValue<K,V>>());
+    }
+
+    /**
+     * Constructs a new <tt>HashMap</tt> with the same mappings as the
+     * specified <tt>Map</tt>.  The <tt>HashMap</tt> is created with
+     * default load factor (0.75) and an initial capacity sufficient to
+     * hold the mappings in the specified <tt>Map</tt>.
+     *
+     * @param   m the map whose mappings are to be placed in this map
+     * @throws  NullPointerException if the specified map is null
+     */
+    public WeakValueHashMap(Map<? extends K, ? extends V> m) {
+        super(new HashMap<K,ReferencableValue<K,V>>());
+        putAll(m);
+    }	
+        
+}


Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueHashMap.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java	2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -1,7 +1,10 @@
 /* 
- * $Id: WeakValueMap.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ * $Id$
  * 
- * Copyright (C) 2005-2007 Stephane GALLAND This library is free software; you can redistribute it and/or
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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.
@@ -19,8 +22,6 @@
 
 package org.arakhne.util.ref;
 
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
 import java.util.Map;
 import java.util.WeakHashMap;
 
@@ -59,8 +60,10 @@
  * @version $FullVersion$
  * @mavengroupid $GroupId$
  * @mavenartifactid $ArtifactId$
+ * @deprecated replace by {@link WeakValueHashMap}
  */
-public class WeakValueMap<K,V> extends AbstractWeakSoftValueMap<K,V> {
+@Deprecated
+public class WeakValueMap<K,V> extends WeakValueHashMap<K,V> {
 	
     /**
      * Constructs an empty <tt>HashMap</tt> with the specified initial
@@ -106,120 +109,5 @@
     public WeakValueMap(Map<? extends K, ? extends V> m) {
         super(m);
     }	
-
-	/** Create a storage object that permits to put the specified
-	 * elements inside this map.
-	 * 
-	 * @param k is the key associated to the value
-	 * @param v is the value
-	 * @param queue is the reference queue to use
-	 * @return the new storage object
-	 */
-	@Override
-	protected WeakSoftValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
-		return new Value<K,V>(k, v, queue);
-	}
-
-	/**
-	 * @author $Author: galland$
-	 * @version $FullVersion$
-	 * @mavengroupid $GroupId$
-	 * @mavenartifactid $ArtifactId$
-	 */
-	private static class Value<K,V> extends WeakReference<V> implements WeakSoftValue<K,V> {
-		
-		private final K k;
-
-		/**
-		 * @param k is the key.
-		 * @param v is the value.
-		 * @param queue is the memory-release listener.
-		 */
-		Value(K k, V v, ReferenceQueue<V> queue) {
-			super(maskNull(v), queue);
-			this.k = k;
-		}
-		
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @return {@inheritDoc}
-		 */
-		@Override
-		public String toString() {
-			StringBuffer buffer = new StringBuffer();
-			buffer.append('{');
-			K key = getKey();
-			buffer.append(key==null ? null : key.toString());
-			buffer.append('=');
-			if (isEnqueued()) {
-				buffer.append("Q#"); //$NON-NLS-1$
-			}
-			else {
-				buffer.append("P#"); //$NON-NLS-1$
-			}
-			V v = getValue();
-			buffer.append((v==null ? null : v.toString()));
-			buffer.append('}');
-			return buffer.toString();
-		}
-		
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public K getKey() {
-			return this.k;
-		}
-		
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public V getValue() {
-			return unmaskNull(get());
-		}
-		
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public V setValue(V o) {
-			throw new UnsupportedOperationException();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @return {@inheritDoc}
-		 */
-		@Override
-		public int hashCode() { 
-			Object val = getValue();
-			return (getKey()==null   ? 0 : getKey().hashCode()) ^
-				   (val==null ? 0 : val.hashCode()); 
-		}
-		
-		/**
-		 * {@inheritDoc}
-		 *
-		 * @param o {@inheritDoc}
-		 * @return {@inheritDoc}
-		 */
-		@SuppressWarnings("unchecked")
-		@Override
-		public boolean equals(Object o) {
-			if (o instanceof Entry) {
-				Entry<K,V> e = (Entry<K,V>)o;
-				Object e1val = getValue();
-				Object e2val = e.getValue();
-				return  (getKey()==null ?
-						e.getKey()==null : getKey().equals(e.getKey()))  &&
-						(e1val==null ? e2val==null : e1val.equals(e2val));
-			}
-			return false;
-		}
-
-	}
         
 }

Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueTreeMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueTreeMap.java	                        (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueTreeMap.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,113 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.Comparator;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>weak values</em>. An entry in a
+ * <tt>WeakValueTreeMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link TreeMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the 
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class WeakValueTreeMap<K,V> extends AbstractWeakValueMap<K,V> {
+	
+    /**
+     * Constructs an empty <tt>TreeMap</tt> with the specified comparator.
+     *
+     * @param comparator the comparator that will be used to order this map.
+     *        If <tt>null</tt>, the {@linkplain Comparable natural
+     *        ordering} of the keys will be used.
+     */
+    public WeakValueTreeMap(Comparator<? super K> comparator) {
+    	super(new TreeMap<K,ReferencableValue<K,V>>(comparator));
+    }
+
+    /**
+     * Constructs an empty <tt>TreeMap</tt>.
+     */
+    public WeakValueTreeMap() {
+    	super(new TreeMap<K,ReferencableValue<K,V>>());
+    }
+
+    /**
+     * Constructs a new <tt>TreeMap</tt> with the same mappings as the
+     * specified <tt>Map</tt>.
+     *
+     * @param   m the map whose mappings are to be placed in this map
+     * @throws  NullPointerException if the specified map is null
+     */
+    public WeakValueTreeMap(Map<? extends K, ? extends V> m) {
+        super(new TreeMap<K,ReferencableValue<K,V>>());
+        putAll(m);
+    }	
+
+    /**
+     * Constructs a new <tt>TreeMap</tt> with the same mappings and
+     * comparator as the specified <tt>Map</tt>.
+     *
+     * @param   m the map whose mappings are to be placed in this map
+     * @throws  NullPointerException if the specified map is null
+     */
+    public WeakValueTreeMap(SortedMap<K, ? extends V> m) {
+        super(new TreeMap<K,ReferencableValue<K,V>>(m.comparator()));
+        putAll(m);
+    }	
+        
+}


Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueTreeMap.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractCollectionTestCase.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractCollectionTestCase.java	                        (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractCollectionTestCase.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,280 @@
+/* $Id$
+ * 
+ * Copyright (c) 2006-10, Multiagent Team, Laboratoire Systemes et Transport,
+ *                        Universite de Technologie de Belfort-Montbeliard.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Random;
+
+/**
+ * @param <OBJ>
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public abstract class AbstractCollectionTestCase<OBJ> extends AbstractTestCase {
+
+	private final Random RANDOM = new Random();
+	
+	/**
+	 */
+	protected ArrayList<OBJ> reference;
+	/**
+	 */
+	protected ArrayList<OBJ> unreference;
+	/**
+	 */
+	protected Collection<OBJ> collection;
+	
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+		int count = this.RANDOM.nextInt(400)+100;
+		this.reference = new ArrayList<OBJ>(count);
+		for(int idx=0; idx<count; idx++) {
+			this.reference.add(createContentInstance());
+		}
+		
+		count = this.RANDOM.nextInt(5)+5;
+		this.unreference = new ArrayList<OBJ>(count);
+		for(int idx=0; idx<count; idx++) {
+			this.unreference.add(createContentInstance());
+		}
+
+		this.collection = createCollection();
+	}
+	
+	/**
+	 * @return an instance
+	 */
+	protected abstract OBJ createContentInstance();
+	
+	/**
+	 * @return a collection
+	 */
+	protected abstract Collection<OBJ> createCollection();
+	
+	/**
+	 * @param toAdd
+	 */
+	protected abstract void initCollectionWith(Collection<OBJ> toAdd);
+	/**
+	 * @param toAdd
+	 */
+	protected abstract void fillCollectionWith(Collection<OBJ> toAdd);
+	
+	@Override
+	public void tearDown() throws Exception {
+		this.collection = null;
+		this.unreference = null;
+		this.reference = null;
+		super.tearDown();
+	}
+	
+	/**
+	 */
+	public void testAddAll() {
+        assertTrue(this.collection.addAll(this.reference));
+        assertEpsilonEquals(this.reference, this.collection);
+	}
+
+	/**
+	 */
+	public void testSize() {
+        assertEquals(0, this.collection.size());
+        initCollectionWith(this.reference);        
+        assertEquals(this.reference.size(), this.collection.size());
+    }
+
+	/**
+	 */
+    public void testIsEmpty() {
+        assertTrue(this.collection.isEmpty());
+        initCollectionWith(this.reference);        
+        assertFalse(this.collection.isEmpty());
+    }
+
+	/**
+	 */
+    public void testContains() {
+        initCollectionWith(this.reference);        
+    	
+        int count = this.RANDOM.nextInt(50)+50;
+        for(int idx=0; idx<count; idx++) {
+        	int index = this.RANDOM.nextInt(this.reference.size());
+        	
+        	assertTrue(this.collection.contains(this.reference.get(index)));
+        }
+        
+        count = this.RANDOM.nextInt(5)+5;
+        int index;
+        OBJ elt;
+        for(int idx=0; idx<count; idx++) {
+        	index = this.RANDOM.nextInt(this.unreference.size());
+        
+        	elt = this.unreference.get(index);
+        	assertFalse(this.collection.contains(elt));
+        }
+    }
+
+	/**
+	 */
+    public void testIterator() {
+        initCollectionWith(this.reference);        
+	
+        // Test the content
+    	OBJ s;
+    	Iterator<OBJ> iter = this.collection.iterator();
+    	boolean asOne = false;
+    	while (iter.hasNext()) {
+    		s = iter.next();
+    		asOne = true;
+    		assertTrue(this.reference.remove(s));
+    	}
+
+    	assertTrue(asOne);
+    	assertTrue(this.reference.isEmpty());
+    }
+
+	/**
+	 */
+	public void testContainsAll() {
+        initCollectionWith(this.reference);        
+	
+        // Test the content
+    	assertTrue(this.reference.containsAll(this.collection));
+    	assertTrue(this.collection.containsAll(this.reference));
+	}
+    
+	/**
+	 */
+	public void testToArray() {
+        initCollectionWith(this.reference);        
+	
+        // Test the content
+    	assertEpsilonEquals(this.reference.toArray(),this.collection.toArray());
+	}
+	
+	/**
+	 */
+	public void testToArrayArray() {
+        initCollectionWith(this.reference);        
+	
+        // Test the content if the array has the right size
+        Object[] tab = new Object[this.reference.size()];
+    	assertEpsilonEquals(this.reference.toArray(),this.collection.toArray(tab));
+    	assertEpsilonEquals(this.reference.toArray(),tab);
+
+        // Test the content if the array is too small
+        tab = new Object[this.reference.size()/2];
+        Object[] tab2 = this.collection.toArray(tab);
+        assertEpsilonEquals(this.reference.toArray(),tab2);
+    	assertNotEpsilonEquals(tab2,tab);
+	}
+
+	/**
+	 */
+	public void testClear() {
+        initCollectionWith(this.reference);        
+    	
+        // Remove elements
+    	this.collection.clear();
+
+		// Collects the objects
+    	assertTrue(this.collection.isEmpty());
+	}
+	
+	/**
+	 */
+	public void testAddE() {
+        initCollectionWith(this.reference);        
+
+        String msg;
+        int testCount = this.RANDOM.nextInt(5)+1;
+        
+        for(int i=0; i<testCount; i++) {
+        	msg = "test "+(i+1)+"/"+testCount; //$NON-NLS-1$ //$NON-NLS-2$
+        
+	        // Add an element
+	        OBJ newElement = createContentInstance();
+	        this.reference.add(newElement);
+	        assertTrue(msg,this.collection.add(newElement));
+	        assertEquals(msg,this.reference.size(), this.collection.size());
+	        assertTrue(msg,this.collection.contains(newElement));
+	    	assertEpsilonEquals(msg,this.reference.toArray(),this.collection.toArray());
+        }
+	}
+
+	/**
+	 */
+	public void testRemoveObject() {
+        String msg;
+	    int testCount = this.RANDOM.nextInt(5)+5;
+        int removalIndex;
+        
+        for(int i=0; i<testCount; i++) {
+        	msg = "test "+(i+1)+"/"+testCount; //$NON-NLS-1$ //$NON-NLS-2$
+
+        	removalIndex = this.RANDOM.nextInt(this.reference.size());
+
+            initCollectionWith(this.reference);        
+
+            OBJ toRemove = this.reference.get(removalIndex);
+            
+	        // Remove elements
+	        assertTrue(msg,this.collection.remove(toRemove));
+	
+	        assertFalse(msg,this.collection.contains(toRemove));
+	        this.reference.remove(toRemove);
+	    	assertEpsilonEquals(msg,this.reference.toArray(),this.collection.toArray());
+        }
+	}
+	
+	/**
+	 */
+	public void testRemoveAll() {
+        initCollectionWith(this.reference);        
+        
+        fillCollectionWith(this.unreference);
+        assertEquals(this.reference.size()+this.unreference.size(), this.collection.size());
+        
+        assertTrue(this.collection.removeAll(this.reference));
+        assertEquals(this.unreference.size(), this.collection.size());
+    	assertEpsilonEquals(this.unreference,this.collection);
+	}
+
+	/**
+	 */
+	public void testRetainAll() {
+        initCollectionWith(this.reference);        
+        
+        fillCollectionWith(this.unreference);
+        assertEquals(this.reference.size()+this.unreference.size(), this.collection.size());
+        
+        assertTrue(this.collection.retainAll(this.reference));
+        assertEquals(this.reference.size(), this.collection.size());
+    	assertEpsilonEquals(this.reference,this.collection);
+	}
+
+}


Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractCollectionTestCase.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractMapTestCase.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractMapTestCase.java	                        (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractMapTestCase.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,335 @@
+/* $Id$
+ * 
+ * Copyright (c) 2006-10, Multiagent Team, Laboratoire Systemes et Transport,
+ *                        Universite de Technologie de Belfort-Montbeliard.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * @param <K>
+ * @param <V>
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public abstract class AbstractMapTestCase<K,V> extends AbstractTestCase {
+
+	private final Random RANDOM = new Random();
+	
+	/**
+	 */
+	protected HashMap<K,V> reference;
+	/**
+	 */
+	protected HashMap<K,V> unreference;
+	/**
+	 */
+	protected Map<K,V> map;
+	
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+		int count = this.RANDOM.nextInt(400)+100;
+		this.reference = new HashMap<K,V>(count);
+		for(int idx=0; idx<count; idx++) {
+			this.reference.put(createKeyInstance("in/"), createValueInstance("in/")); //$NON-NLS-1$//$NON-NLS-2$
+		}
+		
+		count = this.RANDOM.nextInt(5)+5;
+		this.unreference = new HashMap<K,V>(count);
+		for(int idx=0; idx<count; idx++) {
+			this.unreference.put(createKeyInstance("out/"), createValueInstance("out/")); //$NON-NLS-1$//$NON-NLS-2$
+		}
+
+		this.map = createMap();
+	}
+	
+	/**
+	 * @param prefix
+	 * @return an instance
+	 */
+	protected abstract K createKeyInstance(String prefix);
+	
+	/**
+	 * @param prefix
+	 * @return an instance
+	 */
+	protected abstract V createValueInstance(String prefix);
+
+	/**
+	 * @return a map
+	 */
+	protected abstract Map<K,V> createMap();
+	
+	/**
+	 * @param toAdd
+	 */
+	protected void initMapWith(Map<K,V> toAdd) {
+		this.map.clear();
+		this.map.putAll(toAdd);
+	}
+	
+	/**
+	 * @param toAdd
+	 */
+	protected void fillMapWith(Map<K,V> toAdd) {
+		this.map.putAll(toAdd);
+	}
+	
+	@Override
+	public void tearDown() throws Exception {
+		this.map = null;
+		this.unreference = null;
+		this.reference = null;
+		super.tearDown();
+	}
+	
+	private static <KK> KK key(Map<KK,?> map, int index) {
+		int i = 0; 
+		for(KK key : map.keySet()) {
+			if (i==index) return key;
+			++i;
+		}
+		throw new IndexOutOfBoundsException();
+	}
+	
+	private static <VV> VV value(Map<?,VV> map, int index) {
+		int i = 0; 
+		for(VV value : map.values()) {
+			if (i==index) return value;
+			++i;
+		}
+		throw new IndexOutOfBoundsException();
+	}
+
+	/**
+     */
+    public void testSize() {
+        assertEquals(0, this.map.size());
+        initMapWith(this.reference);        
+        assertEquals(this.reference.size(), this.map.size());
+    }
+
+    /**
+     */
+    public void testIsEmpty() {
+        assertTrue(this.map.isEmpty());
+        initMapWith(this.reference);        
+        assertFalse(this.map.isEmpty());
+    }
+
+    /**
+     */
+    public void testEntrySet() {
+    	Set<Entry<K,V>> entries;
+    	
+    	entries = this.map.entrySet();
+    	assertTrue(entries.isEmpty());
+    	
+    	initMapWith(this.reference);
+
+    	entries = this.map.entrySet();
+    	assertFalse(entries.isEmpty());
+    	assertEpsilonEquals(this.reference.entrySet(), entries);
+    }
+
+    /**
+     */
+    public void testContainsKey() {
+    	initMapWith(this.reference);
+        int count = this.RANDOM.nextInt(50)+50;
+        for(int idx=0; idx<count; idx++) {
+        	int index = this.RANDOM.nextInt(this.reference.size());
+        	assertTrue("#"+idx, this.map.containsKey(key(this.reference,index))); //$NON-NLS-1$
+        }
+        count = this.RANDOM.nextInt(5)+5;
+        int index;
+        K elt;
+        for(int idx=0; idx<count; idx++) {
+        	index = this.RANDOM.nextInt(this.unreference.size());
+        	elt = key(this.unreference, index);
+        	assertFalse("#"+idx, this.map.containsKey(elt)); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     */
+    public void testContainsValue() {
+    	initMapWith(this.reference);
+        int count = this.RANDOM.nextInt(50)+50;
+        for(int idx=0; idx<count; idx++) {
+        	int index = this.RANDOM.nextInt(this.reference.size());
+        	assertTrue("#"+idx, this.map.containsValue(value(this.reference,index))); //$NON-NLS-1$
+        }
+        count = this.RANDOM.nextInt(5)+5;
+        int index;
+        V elt;
+        for(int idx=0; idx<count; idx++) {
+        	index = this.RANDOM.nextInt(this.unreference.size());
+        	elt = value(this.unreference, index);
+        	assertFalse("#"+idx, this.map.containsValue(elt)); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     */
+    public void testGet() {
+        int count = this.RANDOM.nextInt(50)+50;
+        for(int idx=0; idx<count; idx++) {
+        	int index = this.RANDOM.nextInt(this.reference.size());
+        	assertNull("#"+idx, this.map.get(key(this.reference,index))); //$NON-NLS-1$
+        }
+        count = this.RANDOM.nextInt(5)+5;
+        int index;
+        K elt;
+        for(int idx=0; idx<count; idx++) {
+        	index = this.RANDOM.nextInt(this.unreference.size());
+        	elt = key(this.unreference, index);
+        	assertNull("#"+idx, this.map.get(elt)); //$NON-NLS-1$
+        }
+        
+        initMapWith(this.reference);
+
+        count = this.RANDOM.nextInt(50)+50;
+        for(int idx=0; idx<count; idx++) {
+        	index = this.RANDOM.nextInt(this.reference.size());
+        	elt = key(this.reference, index);
+        	assertEquals("#"+idx, this.reference.get(elt), this.map.get(elt)); //$NON-NLS-1$
+        }
+        count = this.RANDOM.nextInt(5)+5;
+        for(int idx=0; idx<count; idx++) {
+        	index = this.RANDOM.nextInt(this.unreference.size());
+        	elt = key(this.unreference, index);
+        	assertNull("#"+idx, this.map.get(elt)); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     */
+    public void testPut() {
+        int count = this.RANDOM.nextInt(50)+50;
+        for(int idx=0; idx<count; idx++) {
+        	K key = createKeyInstance("tmp/"); //$NON-NLS-1$
+        	V value = createValueInstance("tmp/"); //$NON-NLS-1$
+        	this.map.put(key, value);
+        	assertSame(value, this.map.get(key));
+        }
+    }
+
+    /**
+     */
+    public void testRemove() {
+        initMapWith(this.reference);
+
+        int index, count;
+        K elt;
+        
+        count = this.RANDOM.nextInt(50)+50;
+        for(int idx=0; !this.reference.isEmpty() && idx<count; idx++) {
+        	index = this.RANDOM.nextInt(this.reference.size());
+        	elt = key(this.reference, index);
+        	assertSame("#"+idx, this.reference.get(elt), this.map.remove(elt)); //$NON-NLS-1$
+        	this.reference.remove(elt);
+        	assertNull("#"+idx, this.map.get(elt)); //$NON-NLS-1$
+        }
+        count = this.RANDOM.nextInt(5)+5;
+        for(int idx=0; idx<count; idx++) {
+        	index = this.RANDOM.nextInt(this.unreference.size());
+        	elt = key(this.unreference, index);
+        	assertNull("#"+idx, this.map.remove(elt)); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     */
+    public void testPutAll() {
+        int index, count;
+        K elt;
+        
+        this.map.putAll(this.reference);
+
+        count = this.RANDOM.nextInt(50)+50;
+        for(int idx=0; idx<count; idx++) {
+        	index = this.RANDOM.nextInt(this.reference.size());
+        	elt = key(this.reference, index);
+        	assertEquals("#"+idx, this.reference.get(elt), this.map.get(elt)); //$NON-NLS-1$
+        }
+        count = this.RANDOM.nextInt(5)+5;
+        for(int idx=0; idx<count; idx++) {
+        	index = this.RANDOM.nextInt(this.unreference.size());
+        	elt = key(this.unreference, index);
+        	assertNull("#"+idx, this.map.get(elt)); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     */
+    public void testClear() {
+    	assertEquals(0, this.map.size());
+    	assertTrue(this.map.isEmpty());
+    	
+    	initMapWith(this.reference);
+    	assertEquals(this.reference.size(), this.map.size());
+    	assertFalse(this.map.isEmpty());
+    	
+    	this.map.clear();
+    	
+    	assertEquals(0, this.map.size());
+    	assertTrue(this.map.isEmpty());
+    }
+
+    /**
+     */
+    public void testKeySet() {
+    	Set<K> keys;
+    	
+    	keys = this.map.keySet();
+    	assertTrue(keys.isEmpty());
+    	
+    	initMapWith(this.reference);
+
+    	keys = this.map.keySet();
+    	assertFalse(keys.isEmpty());
+    	assertEpsilonEquals(this.reference.keySet(), keys);
+    }
+
+    /**
+     */
+    public void testValues() {
+    	Collection<V> values;
+    	
+    	values = this.map.values();
+    	assertTrue(values.isEmpty());
+    	
+    	initMapWith(this.reference);
+
+    	values = this.map.values();
+    	assertFalse(values.isEmpty());
+    	assertEpsilonEquals(this.reference.values(), values);
+    }
+
+}


Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractMapTestCase.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractReferencableValueMapTestCase.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractReferencableValueMapTestCase.java	                        (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractReferencableValueMapTestCase.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,48 @@
+/* $Id$
+ * 
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.UUID;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public abstract class AbstractReferencableValueMapTestCase extends AbstractMapTestCase<String,String> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected String createKeyInstance(String prefix) {
+		return prefix+UUID.randomUUID().toString();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected String createValueInstance(String prefix) {
+		return prefix+UUID.randomUUID().toString();
+	}
+
+}


Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractReferencableValueMapTestCase.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Copied: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractTestCase.java (from rev 312, trunk/arakhneRefs/src/test/java/org/arakhne/junit/AbstractTestCase.java)
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractTestCase.java	                        (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractTestCase.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,852 @@
+/* $Id$
+ * 
+ * Copyright (C) 2007-09 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.awt.geom.Point2D;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Map.Entry;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+/** Test case with utility functions.
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid org.arakhne.afc
+ * @mavenartifactid arakhneRefs
+ */
+public abstract class AbstractTestCase extends TestCase {
+	
+	private static String arrayToString(Object o) {
+		if (o==null) return null;
+		if (o instanceof boolean[])
+			return Arrays.toString((boolean[])o);
+		if (o instanceof byte[])
+			return Arrays.toString((byte[])o);
+		if (o instanceof char[])
+			return Arrays.toString((char[])o);
+		if (o instanceof short[])
+			return Arrays.toString((short[])o);
+		if (o instanceof int[])
+			return Arrays.toString((int[])o);
+		if (o instanceof long[])
+			return Arrays.toString((long[])o);
+		if (o instanceof float[])
+			return Arrays.toString((float[])o);
+		if (o instanceof double[])
+			return Arrays.toString((double[])o);
+		if (o instanceof Object[])
+			return Arrays.toString((Object[])o);
+		return o.toString();
+	}
+
+	/** Replies if the given elements is in the array.
+	 * <p>
+	 * This function is based on {@link Object#equals(java.lang.Object)}.
+	 */
+	private static <T> boolean arrayContainsAll(T[] elts, T[] array) {
+		boolean found;
+		for (T elt : elts) {
+			found = false;
+			for (T t : array) {
+				if ((t==elt)||
+					((t!=null)&&(t.equals(elt)))) {
+					found = true;
+					break;
+				}
+			}
+			if (!found) return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Format a failure message for invalid value.
+	 * 
+	 * @param message is the message to reply.
+	 * @param expected is the expected object.
+	 * @param actual is the actual value of the object.
+	 * @return the message
+	 */
+	protected  String formatFailMessage(String message, Object expected, Object actual) {
+		StringBuffer formatted = new StringBuffer();
+		if (message!=null) {
+			formatted.append(message);
+			formatted.append(' ');
+		}
+		formatted.append("expected:<"); //$NON-NLS-1$
+		formatted.append(arrayToString(expected));
+		formatted.append("> but was:<"); //$NON-NLS-1$
+		formatted.append(arrayToString(actual));
+		formatted.append(">"); //$NON-NLS-1$
+		return formatted.toString();
+	}
+
+	/**
+	 * Format a failure message for invalid value.
+	 * 
+	 * @param message is the first part of the message (optional).
+	 * @param msg is the second part of the message (mandatory).
+	 * @param actual is the actual value of the object.
+	 * @return the message
+	 */
+	protected  String formatFailMessage(String message, String msg, Object actual) {
+		StringBuffer formatted = new StringBuffer();
+		if (message!=null) {
+			formatted.append(message);
+			formatted.append(' ');
+		}
+		formatted.append(msg);
+		formatted.append(" but was:<"); //$NON-NLS-1$
+		formatted.append(arrayToString(actual));
+		formatted.append(">"); //$NON-NLS-1$
+		return formatted.toString();
+	}
+
+	/**
+	 * Format a failure message for not-expected values.
+	 * 
+	 * @param message is the message to reply.
+	 * @param notexpected is the not-expected object.
+	 * @return the message
+	 */
+	protected String formatFailNegMessage(String message, Object notexpected) {
+		StringBuffer formatted = new StringBuffer();
+		if (message!=null) {
+			formatted.append(message);
+			formatted.append(' ');
+		}
+		formatted.append("not expected:<"); //$NON-NLS-1$
+		formatted.append(arrayToString(notexpected));
+		formatted.append("> but the same"); //$NON-NLS-1$
+		return formatted.toString();
+	}
+
+	/** Asserts that two objects are not equal. If they are
+	 * an AssertionFailedError is thrown with the given message.
+	 * 
+	 * @param message is the error message to put inside the assertion.
+	 * @param notexpected is the value which is not expected by the unit test.
+	 * @param actual is the actual value of the object in the unit test.
+	 */
+	protected void assertNotEquals(String message, Object notexpected, Object actual) {
+		if ((notexpected!=actual)&&
+			((notexpected==null)
+			 ||
+			 (!notexpected.equals(actual)))) return;
+		fail(formatFailNegMessage(message, notexpected));
+	}
+
+	/** Asserts that two objects are not equal. If they are
+	 * an AssertionFailedError is thrown with the given message.
+	 * 
+	 * @param notexpected is the value which is not expected by the unit test.
+	 * @param actual is the actual value of the object in the unit test.
+	 */
+	protected void assertNotEquals(Object notexpected, Object actual) {
+	    assertNotEquals(null, notexpected, actual);
+	}
+	
+	/** Asserts that the actuel object is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown with the given message.
+	 * 
+	 * @param message is the error message to put inside the assertion.
+	 * @param expectedObjects are the set of expected values during the unit test.
+	 * @param actual is the actual value of the object in the unit test.
+	 */
+	protected void assertEquals(String message, Object[] expectedObjects, Object actual) {
+		if ((expectedObjects!=null)&&(expectedObjects.length>0)) {
+			for (Object object : expectedObjects) {
+				if ((object==null)&&(actual==null)) return;
+				if ((object!=null)&&(object.equals(actual))) return;
+			}
+		}
+		fail(formatFailMessage(message, expectedObjects, actual));
+	}
+
+	/** Asserts that the actuel object is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param expectedObjects are the set of expected values during the unit test.
+	 * @param actual is the actual value of the object in the unit test.
+	 */
+	protected void assertEquals(Object[] expectedObjects, Object actual) {
+	    assertEquals(null, expectedObjects, actual);
+	}
+
+	/** Asserts that the actuel object is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown with the given message.
+	 *
+	 * @param <T> is the type of the array.
+	 * @param message is the error message to put inside the assertion.
+	 * @param expectedObjects are the set of expected values during the unit test.
+	 * @param actual is the actual value of the objects in the unit test.
+	 */
+	protected <T> void assertEquals(String message, T[] expectedObjects, T[] actual) {
+		if (expectedObjects==actual) return;
+		if ((expectedObjects!=null)&&(actual!=null)&&
+			(expectedObjects.length==actual.length)) {
+			boolean ok = true;
+			for(int i=0; i<expectedObjects.length; i++) {
+				if ((expectedObjects[i]!=null)||(actual[i]!=null)) {
+					if ((expectedObjects[i]==null)||(!expectedObjects[i].equals(actual[i]))) {
+						ok = false;
+						break;
+					}
+				}
+			}
+			if (ok) return;
+		}
+		fail(formatFailMessage(message, expectedObjects, actual));
+	}
+
+	/** Asserts that the actuel object is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 *
+	 * @param <T> is the type of the array.
+	 * @param expectedObjects are the set of expected values during the unit test.
+	 * @param actual is the actual value of the objects in the unit test.
+	 */
+	protected <T> void assertEquals(T[] expectedObjects, T[] actual) {
+	    assertEquals(null, expectedObjects, actual);
+	}
+
+	/** Asserts that the actuel object is not equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown with the given message.
+	 *
+	 * @param <T> is the type of the array.
+	 * @param message is the error message to put inside the assertion.
+	 * @param expectedObjects are the set of expected values during the unit test.
+	 * @param actual is the actual value of the objects in the unit test.
+	 */
+	protected <T> void assertNotEquals(String message, T[] expectedObjects, T[] actual) {
+		if (expectedObjects!=actual) {			
+			if ((expectedObjects!=null)&&(actual!=null)) {
+				if (expectedObjects.length!=actual.length) return;
+				boolean ok = true;
+				for(int i=0; i<expectedObjects.length; i++) {
+					if ((expectedObjects[i]!=null)||(actual[i]!=null)) {
+						if ((expectedObjects[i]==null)||(!expectedObjects[i].equals(actual[i]))) {
+							ok = false;
+							break;
+						}
+					}
+				}
+				if (!ok) return;
+			}
+			else return;
+		}
+		fail(formatFailMessage(message, expectedObjects, actual));
+	}
+
+	/** Asserts that the actuel object is not equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 *
+	 * @param <T> is the type of the array.
+	 * @param expectedObjects are the set of expected values during the unit test.
+	 * @param actual is the actual value of the objects in the unit test.
+	 */
+	protected <T> void assertNotEquals(T[] expectedObjects, T[] actual) {
+	    assertNotEquals(null, expectedObjects, actual);
+	}
+
+	/** Asserts that the actuel object is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * This assertion function tests the types of its parameters to call the best
+	 * {@code assertEquals} function.
+	 * 
+	 * @param expected is the expected value during the unit test.
+	 * @param actual is the actual value of the object during the unit test.
+	 * @see #assertEquals(Object, Object)
+	 * @see #assertEquals(Object[], Object)
+	 * @see #assertEquals(Object[], Object[])
+	 */
+	protected void assertEqualsGeneric(Object expected, Object actual) {
+		assertEqualsGeneric(null, expected, actual);
+	}
+
+	/** Asserts that the actuel object is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * This assertion function tests the types of its parameters to call the best
+	 * {@code assertEquals} function.
+	 * 
+	 * @param message is the error message to put inside the assertion.
+	 * @param expected is the expected value during the unit test.
+	 * @param actual is the actual value of the object during the unit test.
+	 * @see #assertEquals(Object, Object)
+	 * @see #assertEquals(Object[], Object)
+	 * @see #assertEquals(Object[], Object[])
+	 */
+	protected void assertEqualsGeneric(String message, Object expected, Object actual) {
+		if ((expected!=null)&&(actual!=null)&&(expected.getClass().isArray())) {
+			if (actual.getClass().isArray())
+				assertEquals(message, (Object[])expected, (Object[])actual);
+			else
+				assertEquals(message, (Object[])expected, actual);
+		}
+		else assertEquals(message, expected, actual);
+	}
+
+	/** Asserts that the actuel similar is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <T> is the type of the values
+	 * @param expectedObjects are the expected values during the unit test.
+	 * @param actual are the actual values of the objects during the unit test.
+	 */
+	protected <T> void assertSimilars(T[] expectedObjects, T[] actual) {
+	    assertSimilars(null, expectedObjects, actual);
+	}
+
+	/** Asserts that the actuel similar is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <T> is the type of the values
+	 * @param message is the error message to put inside the assertion.
+	 * @param expectedObjects are the expected values during the unit test.
+	 * @param actual are the actual values of the objects during the unit test.
+	 */
+	protected <T> void assertSimilars(String message, T[] expectedObjects, T[] actual) {
+		if (expectedObjects==actual) return;
+		if ((arrayContainsAll(expectedObjects, actual))&&(arrayContainsAll(actual, expectedObjects)))
+			return;
+		fail(formatFailMessage(message, expectedObjects, actual));
+	}
+
+	/** Asserts that the actuel similar is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <T> is the type of the values
+	 * @param expectedObjects are the expected values during the unit test.
+	 * @param actual are the actual values of the objects during the unit test.
+	 */
+	protected <T> void assertSimilars(Collection<T> expectedObjects, Collection<T> actual) {
+	    assertSimilars(null, expectedObjects, actual);
+	}
+	
+	/** Asserts that the actuel similar is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <T> is the type of the values
+	 * @param message is the error message to put inside the assertion.
+	 * @param expectedObjects are the expected values during the unit test.
+	 * @param actual are the actual values of the objects during the unit test.
+	 */
+	protected <T> void assertSimilars(String message, Collection<T> expectedObjects, Collection<T> actual) {
+		if (expectedObjects==actual) return;
+		if (similars(expectedObjects,actual)) return;
+		fail(formatFailMessage(message, expectedObjects, actual));
+	}
+	
+	private <T> boolean similars(Collection<T> c1, Collection<T> c2) {
+		ArrayList<T> a = new ArrayList<T>();
+		a.addAll(c2);
+		for(T elt : c1) {
+			if (!a.remove(elt)) {
+				return false;
+			}
+		}
+		return a.isEmpty();
+	}
+
+	/** Asserts that the actuel similar is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <T> is the type of the values
+	 * @param expectedObjects are the expected values during the unit test.
+	 * @param actual are the actual values of the objects during the unit test.
+	 */
+	protected <T> void assertEquals(List<T> expectedObjects, List<T> actual) {
+	    assertEquals(null, expectedObjects, actual);
+	}
+	
+	/** Asserts that the actuel similar is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <T> is the type of the values.
+	 * @param message is the error message to put inside the assertion.
+	 * @param expectedObjects are the expected values during the unit test.
+	 * @param actual are the actual values of the objects during the unit test.
+	 */
+	protected <T> void assertEquals(String message, List<T> expectedObjects, List<T> actual) {
+		if (expectedObjects==actual) return;
+		if (equals(expectedObjects,actual)) return;
+		fail(formatFailMessage(message, expectedObjects, actual));
+	}
+
+	private <T> boolean equals(List<T> c1, List<T> c2) {
+		if (c1.size()!=c2.size()) return false;
+		int count = c1.size();
+		T e1, e2;
+		for(int i=0; i<count; i++) {
+			e1 = c1.get(i);
+			e2 = c2.get(i);
+			if ((e1!=e2)&&(!e1.equals(e2))) {
+				return false;
+			}
+		}
+		return true;
+	}
+	
+	/** Asserts that the actuel similar is not equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <T> is the type of the values
+	 * @param expectedObjects are the expected values during the unit test.
+	 * @param actual are the actual values of the objects during the unit test.
+	 */
+	protected <T> void assertNotEquals(List<T> expectedObjects, List<T> actual) {
+	    assertNotEquals(null, expectedObjects, actual);
+	}
+	
+	/** Asserts that the actuel object is not equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <T> is the type of the values
+	 * @param message is the error message to put inside the assertion.
+	 * @param expectedObjects are the expected values during the unit test.
+	 * @param actual are the actual values of the objects during the unit test.
+	 */
+	protected <T> void assertNotEquals(String message, List<T> expectedObjects, List<T> actual) {
+		if ((expectedObjects!=actual)&&(!equals(expectedObjects,actual))) return;
+		fail(formatFailMessage(message, expectedObjects, actual));
+	}
+
+	/** Asserts that the actual object is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <T> is the type of the values
+	 * @param <X> is the element's type of the values if they are arrays.
+	 * @param message is the error message to put inside the assertion.
+	 * @param expected is the expected value during the unit test.
+	 * @param actual are the actual value of the object during the unit test.
+	 */
+	@SuppressWarnings("unchecked")
+	protected <T, X> void assertSimilars(String message, T expected, T actual) {
+		if (expected==actual) return;
+		if (expected instanceof Collection)
+			assertSimilars(message, (Collection<?>)expected, (Collection<?>)actual);
+		else if (expected instanceof Point2D)
+			assertSimilars(message, (Point2D)expected, (Point2D)actual);
+		else if (expected instanceof Date)
+			assertSimilars(message, (Date)expected, (Date)actual);
+		else if (expected.getClass().isArray())
+			assertSimilars(message, (X[])expected, (X[])actual);
+		else
+			assertEquals(message, expected, actual);
+	}
+
+	/** Asserts that the actual object is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <T> is the type of the values.
+	 * @param <X> is the element's type of the values if they are arrays.
+	 * @param message is the error message to put inside the assertion.
+	 * @param expected is the expected value.
+	 * @param actual is the current value.
+	 */
+	protected <T, X> void assertNotSimilars(String message, T expected, T actual) {
+		if (expected!=actual) {
+			try {
+				assertSimilars(message,expected, actual);
+			}
+			catch(AssertionError _) {
+				// ok
+				return;
+			}
+			catch(AssertionFailedError _) {
+				// ok
+				return;
+			}
+		}		
+		fail(formatFailMessage(message, expected, actual));
+	}
+
+	/** Replies if the two objects are similars.
+	 * 
+	 * @param <T> is the type of the values
+	 * @param <X> is the element's type of the values if they are arrays.
+	 * @param obj1
+	 * @param obj2
+	 * @return <code>true</code> if the objects are similar, otherwise <code>false</code>
+	 */
+	protected <T, X> boolean isSimilarObjects(T obj1, T obj2) {
+		if (obj1==obj2) return true;
+		try {
+			assertSimilars(null,obj1, obj2);
+			return true;
+		}
+		catch(AssertionError _) {
+			return false;
+		}
+		catch(AssertionFailedError _) {
+			return false;
+		}
+	}
+
+	/** Asserts that the actuel similar is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <K> is the type of the map keys.
+	 * @param <V> is the type of the map values.
+	 * @param expectedObjects is the expected map.
+	 * @param actual is the current map.
+	 */
+	protected <K,V> void assertDeepSimilars(Map<K,V> expectedObjects, Map<K,V> actual) {
+	    assertDeepSimilars(null, expectedObjects, actual);
+	}
+	
+	/** Asserts that the actuel similar is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <K> is the type of the map keys.
+	 * @param <V> is the type of the map values.
+	 * @param message is the error message to put inside the assertion.
+	 * @param expectedObjects is the expected map.
+	 * @param actual is the current map.
+	 */
+	protected <K,V> void assertDeepSimilars(String message, Map<K,V> expectedObjects, Map<K,V> actual) {
+		if (expectedObjects==actual) return;
+		if (similars(expectedObjects.keySet(), actual.keySet())) {
+			for(Entry<K,V> entry : expectedObjects.entrySet()) {
+				V v1 = entry.getValue();
+				V v2 = actual.get(entry.getKey());
+				assertSimilars(message, v1, v2);
+			}
+			// all values are correct
+			return;
+		}
+		fail(formatFailMessage(message, expectedObjects, actual));
+	}
+
+	/** Asserts that the actuel similar is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <K> is the type of the map keys.
+	 * @param <V> is the type of the map values.
+	 * @param expectedObjects is the expected map.
+	 * @param actual is the current map.
+	 */
+	protected <K,V> void assertNotDeepSimilars(Map<K,V> expectedObjects, Map<K,V> actual) {
+	    assertNotDeepSimilars(null, expectedObjects, actual);
+	}
+	
+	/** Asserts that the actuel similar is equal to one of the expected objects. If not
+	 * an AssertionFailedError is thrown.
+	 * 
+	 * @param <K> is the type of the map keys.
+	 * @param <V> is the type of the map values.
+	 * @param message is the error message to put inside the assertion.
+	 * @param expectedObjects is the expected map.
+	 * @param actual is the current map.
+	 */
+	protected <K,V> void assertNotDeepSimilars(String message, Map<K,V> expectedObjects, Map<K,V> actual) {
+		if (expectedObjects!=actual) {
+			if (!similars(expectedObjects.keySet(), actual.keySet())) return;
+			
+			for(Entry<K,V> entry : expectedObjects.entrySet()) {
+				V v1 = entry.getValue();
+				V v2 = actual.get(entry.getKey());
+				if (!isSimilarObjects(v1, v2)) return;
+			}
+		}
+		fail(formatFailMessage(message, expectedObjects, actual));
+	}
+
+	/** Asserts that the specified value is stricly negative.
+	 * 
+	 * @param number
+	 */
+	protected void assertStrictlyNegative(Number number) {
+		assertStrictlyNegative(null,number);
+	}
+
+	/** Asserts that the specified value is stricly negative.
+	 * 
+	 * @param message is the error message to put inside the assertion.
+	 * @param number
+	 */
+	protected void assertStrictlyNegative(String message, Number number) {
+		if (number.doubleValue()<0.) return;
+		fail(formatFailMessage(message, "expected negative value", number)); //$NON-NLS-1$
+	}
+
+	/** Asserts that the specified value is stricly positive.
+	 * 
+	 * @param number
+	 */
+	protected void assertStrictlyPositive(Number number) {
+		assertStrictlyPositive(null,number);
+	}
+
+	/** Asserts that the specified value is stricly positive.
+	 * 
+	 * @param message is the error message to put inside the assertion.
+	 * @param number
+	 */
+	protected void assertStrictlyPositive(String message, Number number) {
+		if (number.doubleValue()>0.) return;
+		fail(formatFailMessage(message, "expected positive value", number)); //$NON-NLS-1$
+	}
+
+	/** Asserts that the specified value is negative.
+	 * 
+	 * @param number
+	 */
+	protected void assertNegative(Number number) {
+		assertNegative(null,number);
+	}
+
+	/** Asserts that the specified value is negative.
+	 * 
+	 * @param message is the error message to put inside the assertion.
+	 * @param number
+	 */
+	protected void assertNegative(String message, Number number) {
+		if (number.doubleValue()<=0.) return;
+		fail(formatFailMessage(message, "expected negative value", number)); //$NON-NLS-1$
+	}
+
+	/** Asserts that the specified value is positive.
+	 * 
+	 * @param number
+	 */
+	protected void assertPositive(Number number) {
+		assertPositive(null,number);
+	}
+
+	/** Asserts that the specified value is positive.
+	 * 
+	 * @param message is the error message to put inside the assertion.
+	 * @param number
+	 */
+	protected void assertPositive(String message, Number number) {
+		if (number.doubleValue()>=0.) return;
+		fail(formatFailMessage(message, "expected positive value", number)); //$NON-NLS-1$
+	}
+
+	/**
+	 * Replies an array which is containing values randomly selected from the parameter.
+	 * Duplicate values are allowed.
+	 * 
+	 * @param <T> is the type of the values.
+	 * @param availableValues is the collection of available values.
+	 * @return the selected values (possible duplicated)
+	 */
+	@SuppressWarnings("unchecked")
+	protected <T> T[] extractRandomValues(T[] availableValues) {
+		Random rnd = new Random();
+		int count = rnd.nextInt(500);
+		ArrayList<T> tab = new ArrayList<T>(count);
+		for(int i=0; i<count; i++) {
+			tab.add(availableValues[rnd.nextInt(availableValues.length)]);
+		}
+		Class<?> clazz = availableValues.getClass().getComponentType();
+		T[] array = (T[])Array.newInstance(clazz, tab.size());
+		tab.toArray(array);
+		tab.clear();
+		return array;
+	}
+	
+	/** Replies a randomized string.
+	 * 
+	 * @return a random string.
+	 */
+	protected String randomString() {
+		return randomString(-1);
+	}
+
+	/** Replies a randomized string with a max length.
+	 *
+	 * @param maxSize is the max length of the string.
+	 * @return a random string with a max length.
+	 */
+	protected String randomString(int maxSize) {
+		Random rnd = new Random();
+		StringBuffer b = new StringBuffer();
+		int count = rnd.nextInt(maxSize<=0 ? 255 : maxSize-1)+1;
+		for(int i=0; i<count; i++) {
+			char c = (char)('A' + rnd.nextInt(26));
+			b.append(c);
+		}
+		return b.toString();
+	}
+
+	/** Assert the the specified method thrown an exception
+	 * 
+	 * @param self is the calling object
+	 * @param method is the name of the method to invoke
+	 * @param types is the parameter types of the method
+	 * @param parameters is the parameter values to pass at invocation.
+	 */
+	protected void assertException(Object self, String method, Class<?>[] types, Object[] parameters) {
+		assertException(null, self, method, types, parameters);
+	}
+
+	/** Assert the the specified method thrown an exception
+	 * 
+	 * @param message is the error message to put in the assertion.
+	 * @param self is the calling object
+	 * @param method is the name of the method to invoke
+	 * @param types is the parameter types of the method
+	 * @param parameters is the parameter values to pass at invocation.
+	 */
+	protected void assertException(String message, Object self, String method, Class<?>[] types, Object[] parameters) {
+		try {
+			Class<?> clazz = self.getClass();
+			Method methodFunc = clazz.getMethod(method, types);
+			methodFunc.invoke(self, parameters);
+			fail((message==null ? "" : message)+"An exception was attempted but never thrown."); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		catch(Exception _) {
+			// Expected behavior
+		}
+	}
+
+	/** Assert the the specified method thrown an exception
+	 * 
+	 * @param self is the calling object
+	 * @param method is the name of the method to invoke
+	 */
+	protected void assertException(Object self, String method) {
+		assertException(null, self, method, new Class<?>[0], new Object[0]);
+	}
+
+	/** Assert the the specified method thrown an exception
+	 * 
+	 * @param message is the error message to put in the assertion.
+	 * @param self is the calling object
+	 * @param method is the name of the method to invoke
+	 */
+	protected void assertException(String message, Object self, String method) {
+		assertException(message, self, method, new Class<?>[0], new Object[0]);
+	}
+
+	/** Test if the two collections contain the same elements without
+	 * taking into account the order of the elements in the collections.
+	 * 
+	 * @param <T>
+	 * @param expected
+	 * @param actual
+	 */
+	protected <T> void assertEpsilonEquals(Collection<? extends T> expected, Collection<? extends T> actual) {
+		assertEpsilonEquals(null, expected, actual);
+	}
+
+	/** Test if the two collections contain the same elements without
+	 * taking into account the order of the elements in the collections.
+	 *
+	 * @param <T>
+	 * @param message
+	 * @param expected
+	 * @param actual
+	 */
+	protected <T> void assertEpsilonEquals(String message, Collection<? extends T> expected, Collection<? extends T> actual) {
+		ArrayList<T> l = new ArrayList<T>(actual);
+		for(T e : expected) {
+			if (!l.remove(e)) {
+				fail((message==null ? "" : (message+": "))  //$NON-NLS-1$//$NON-NLS-2$
+						+"not similar collections, expected element:"+ //$NON-NLS-1$
+						expected);
+			}
+		}
+		if (!l.isEmpty()) {
+			fail((message==null ? "" : (message+": "))  //$NON-NLS-1$//$NON-NLS-2$
+					+"not similar collections, not expected elements:"+ //$NON-NLS-1$
+					l);
+		}
+	}
+
+	/** Test if the two collections contain the same elements without
+	 * taking into account the order of the elements in the collections.
+	 * 
+	 * @param <T>
+	 * @param expected
+	 * @param actual
+	 */
+	protected <T> void assertEpsilonEquals(T[] expected, T[] actual) {
+		assertEpsilonEquals(null, expected, actual);
+	}
+
+	/** Test if the two collections contain the same elements without
+	 * taking into account the order of the elements in the collections.
+	 *
+	 * @param <T>
+	 * @param message
+	 * @param expected
+	 * @param actual
+	 */
+	protected <T> void assertEpsilonEquals(String message, T[] expected, T[] actual) {
+		ArrayList<T> l = new ArrayList<T>(Arrays.asList(actual));
+		for(T e : expected) {
+			if (!l.remove(e)) {
+				fail((message==null ? "" : (message+": "))  //$NON-NLS-1$//$NON-NLS-2$
+						+"not similar collections, expected element:"+ //$NON-NLS-1$
+						expected.toString());
+			}
+		}
+		if (!l.isEmpty()) {
+			fail((message==null ? "" : (message+": "))  //$NON-NLS-1$//$NON-NLS-2$
+					+"not similar collections, not expected elements:"+ //$NON-NLS-1$
+					l.toString());
+		}
+	}
+
+	/** Test if the two collections do no contain the same elements without
+	 * taking into account the order of the elements in the collections.
+	 * 
+	 * @param <T>
+	 * @param expected
+	 * @param actual
+	 */
+	protected <T> void assertNotEpsilonEquals(T[] expected, T[] actual) {
+		assertNotEpsilonEquals(null, expected, actual);
+	}
+
+	/** Test if the two collections do no contain the same elements without
+	 * taking into account the order of the elements in the collections.
+	 * 
+	 * @param <T>
+	 * @param message
+	 * @param expected
+	 * @param actual
+	 */
+	protected <T> void assertNotEpsilonEquals(String message, T[] expected, T[] actual) {
+		ArrayList<T> l = new ArrayList<T>(Arrays.asList(actual));
+		for(T e : expected) {
+			if (!l.remove(e)) return;
+		}
+		if (l.isEmpty()) {
+			fail((message==null ? "" : (message+": "))  //$NON-NLS-1$//$NON-NLS-2$
+					+"similar collections when not attempted"); //$NON-NLS-1$
+		}
+	}
+
+}

Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractWeakCollectionTestCase.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractWeakCollectionTestCase.java	                        (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractWeakCollectionTestCase.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,41 @@
+/* $Id$
+ * 
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.UUID;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public abstract class AbstractWeakCollectionTestCase extends AbstractCollectionTestCase<String> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected String createContentInstance() {
+		return UUID.randomUUID().toString();
+	}
+
+
+}


Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractWeakCollectionTestCase.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueHashMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueHashMapTest.java	                        (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueHashMapTest.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ * 
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class PhantomValueHashMapTest extends AbstractReferencableValueMapTestCase {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected Map<String,String> createMap() {
+		return new PhantomValueHashMap<String,String>();
+	}
+
+}


Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueHashMapTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueTreeMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueTreeMapTest.java	                        (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueTreeMapTest.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ * 
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class PhantomValueTreeMapTest extends AbstractReferencableValueMapTestCase {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected Map<String,String> createMap() {
+		return new PhantomValueTreeMap<String,String>();
+	}
+
+}


Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueTreeMapTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueHashMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueHashMapTest.java	                        (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueHashMapTest.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ * 
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class SoftValueHashMapTest extends AbstractReferencableValueMapTestCase {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected Map<String,String> createMap() {
+		return new SoftValueHashMap<String,String>();
+	}
+
+}


Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueHashMapTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Deleted: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java	2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -1,382 +0,0 @@
-/* $Id$
- * 
- * Copyright (C) 2007-09 Stephane GALLAND This library 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 library 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 library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * This program is free software; you can redistribute it and/or modify
- */
-package org.arakhne.util.ref;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Random;
-import java.util.Map.Entry;
-
-import org.arakhne.junit.AbstractTestCase;
-
-/**
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
-public class SoftValueMapTest extends AbstractTestCase {
-
-	private static final int REFERENCE_SIZE = 0; 
-
-	private final HashMap<String,String> reference = new HashMap<String,String>();
-
-	private static void collect() {
-		System.gc();System.gc();System.gc();
-	}
-
-	private void spawnReference() {
-		this.reference.clear();
-		Random rnd = new Random();
-		int count = rnd.nextInt(REFERENCE_SIZE+1)+5;
-		String str;
-		for(int i=0; i<count; i++) {
-			str = randomString(10);
-			this.reference.put(
-					Integer.toString(i)+str,
-					str);
-		}
-		str = null;
-	}
-
-	private String getReferenceObject(int index) {
-		Object[] tab = this.reference.keySet().toArray();
-		return (String)tab[index];
-	}
-
-	private Map<String,String> removeElementsFromReference() {
-		HashMap<String,String> removed = new HashMap<String,String>();
-		Random rnd = new Random();
-		int index;
-		int count = rnd.nextInt(this.reference.size()/4)+1;
-		String key, value;
-		for(int i=0; i<count; i++) {
-			index = rnd.nextInt(this.reference.size());
-			key = getReferenceObject(index);
-			value = this.reference.remove(key);
-			removed.put(key,value);
-		}
-		key = null;
-		value =  null;
-		return removed;
-	}
-
-	@Override
-	public void setUp() {
-		spawnReference();
-	}
-
-	@Override
-	public void tearDown() {
-		this.reference.clear();
-	}
-
-	/**
-	 */
-	public void testSoftValueMapMap() {
-		SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
-		assertDeepSimilars(this.reference, test);
-	}
-
-	/**
-	 */
-	public void testSize() {
-		SoftValueMap<String,String> test = new SoftValueMap<String,String>();
-		assertEquals(0, test.size());
-
-		test = new SoftValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-		assertEquals(this.reference.size(), test.size());
-
-		Map<String,String> removed = removeElementsFromReference();
-		assertNotNull(removed);
-		int count = removed.size();
-		removed = null;
-
-		collect();
-
-		assertTrue(((this.reference.size()-count)<=test.size())||(this.reference.size()>test.size()));		
-	}
-
-	/**
-	 */
-	public void testIsEmpty() {
-		SoftValueMap<String,String> test = new SoftValueMap<String,String>();
-		assertTrue(test.isEmpty());
-
-		test = new SoftValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-		assertFalse(test.isEmpty());
-
-		removeElementsFromReference();
-
-		collect();
-
-		assertFalse(test.isEmpty());
-
-		this.reference.clear();
-
-		collect();
-
-		assertFalse(test.isEmpty());
-	}
-
-	/**
-	 */
-	public void testContainsKey() {
-		SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-		assertDeepSimilars(this.reference, test);
-
-		// Test the content
-		{
-			String elt;
-			Iterator<String> iter = this.reference.keySet().iterator(); 
-			while (iter.hasNext()) {
-				elt = iter.next();
-				assertTrue(test.containsKey(elt));
-			}
-			elt = null;
-		}
-		assertDeepSimilars(this.reference, test);
-
-		Map<String,String> removedElements = removeElementsFromReference();
-		int originalSize = removedElements.size() + this.reference.size();
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		assertEquals(originalSize, test.size());
-		assertNotDeepSimilars(this.reference, test);
-
-		// Clear the list of removed elements, which will cause collecting
-		removedElements.clear();
-		removedElements = null;
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		assertNotEquals(this.reference.size(), test.size());
-		for(String elt : this.reference.keySet()) {
-			assertTrue(test.containsKey(elt));
-		}
-	}
-
-	/**
-	 */
-	public void testContainsValue() {
-		SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-		assertDeepSimilars(this.reference, test);
-
-		// Test the content
-		{
-			String elt;
-			Iterator<String> iter = this.reference.values().iterator(); 
-			while (iter.hasNext()) {
-				elt = iter.next();
-				assertTrue(test.containsValue(elt));
-			}
-			elt = null;
-		}
-		assertDeepSimilars(this.reference, test);
-
-		Map<String,String> removedElements = removeElementsFromReference();
-		int originalSize = removedElements.size() + this.reference.size();
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		assertEquals(originalSize, test.size());
-		assertNotDeepSimilars(this.reference, test);
-
-		// Clear the list of removed elements, which will cause collecting
-		removedElements.clear();
-		removedElements = null;
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		assertNotEquals(this.reference.size(), test.size());
-		for(String elt : this.reference.values()) {
-			assertTrue(test.containsValue(elt));
-		}
-	}
-
-	/**
-	 */
-	public void testEntryIterator() {
-		SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-
-		// Test the content
-		{
-			assertDeepSimilars(this.reference, test);
-			Entry<String,String> e;
-			Iterator<Entry<String,String>> iter = test.entrySet().iterator();
-			while (iter.hasNext()) {
-				e = iter.next();
-				assertTrue(this.reference.containsKey(e.getKey()));
-				assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
-			}
-		}
-
-		// Remove elements
-		Map<String,String> baseElements = new HashMap<String,String>(this.reference);
-		removeElementsFromReference();
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		{
-			assertNotDeepSimilars(this.reference, test);
-			Entry<String,String> e;
-			Iterator<Entry<String,String>> iter = test.entrySet().iterator();
-			while (iter.hasNext()) {
-				e = iter.next();
-				assertTrue(baseElements.containsKey(e.getKey()));
-				assertEquals(baseElements.get(e.getKey()),baseElements.get(e.getKey()));
-			}
-		}
-
-		// Clear the list of removed elements, which will cause collecting
-		baseElements.clear();
-		baseElements = null;
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		{
-			assertNotDeepSimilars(this.reference, test);
-			Entry<String,String> e;
-			Iterator<Entry<String,String>> iter = test.entrySet().iterator();
-			while (iter.hasNext()) {
-				e = iter.next();
-				assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
-			}
-		}
-	}
-
-	/**
-	 */
-	public void testKeyIterator() {
-		SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-
-		// Test the content
-		{
-			assertDeepSimilars(this.reference, test);
-			String k;
-			Iterator<String> iter = test.keySet().iterator();
-			while (iter.hasNext()) {
-				k = iter.next();
-				assertTrue(this.reference.containsKey(k));
-			}
-		}
-
-		// Remove elements
-		Map<String,String> baseElements = new HashMap<String,String>(this.reference);
-		removeElementsFromReference();
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		{
-			assertNotDeepSimilars(this.reference, test);
-			String k;
-			Iterator<String> iter = test.keySet().iterator();
-			while (iter.hasNext()) {
-				k = iter.next();
-				assertTrue(baseElements.containsKey(k));
-			}
-		}
-
-		// Clear the list of removed elements, which will cause collecting
-		baseElements.clear();
-		baseElements = null;
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		{
-			assertNotDeepSimilars(this.reference, test);
-		}
-	}
-
-	/**
-	 */
-	public void testValueIterator() {
-		SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-
-		// Test the content
-		{
-			assertDeepSimilars(this.reference, test);
-			String v;
-			Iterator<String> iter = test.values().iterator();
-			while (iter.hasNext()) {
-				v = iter.next();
-				assertTrue(this.reference.containsValue(v));
-			}
-			v = null;
-			iter = null;
-		}
-
-		// Remove elements
-		Map<String,String> baseElements = new HashMap<String,String>(this.reference);
-		removeElementsFromReference();
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		{
-			assertNotDeepSimilars(this.reference, test);
-			String v;
-			Iterator<String> iter = test.values().iterator();
-			while (iter.hasNext()) {
-				v = iter.next();
-				assertTrue(baseElements.containsValue(v));
-			}
-			v = null;
-			iter = null;
-		}
-
-		// Clear the list of removed elements, which will cause collecting
-		baseElements.clear();
-		baseElements = null;
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		{
-			assertNotDeepSimilars(this.reference, test);
-		}
-	}
-
-}

Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueTreeMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueTreeMapTest.java	                        (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueTreeMapTest.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ * 
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class SoftValueTreeMapTest extends AbstractReferencableValueMapTestCase {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected Map<String,String> createMap() {
+		return new SoftValueTreeMap<String,String>();
+	}
+
+}


Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueTreeMapTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueHashMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueHashMapTest.java	                        (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueHashMapTest.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ * 
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class WeakValueHashMapTest extends AbstractReferencableValueMapTestCase {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected Map<String,String> createMap() {
+		return new WeakValueHashMap<String,String>();
+	}
+
+}


Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueHashMapTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Deleted: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java	2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -1,399 +0,0 @@
-/* $Id$
- * 
- * Copyright (C) 2007-09 Stephane GALLAND This library 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 library 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 library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * This program is free software; you can redistribute it and/or modify
- */
-package org.arakhne.util.ref;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Random;
-import java.util.Map.Entry;
-
-import org.arakhne.junit.AbstractTestCase;
-
-/**
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
-public class WeakValueMapTest extends AbstractTestCase {
-
-	private static final int REFERENCE_SIZE = 0; 
-
-	private final HashMap<String,String> reference = new HashMap<String,String>();
-
-	private static void collect() {
-		System.gc();System.gc();System.gc();
-	}
-
-	private void spawnReference() {
-		this.reference.clear();
-		Random rnd = new Random();
-		int count = rnd.nextInt(REFERENCE_SIZE+1)+5;
-		String str;
-		for(int i=0; i<count; i++) {
-			str = randomString(10);
-			this.reference.put(
-					Integer.toString(i)+str,
-					str);
-		}
-		str = null;
-	}
-
-	private String getReferenceObject(int index) {
-		Object[] tab = this.reference.keySet().toArray();
-		return (String)tab[index];
-	}
-
-	private Map<String,String> removeElementsFromReference() {
-		HashMap<String,String> removed = new HashMap<String,String>();
-		Random rnd = new Random();
-		int index;
-		int count = rnd.nextInt(this.reference.size()/4)+1;
-		String key, value;
-		for(int i=0; i<count; i++) {
-			index = rnd.nextInt(this.reference.size());
-			key = getReferenceObject(index);
-			value = this.reference.remove(key);
-			removed.put(key,value);
-		}
-		key = null;
-		value =  null;
-		return removed;
-	}
-
-	@Override
-	public void setUp() {
-		spawnReference();
-	}
-
-	@Override
-	public void tearDown() {
-		this.reference.clear();
-	}
-
-	/**
-	 */
-	public void testEntryIterator() {
-		WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-
-		// Test the content
-		{
-			assertDeepSimilars(this.reference, test);
-			Entry<String,String> e;
-			Iterator<Entry<String,String>> iter = test.entrySet().iterator();
-			while (iter.hasNext()) {
-				e = iter.next();
-				assertTrue(this.reference.containsKey(e.getKey()));
-				assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
-			}
-		}
-
-		{
-			// Remove elements
-			Map<String,String> baseElements = new HashMap<String,String>(this.reference);
-			removeElementsFromReference();
-
-			// Collects the objects
-			collect();
-
-			// Test the content
-			{
-				assertNotDeepSimilars(this.reference, test);
-				Entry<String,String> e;
-				Iterator<Entry<String,String>> iter = test.entrySet().iterator();
-				while (iter.hasNext()) {
-					e = iter.next();
-					assertTrue(baseElements.containsKey(e.getKey()));
-					assertEquals(baseElements.get(e.getKey()),baseElements.get(e.getKey()));
-				}
-			}
-
-			// Clear the list of removed elements, which will cause collecting
-			baseElements.clear();
-			baseElements = null;
-
-			// Collects the objects
-			collect();
-			collect();
-		}
-
-		// Test the content
-		/*{
-        	assertDeepSimilars(this.reference, test);
-    		Entry<String,String> e;
-        	Iterator<Entry<String,String>> iter = test.entrySet().iterator();
-        	while (iter.hasNext()) {
-        		e = iter.next();
-        		assertTrue(this.reference.containsKey(e.getKey()));
-        		assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
-        	}
-    	}*/
-	}
-
-	/**
-	 */
-	public void testWeakValueMapMap() {
-		WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
-		assertDeepSimilars(this.reference, test);
-	}
-
-	/**
-	 */
-	public void testSize() {
-		WeakValueMap<String,String> test = new WeakValueMap<String,String>();
-		assertEquals(0, test.size());
-
-		test = new WeakValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-		assertEquals(this.reference.size(), test.size());
-
-		removeElementsFromReference();
-
-		collect();
-
-		assertEquals(this.reference.size(), test.size());		
-	}
-
-	/**
-	 */
-	public void testIsEmpty() {
-		WeakValueMap<String,String> test = new WeakValueMap<String,String>();
-		assertTrue(test.isEmpty());
-
-		test = new WeakValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-		assertFalse(test.isEmpty());
-
-		removeElementsFromReference();
-
-		collect();
-
-		assertFalse(test.isEmpty());
-
-		this.reference.clear();
-
-		collect();
-
-		assertTrue(test.isEmpty());
-	}
-
-	/**
-	 */
-	public void testContainsKey() {
-		WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-		assertDeepSimilars(this.reference, test);
-
-		// Test the content
-		{
-			String elt;
-			Iterator<String> iter = this.reference.keySet().iterator(); 
-			while (iter.hasNext()) {
-				elt = iter.next();
-				assertTrue(test.containsKey(elt));
-			}
-			elt = null;
-		}
-		assertDeepSimilars(this.reference, test);
-
-		Map<String,String> removedElements = removeElementsFromReference();
-		int originalSize = removedElements.size() + this.reference.size();
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		assertEquals(originalSize, test.size());
-		assertNotDeepSimilars(this.reference, test);
-
-		// Clear the list of removed elements, which will cause collecting
-		removedElements.clear();
-		removedElements = null;
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		assertEquals(this.reference.size(), test.size());
-		assertDeepSimilars(this.reference, test);
-		for(String elt : this.reference.keySet()) {
-			assertTrue(test.containsKey(elt));
-		}
-	}
-
-	/**
-	 */
-	public void testContainsValue() {
-		WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-		assertDeepSimilars(this.reference, test);
-
-		// Test the content
-		{
-			String elt;
-			Iterator<String> iter = this.reference.values().iterator(); 
-			while (iter.hasNext()) {
-				elt = iter.next();
-				assertTrue(test.containsValue(elt));
-			}
-			elt = null;
-		}
-		assertDeepSimilars(this.reference, test);
-
-		Map<String,String> removedElements = removeElementsFromReference();
-		int originalSize = removedElements.size() + this.reference.size();
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		assertEquals(originalSize, test.size());
-		assertNotDeepSimilars(this.reference, test);
-
-		// Clear the list of removed elements, which will cause collecting
-		removedElements.clear();
-		removedElements = null;
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		assertEquals(this.reference.size(), test.size());
-		assertDeepSimilars(this.reference, test);
-		for(String elt : this.reference.values()) {
-			assertTrue(test.containsValue(elt));
-		}
-	}
-
-	/**
-	 */
-	public void testKeyIterator() {
-		WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-
-		// Test the content
-		{
-			assertDeepSimilars(this.reference, test);
-			String k;
-			Iterator<String> iter = test.keySet().iterator();
-			while (iter.hasNext()) {
-				k = iter.next();
-				assertTrue(this.reference.containsKey(k));
-			}
-		}
-
-		// Remove elements
-		Map<String,String> baseElements = new HashMap<String,String>(this.reference);
-		removeElementsFromReference();
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		{
-			assertNotDeepSimilars(this.reference, test);
-			String k;
-			Iterator<String> iter = test.keySet().iterator();
-			while (iter.hasNext()) {
-				k = iter.next();
-				assertTrue(baseElements.containsKey(k));
-			}
-		}
-
-		// Clear the list of removed elements, which will cause collecting
-		baseElements.clear();
-		baseElements = null;
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		{
-			assertDeepSimilars(this.reference, test);
-			String k;
-			Iterator<String> iter = test.keySet().iterator();
-			while (iter.hasNext()) {
-				k = iter.next();
-				assertTrue(this.reference.containsKey(k));
-			}
-		}
-	}
-
-	/**
-	 */
-	public void testValueIterator() {
-		WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
-		test.setDeeplyExpurge(true);
-
-		// Test the content
-		{
-			assertDeepSimilars(this.reference, test);
-			String v;
-			Iterator<String> iter = test.values().iterator();
-			while (iter.hasNext()) {
-				v = iter.next();
-				assertTrue(this.reference.containsValue(v));
-			}
-			v = null;
-			iter = null;
-		}
-
-		// Remove elements
-		Map<String,String> baseElements = new HashMap<String,String>(this.reference);
-		removeElementsFromReference();
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		{
-			assertNotDeepSimilars(this.reference, test);
-			String v;
-			Iterator<String> iter = test.values().iterator();
-			while (iter.hasNext()) {
-				v = iter.next();
-				assertTrue(baseElements.containsValue(v));
-			}
-			v = null;
-			iter = null;
-		}
-
-		// Clear the list of removed elements, which will cause collecting
-		baseElements.clear();
-		baseElements = null;
-
-		// Collects the objects
-		collect();
-
-		// Test the content
-		{
-			assertDeepSimilars(this.reference, test);
-			String v;
-			Iterator<String> iter = test.values().iterator();
-			while (iter.hasNext()) {
-				v = iter.next();
-				assertTrue(this.reference.containsValue(v));
-			}
-			v = null;
-			iter = null;
-		}
-	}
-
-}

Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueTreeMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueTreeMapTest.java	                        (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueTreeMapTest.java	2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ * 
+ * Copyright (C) 2011 Stephane GALLAND.
+ * 
+ * This library 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 library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class WeakValueTreeMapTest extends AbstractReferencableValueMapTestCase {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected Map<String,String> createMap() {
+		return new WeakValueTreeMap<String,String>();
+	}
+
+}


Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueTreeMapTest.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/