diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/PermanentIdentifier.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/PermanentIdentifier.java
new file mode 100644
index 0000000000000000000000000000000000000000..e4c98cbec75442a5ccf8468e7ce48a5dc3cfd47b
--- /dev/null
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/PermanentIdentifier.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010 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.openbis.plugin.screening.shared.api.v1.dto;
+
+import java.io.Serializable;
+
+/**
+ * A class representing a permanent identifier in openBIS.
+ *
+ * @author Bernd Rinn
+ */
+public class PermanentIdentifier implements Serializable, IPermanentIdentifier
+{
+    private static final long serialVersionUID = 1L;
+    
+    private final String permId;
+    
+    public PermanentIdentifier(String permId)
+    {
+        this.permId = permId;
+    }
+
+    public String getPermId()
+    {
+        return permId;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getPermId();
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((permId == null) ? 0 : permId.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+        {
+            return true;
+        }
+        if (obj == null)
+        {
+            return false;
+        }
+        if (getClass() != obj.getClass())
+        {
+            return false;
+        }
+        final PermanentIdentifier other = (PermanentIdentifier) obj;
+        if (permId == null)
+        {
+            if (other.permId != null)
+            {
+                return false;
+            }
+        } else if (permId.equals(other.permId) == false)
+        {
+            return false;
+        }
+        return true;
+    }
+
+}
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/Plate.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/Plate.java
index 3b4adf06a92f2f4639c03efdefbfedcae78bfd79..5f87d15b4dc157f0c63a8fe0ed19bad464ccafd5 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/Plate.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/Plate.java
@@ -1,34 +1,73 @@
 package ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto;
 
-import java.io.Serializable;
+import java.io.IOException;
+import java.io.ObjectInputStream;
 
 /**
- * Describes a plate and its context in a hierarchy
+ * Unique identifier for a plate which is assigned to an experiment. This class really should be
+ * called <code>ExperimentPlateIdentifier</code>.
  * 
  * @author Tomasz Pylak
  */
-public class Plate extends PlateIdentifier implements Serializable
+public class Plate extends PlateIdentifier
 {
     private static final long serialVersionUID = 1L;
 
+    // Keep for backward compatibility
     private String experimentCode, projectCode;
 
-    public Plate(String plateCode, String experimentCode, String projectCode, String spaceCodeOrNull)
+    private ExperimentIdentifier experimentIdentifier;
+
+    @Deprecated
+    public Plate(String plateCode, String experimentCode, String projectCode, String spaceCode)
+    {
+        this(plateCode, spaceCode, null, new ExperimentIdentifier(spaceCode, projectCode,
+                experimentCode, null));
+    }
+
+    public Plate(String plateCode, String spaceCode, String permId,
+            ExperimentIdentifier experimentIdentifier)
+    {
+        super(plateCode, spaceCode, permId);
+        this.experimentCode = experimentIdentifier.getExperimentCode();
+        this.projectCode = experimentIdentifier.getProjectCode();
+        this.experimentIdentifier = experimentIdentifier;
+    }
+
+    /**
+     * Get the identifier of the experiment that this plate is assigned to.
+     */
+    public ExperimentIdentifier getExperimentIdentifier()
     {
-        super(plateCode, spaceCodeOrNull);
-        this.experimentCode = experimentCode;
-        this.projectCode = projectCode;
+        return experimentIdentifier;
     }
 
-    /** a code of the experiment to which the plate belongs */
+    /**
+     * The code of the experiment to which the plate belongs.
+     */
     public String getExperimentCode()
     {
         return experimentCode;
     }
 
-    /** a code of the project to which the plate belongs */
+    /**
+     * The code of the project to which the plate belongs.
+     */
     public String getProjectCode()
     {
         return projectCode;
     }
+
+    // Special method for customizing Java deserialization.
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+    {
+        // Kick-off the default serialization procedure.
+        in.defaultReadObject();
+        // V1.0 didn't have the experimentIdentifier, so it may be null here.
+        if (experimentIdentifier == null)
+        {
+            experimentIdentifier =
+                    new ExperimentIdentifier(experimentCode, projectCode, tryGetSpaceCode(), null);
+        }
+    }
 }
\ No newline at end of file
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/PlateIdentifier.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/PlateIdentifier.java
index 7de3645cf37ba3438db6d319661fe40787264240..2cca1f51640dd1c44cfebf00c6dea06fbe8722ba 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/PlateIdentifier.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/PlateIdentifier.java
@@ -1,13 +1,11 @@
 package ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto;
 
-import java.io.Serializable;
-
 /**
- * Contains data which uniquely define a plate
+ * Contains data which uniquely define a plate.
  * 
  * @author Tomasz Pylak
  */
-public class PlateIdentifier implements Serializable
+public class PlateIdentifier extends PermanentIdentifier
 {
     private static final long serialVersionUID = 1L;
 
@@ -15,47 +13,44 @@ public class PlateIdentifier implements Serializable
 
     public PlateIdentifier(String plateCode, String spaceCodeOrNull)
     {
+        this(plateCode, spaceCodeOrNull, null);
+    }
+
+    public PlateIdentifier(String plateCode, String spaceCodeOrNull, String permId)
+    {
+        super(permId);
         this.plateCode = plateCode;
         this.spaceCodeOrNull = spaceCodeOrNull;
     }
 
-    /** a code of the plate */
+    /**
+     * A code of the plate.
+     */
     public String getPlateCode()
     {
         return plateCode;
     }
 
-    /** a code of the space to which the plate belongs or null if it is a shared plate */
+    /**
+     * A code of the space to which the plate belongs or <code>null</code> if it is a shared plate.
+     */
     public String tryGetSpaceCode()
     {
         return spaceCodeOrNull;
     }
 
-    @Override
-    public String toString()
+    /**
+     * Returns the augmented (full) code of this plate.
+     */
+    public String getAugmentedCode()
     {
-        return (spaceCodeOrNull != null ? "/" + spaceCodeOrNull : "") + "/" + plateCode;
-    }
-
-    @Override
-    public int hashCode()
-    {
-        final int prime = 31;
-        int result = prime + plateCode.hashCode();
-        return prime * result + ((spaceCodeOrNull == null) ? 0 : spaceCodeOrNull.hashCode());
-    }
-
-    @Override
-    public boolean equals(Object obj)
-    {
-        if (obj == null || obj instanceof PlateIdentifier == false)
+        if (spaceCodeOrNull != null)
+        {
+            return "/" + spaceCodeOrNull + "/" + plateCode;
+        } else
         {
-            return false;
+            return "/" + plateCode;
         }
-        PlateIdentifier that = (PlateIdentifier) obj;
-        return plateCode.equals(that.getPlateCode())
-                && ((spaceCodeOrNull != null && spaceCodeOrNull.equals(that.tryGetSpaceCode())) || (spaceCodeOrNull == null && that
-                        .tryGetSpaceCode() == null));
     }
 
 }
\ No newline at end of file