Index: module/org.restlet/src/org/restlet/data/Conditions.java
===================================================================
--- module/org.restlet/src/org/restlet/data/Conditions.java	(revision 1119)
+++ module/org.restlet/src/org/restlet/data/Conditions.java	(working copy)
@@ -25,6 +25,8 @@
 import java.util.Date;
 import java.util.List;
 
+import org.restlet.util.ImmutableDate;
+
 /**
  * Set of conditions applying to a request. This is equivalent to the HTTP conditional headers.  
  * @author Jerome Louvel (contact@noelios.com) <a href="http://www.noelios.com/">Noelios Consulting</a>
@@ -32,10 +34,10 @@
 public class Conditions
 {
 	/** The "if-modified-since" condition */
-	private Date modifiedSince;
+	private ImmutableDate modifiedSince;
 
 	/** The "if-unmodified-since" condition */
-	private Date unmodifiedSince;
+	private ImmutableDate unmodifiedSince;
 
 	/** The "if-match" condition */
 	private List<Tag> match;
@@ -65,7 +67,7 @@
 	 */
 	public void setModifiedSince(Date date)
 	{
-		this.modifiedSince = date;
+		this.modifiedSince = ImmutableDate.valueOf(date);
 	}
 
 	/**
@@ -83,7 +85,7 @@
 	 */
 	public void setUnmodifiedSince(Date date)
 	{
-		this.unmodifiedSince = date;
+		this.unmodifiedSince = ImmutableDate.valueOf(date);
 	}
 
 	/**
Index: module/org.restlet/src/org/restlet/data/Cookie.java
===================================================================
--- module/org.restlet/src/org/restlet/data/Cookie.java	(revision 1119)
+++ module/org.restlet/src/org/restlet/data/Cookie.java	(working copy)
@@ -28,170 +28,163 @@
  */
 public class Cookie extends Parameter
 {
-   /** The version number. */
+	/** The version number. */
 	private int version;
 
-   /** The validity path. */
+	/** The validity path. */
 	private String path;
 
-   /** The domain name. */
+	/** The domain name. */
 	private String domain;
 
-   /**
-    * Constructor.
-    */
-   public Cookie()
-   {
-      this(0, null, null, null, null);
-   }
+	/**
+	 * Constructor.
+	 */
+	public Cookie()
+	{
+		this(0, null, null, null, null);
+	}
 
-   /**
-    * Constructor.
-    * @param name The name.
-    * @param value The value.
-    */
-   public Cookie(String name, String value)
-   {
-      this(0, name, value, null, null);
-   }
+	/**
+	 * Constructor.
+	 * @param name The name.
+	 * @param value The value.
+	 */
+	public Cookie(String name, String value)
+	{
+		this(0, name, value, null, null);
+	}
 
-   /**
-    * Constructor.
-    * @param version The version number.
-    * @param name The name.
-    * @param value The value.
-    */
-   public Cookie(int version, String name, String value)
-   {
-      this(version, name, value, null, null);
-   }
+	/**
+	 * Constructor.
+	 * @param version The version number.
+	 * @param name The name.
+	 * @param value The value.
+	 */
+	public Cookie(int version, String name, String value)
+	{
+		this(version, name, value, null, null);
+	}
 
-   /**
-    * Constructor.
-    * @param version The version number.
-    * @param name The name.
-    * @param value The value.
-    * @param path The validity path.
-    * @param domain The domain name.
-    */
-   public Cookie(int version, String name, String value, String path, String domain)
-   {
-      super(name, value);
-      this.version = version;
-      this.path = path;
-      this.domain = domain;
-   }
+	/**
+	 * Constructor.
+	 * @param version The version number.
+	 * @param name The name.
+	 * @param value The value.
+	 * @param path The validity path.
+	 * @param domain The domain name.
+	 */
+	public Cookie(int version, String name, String value, String path, String domain)
+	{
+		super(name, value);
+		this.version = version;
+		this.path = path;
+		this.domain = domain;
+	}
 
-   /**
-    * Returns the cookie specification version.
-    * @return The cookie specification version.
-    */
-   public int getVersion()
-   {
-      return this.version;
-   }
+	/**
+	 * Returns the cookie specification version.
+	 * @return The cookie specification version.
+	 */
+	public int getVersion()
+	{
+		return this.version;
+	}
 
-   /**
-    * Sets the cookie specification version.
-    * @param version The cookie specification version.
-    */
-   public void setVersion(int version)
-   {
-      this.version = version;
-   }
+	/**
+	 * Sets the cookie specification version.
+	 * @param version The cookie specification version.
+	 */
+	public void setVersion(int version)
+	{
+		this.version = version;
+	}
 
-   /**
-    * Returns the validity path.
-    * @return The validity path.
-    */
-   public String getPath()
-   {
-      return this.path;
-   }
+	/**
+	 * Returns the validity path.
+	 * @return The validity path.
+	 */
+	public String getPath()
+	{
+		return this.path;
+	}
 
-   /**
-    * Sets the validity path.
-    * @param path The validity path.
-    */
-   public void setPath(String path)
-   {
-      this.path = path;
-   }
+	/**
+	 * Sets the validity path.
+	 * @param path The validity path.
+	 */
+	public void setPath(String path)
+	{
+		this.path = path;
+	}
 
-   /**
-    * Returns the domain name.
-    * @return The domain name.
-    */
-   public String getDomain()
-   {
-      return this.domain;
-   }
+	/**
+	 * Returns the domain name.
+	 * @return The domain name.
+	 */
+	public String getDomain()
+	{
+		return this.domain;
+	}
 
-   /**
-    * Sets the domain name.
-    * @param domain The domain name.
-    */
-   public void setDomain(String domain)
-   {
-      this.domain = domain;
-   }
+	/**
+	 * Sets the domain name.
+	 * @param domain The domain name.
+	 */
+	public void setDomain(String domain)
+	{
+		this.domain = domain;
+	}
 
-   /**
-    * Compares two parameters.
-    * @param object The object to compare to.
-    * @return True if the parameters are identical (name and value).
-    */
-   public boolean equals(Object object)
-   {
-      boolean result = super.equals(object);
-      
-      if(result)
-      {
-      	result = object instanceof Cookie;
-      	
-      	if(result)
-      	{
-      		Cookie otherCookie = (Cookie)object;
-      		
-      		if(otherCookie != null)
-      		{
-			      result &= (getVersion() == otherCookie.getVersion());
-			
-			      if(getPath() == null)
-			      {
-			         result &= (otherCookie.getPath() == null);
-			      }
-			      else
-			      {
-			         result &= getPath().equals(otherCookie.getPath());
-			      }
-			
-			      if(getDomain() == null)
-			      {
-			         result &= (otherCookie.getDomain() == null);
-			      }
-			      else
-			      {
-			         result &= getDomain().equals(otherCookie.getDomain());
-			      }
-      		}
-      		else
-      		{
-      			result = false;
-      		}
-      	}
-      }
-      
-      return result;
-   }
-	
-	/** {@inheritDoc} */
 	@Override
+	public boolean equals(Object obj)
+	{
+		boolean result = (obj == this);
+		//if obj == this no need to go further
+		if (!result)
+		{
+			// test for equality at Parameter level i.e. name and value.
+			if (super.equals(obj))
+			{
+				// if obj isn't a cookie or is null don't evaluate further
+				if ((obj instanceof Cookie) && obj != null)
+				{
+					Cookie that = (Cookie) obj;
+					result = (this.version == that.version);
+					if (result) // if versions are equal test domains
+					{
+						if (!(this.domain == null)) // compare domains taking care of nulls
+						{
+							result = (this.domain.equals(that.domain));
+						} else {
+							result = (that.domain == null);
+						}
+						if (result) //if domains are equal test the paths
+						{
+							if (!(this.path == null)) // compare paths taking care of nulls
+							{
+								result = (this.path.equals(that.path));
+							} else {
+								result = (that.path == null);
+							}
+						}
+					}
+				} 
+			}
+
+		}
+		return result;
+	}
+
+	@Override
 	public int hashCode()
 	{
-		// to workaround findbugs warning
-		// to properly implement
-		return super.hashCode();
+		final int PRIME = 31;
+		int result = super.hashCode(); //takes into account the name and value fields in superclass
+		result = PRIME * result + ((domain == null) ? 0 : domain.hashCode());
+		result = PRIME * result + ((path == null) ? 0 : path.hashCode());
+		result = PRIME * result + version;
+		return result;
 	}
 
 }
