diff --git a/common/source/java/ch/systemsx/cisd/common/collections/IKeyExtractor.java b/common/source/java/ch/systemsx/cisd/common/collections/IKeyExtractor.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce880e12d94bc93756e933c0f3322a02d76156fb
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/collections/IKeyExtractor.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.common.collections;
+
+/**
+ * Interface defining the role of a key extractor.
+ *
+ * @author Franz-Josef Elmer
+ */
+public interface IKeyExtractor<K, E>
+{
+    /**
+     * Returns the key of type <code>K</code> from an entity <code>E</code>.
+     */
+    public K getKey(E e);
+}
diff --git a/common/source/java/ch/systemsx/cisd/common/collections/TableMap.java b/common/source/java/ch/systemsx/cisd/common/collections/TableMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..1943c3edf10e46634c0a1533da1965e5e1905873
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/collections/TableMap.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.common.collections;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class TableMap<K, E> implements Iterable<E>
+{
+    private final Map<K, E> map = new LinkedHashMap<K, E>();
+    private final IKeyExtractor<K, E> extractor;
+    
+    public TableMap(Collection<E> rows, IKeyExtractor<K, E> extractor)
+    {
+        this.extractor = extractor;
+        for (E row : rows)
+        {
+            add(row);
+        }
+    }
+    
+    public void add(E row)
+    {
+        map.put(extractor.getKey(row), row);
+    }
+    
+    public E get(K key)
+    {
+        return map.get(key);
+    }
+
+    public Iterator<E> iterator()
+    {
+        return new Iterator<E>()
+            {
+                private Iterator<Map.Entry<K, E>> iterator = map.entrySet().iterator();
+                
+                public boolean hasNext()
+                {
+                    return iterator.hasNext();
+                }
+
+                public E next()
+                {
+                    return iterator.next().getValue();
+                }
+
+                public void remove()
+                {
+                    throw new UnsupportedOperationException("Can not remove an element.");
+                }
+        
+            };
+    }
+}