Index: module/org.restlet/src/org/restlet/data/Parameter.java
===================================================================
--- module/org.restlet/src/org/restlet/data/Parameter.java	(revision 1119)
+++ module/org.restlet/src/org/restlet/data/Parameter.java	(working copy)
@@ -30,78 +30,80 @@
  */
 public class Parameter implements Comparable<Parameter>
 {
-   /** The name. */
+	/** The name. */
 	private String name;
-	
-   /** The value. */
+
+	/** The value. */
 	private String value;
 
-   /**
-    * Default constructor.
-    */
-   public Parameter() 
-   {
-      this(null, null);
-   }
+	/**
+	 * Default constructor.
+	 */
+	public Parameter()
+	{
+		this(null, null);
+	}
 
-   /**
-    * Preferred constructor.
-    * @param name The name.
-    * @param value The value.
-    */
-   public Parameter(String name, String value)
-   {
-      this.name = name;
-      this.value = value;
-   }
+	/**
+	 * Preferred constructor.
+	 * @param name The name.
+	 * @param value The value.
+	 */
+	public Parameter(String name, String value)
+	{
+		this.name = name;
+		this.value = value;
+	}
 
-   /**
-    * Returns the value.
-    * @return The value.
-    */
-   public String getValue()
-   {
-      return this.value;
-   }
+	/**
+	 * Returns the value.
+	 * @return The value.
+	 */
+	public String getValue()
+	{
+		return this.value;
+	}
 
-   /**
-    * Sets the value.
-    * @param value The value.
-    */
-   public void setValue(String value)
-   {
-      this.value = value;
-   }
+	/**
+	 * Sets the value.
+	 * @param value The value.
+	 */
+	public void setValue(String value)
+	{
+		this.value = value;
+	}
 
-   /**
-    * Compares two parameters.
-    * @param object The object to compare.
-    * @return True if the parameters are identical (name and value).
-    */
-   public boolean equals(Object object)
+	/**
+	 * Compares two parameters.
+	 * @param object The object to compare.
+	 * @return True if the parameters are identical (name and value).
+	 */
+	public boolean equals(Object obj)
 	{
-		boolean result = false;
-		if (object instanceof Parameter && object != null) //avoid findbugs correctness warning
+		boolean result = (obj == this);
+		//if obj == this no need to go further
+		if (!result)
 		{
-			final Parameter that = (Parameter) object;
-			final String thisName = this.getName();
-			final String thatName = that.getName();
-			if(!(thisName == thatName)) { // compare names taking care of nulls
-				result = (thisName != null && thisName.equals(thatName));				
-			}
-			//compare values if names are equal
-			if (result)
+			if ((obj instanceof Parameter) && obj != null)
 			{
-				final String thisValue = this.getValue();
-				final String thatValue = that.getValue();
-				if (!(thisValue == thatValue)) // consider equality with nulls
-				{ 
-					result = (thisValue != null && thisValue.equals(thatValue));
+				Parameter that = (Parameter) obj;
+				if (!(this.name == null)) // compare names taking care of nulls
+				{
+					result = this.name.equals(that.name);
+				} else {
+					result = (that.name == null); 
 				}
+				if (result) //if names are equal test the values
+				{
+					if (!(this.value == null)) // compare values taking care of nulls
+					{
+						result = (this.value.equals(that.value));
+					} else  {
+						result = (that.value == null);
+					}
+				}
 			}
-
 		}
-
 		return result;
 	}
 
@@ -124,64 +126,63 @@
 		return nameHashCode + valueHashCode;
 	}
 
-   /**
-    * Returns the name of this parameter.
-    * @return The name of this parameter.
-    */
-   public String getName()
-   {
-   	return this.name;
-   }
-   
-   /**
-    * Returns a string with the name and value of the parameter.
-    * @return A string with the name and value of the parameter.
-    */
-   public String toString()
-   {
-   	return getName() + ": " + getValue();
-   }
+	/**
+	 * Returns the name of this parameter.
+	 * @return The name of this parameter.
+	 */
+	public String getName()
+	{
+		return this.name;
+	}
 
-   /**
-    * Compares this object with the specified object for order.
-    * @param o The object to be compared.
-    * @return A negative integer, zero, or a positive integer as this object is less than, equal to, or
-    * greater than the specified object.
-    */
-   public int compareTo(Parameter o)
-   {
-      return getName().compareTo(o.getName());
-   }
+	/**
+	 * Returns a string with the name and value of the parameter.
+	 * @return A string with the name and value of the parameter.
+	 */
+	public String toString()
+	{
+		return getName() + ": " + getValue();
+	}
 
-   /**
-    * Encodes the parameter.
-    * @return The encoded string.
-    * @throws IOException
-    */
-   public String urlEncode() throws IOException
-   {
-      StringBuilder sb = new StringBuilder();
-      urlEncode(sb);
-      return sb.toString();
-   }
+	/**
+	 * Compares this object with the specified object for order.
+	 * @param o The object to be compared.
+	 * @return A negative integer, zero, or a positive integer as this object is less than, equal to, or
+	 * greater than the specified object.
+	 */
+	public int compareTo(Parameter o)
+	{
+		return getName().compareTo(o.getName());
+	}
 
-   /**
-    * Encodes the parameter and append the result to the given buffer.
-    * @param buffer The buffer to append.
-    * @throws IOException
-    */
-   public void urlEncode(Appendable buffer) throws IOException
-   {
-   	if(getName() != null)
-   	{
-      	buffer.append(Reference.encode(getName()));
-            
-         if(getValue() != null)
-         {
-         	buffer.append('=');
-            buffer.append(Reference.encode(getValue()));
-         }
-      }
-   }
-   
+	/**
+	 * Encodes the parameter.
+	 * @return The encoded string.
+	 * @throws IOException
+	 */
+	public String urlEncode() throws IOException
+	{
+		StringBuilder sb = new StringBuilder();
+		urlEncode(sb);
+		return sb.toString();
+	}
+
+	/**
+	 * Encodes the parameter and append the result to the given buffer.
+	 * @param buffer The buffer to append.
+	 * @throws IOException
+	 */
+	public void urlEncode(Appendable buffer) throws IOException
+	{
+		if (getName() != null)
+		{
+			buffer.append(Reference.encode(getName()));
+
+			if (getValue() != null)
+			{
+				buffer.append('=');
+				buffer.append(Reference.encode(getValue()));
+			}
+		}
+	}
 }
Index: module/org.restlet/src/org/restlet/resource/Representation.java
===================================================================
--- module/org.restlet/src/org/restlet/resource/Representation.java	(revision 1119)
+++ module/org.restlet/src/org/restlet/resource/Representation.java	(working copy)
@@ -37,6 +37,7 @@
 import org.restlet.data.Language;
 import org.restlet.data.MediaType;
 import org.restlet.data.Tag;
+import org.restlet.util.ImmutableDate;
 
 /**
  * Current or intended state of a resource. For performance purpose, it is essential that a minimal overhead 
@@ -75,7 +76,7 @@
 	private long size;
 
 	/** The expiration date. */
-	private Date expirationDate;
+	private ImmutableDate expirationDate;
 
 	/** The language or null if not applicable. */
 	private Language language;
@@ -84,7 +85,7 @@
 	private MediaType mediaType;
 
 	/** The modification date. */
-	private Date modificationDate;
+	private ImmutableDate modificationDate;
 
 	/** The represented resource, if available. */
 	private Resource resource;
@@ -199,7 +200,7 @@
 	 */
 	public void setExpirationDate(Date expirationDate)
 	{
-		this.expirationDate = expirationDate;
+		this.expirationDate = ImmutableDate.valueOf(expirationDate);
 	}
 
 	/**
@@ -254,7 +255,7 @@
 	 */
 	public void setModificationDate(Date modificationDate)
 	{
-		this.modificationDate = modificationDate;
+		this.modificationDate = ImmutableDate.valueOf(modificationDate);
 	}
 
 	/**
Index: module/org.restlet/src/org/restlet/util/ImmutableDate.java
===================================================================
--- module/org.restlet/src/org/restlet/util/ImmutableDate.java	(revision 0)
+++ module/org.restlet/src/org/restlet/util/ImmutableDate.java	(revision 0)
@@ -0,0 +1,239 @@
+package org.restlet.util;
+
+import java.util.Date;
+import java.util.WeakHashMap;
+
+/**
+ * Class acting as an immutable date class based on the {@link java.util.Date} class.
+ * 
+ * Throws {@link UnsupportedOperationException} when muttable methopds are invoked.
+ * @author Piyush Purang
+ * @see java.util.Date
+ * @see <a href="http://discuss.fogcreek.com/joelonsoftware3/default.asp?cmd=show&ixPost=73959&ixReplies=24">Immutable Date</a>
+ */
+public final class ImmutableDate extends Date
+{
+	// todo are we serializable?
+	private static final long serialVersionUID = -5946186780670229206L;
+
+	/** delegatee being wrapped */
+	private final Date delegatee;
+
+	private static final transient WeakHashMap<Date, ImmutableDate> CACHE = new WeakHashMap<Date, ImmutableDate>();
+
+	/**
+	 * Private constructor. A factory method is provided.
+	 * @param date date to be made immutable
+	 */
+	private ImmutableDate(Date date)
+	{
+		this.delegatee = (Date) date.clone();
+	}
+
+	/**
+	 * Returns an ImmutableDate object wrapping the given date.
+	 * @param date object to be made immutable
+	 * @return an immutable date object
+	 */
+	public static ImmutableDate valueOf(Date date)
+	{
+		if (!CACHE.containsKey(date))
+		{
+			CACHE.put(date, new ImmutableDate(date));
+		}
+		return CACHE.get(date);
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	public boolean after(Date when)
+	{
+		return delegatee.after(when);
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	public boolean before(Date when)
+	{
+		return delegatee.before(when);
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	public Object clone()
+	{
+		throw new UnsupportedOperationException("ImmutableDate is immutable");
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	public int compareTo(Date anotherDate)
+	{
+		return delegatee.compareTo(anotherDate);
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	public boolean equals(Object obj)
+	{
+		return delegatee.equals(obj);
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public int getDate()
+	{
+		return delegatee.getDate();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public int getDay()
+	{
+		return delegatee.getDay();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public int getHours()
+	{
+		return delegatee.getHours();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public int getMinutes()
+	{
+		return delegatee.getMinutes();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public int getMonth()
+	{
+		return delegatee.getMonth();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public int getSeconds()
+	{
+
+		return delegatee.getSeconds();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	public long getTime()
+	{
+		return delegatee.getTime();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public int getTimezoneOffset()
+	{
+		return delegatee.getTimezoneOffset();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public int getYear()
+	{
+		return delegatee.getYear();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	public int hashCode()
+	{
+		return delegatee.hashCode();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public void setDate(int date)
+	{
+		throw new UnsupportedOperationException("ImmutableDate is immutable");
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public void setHours(int hours)
+	{
+		throw new UnsupportedOperationException("ImmutableDate is immutable");
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public void setMinutes(int minutes)
+	{
+		throw new UnsupportedOperationException("ImmutableDate is immutable");
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public void setMonth(int month)
+	{
+		throw new UnsupportedOperationException("ImmutableDate is immutable");
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public void setSeconds(int seconds)
+	{
+		throw new UnsupportedOperationException("ImmutableDate is immutable");
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public void setTime(long time)
+	{
+		throw new UnsupportedOperationException("ImmutableDate is immutable");
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public void setYear(int year)
+	{
+		throw new UnsupportedOperationException("ImmutableDate is immutable");
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public String toGMTString()
+	{
+		return delegatee.toGMTString();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	@Deprecated
+	public String toLocaleString()
+	{
+		return delegatee.toLocaleString();
+	}
+
+	/**{@inheritDoc}*/
+	@Override
+	public String toString()
+	{
+		return delegatee.toString();
+	}
+}
