Bug 335792 - The generics type parameters need to be specified in data - bean and jface plug-ins
diff --git a/bundles/org.eclipse.core.databinding.beans/.classpath b/bundles/org.eclipse.core.databinding.beans/.classpath
index ce73933..304e861 100644
--- a/bundles/org.eclipse.core.databinding.beans/.classpath
+++ b/bundles/org.eclipse.core.databinding.beans/.classpath
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/bundles/org.eclipse.core.databinding.beans/.settings/.api_filters b/bundles/org.eclipse.core.databinding.beans/.settings/.api_filters
new file mode 100644
index 0000000..251f16f
--- /dev/null
+++ b/bundles/org.eclipse.core.databinding.beans/.settings/.api_filters
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.core.databinding.beans" version="2">
+    <resource path="src/org/eclipse/core/databinding/beans/IBeanListProperty.java" type="org.eclipse.core.databinding.beans.IBeanListProperty">
+        <filter comment="org.eclipse.org.databinding.beans can implement noextend interfaces because it is maintained concurrently" id="574619656">
+            <message_arguments>
+                <message_argument value="IListProperty&lt;S, E&gt;"/>
+                <message_argument value="IBeanListProperty&lt;S, E&gt;"/>
+            </message_arguments>
+        </filter>
+        <filter comment="comment" id="574660632">
+            <message_arguments>
+                <message_argument value="IBeanProperty"/>
+                <message_argument value="IProperty"/>
+                <message_argument value="IBeanListProperty&lt;S, E&gt;"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/core/databinding/beans/IBeanMapProperty.java" type="org.eclipse.core.databinding.beans.IBeanMapProperty">
+        <filter comment="org.eclipse.org.databinding.beans can implement noextend interfaces because it is maintained concurrently" id="574619656">
+            <message_arguments>
+                <message_argument value="IMapProperty&lt;S, K, V&gt;"/>
+                <message_argument value="IBeanMapProperty&lt;S, K, V&gt;"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/core/databinding/beans/IBeanSetProperty.java" type="org.eclipse.core.databinding.beans.IBeanSetProperty">
+        <filter comment="org.eclipse.org.databinding.beans can implement noextend interfaces because it is maintained concurrently" id="574619656">
+            <message_arguments>
+                <message_argument value="ISetProperty&lt;S, E&gt;"/>
+                <message_argument value="IBeanSetProperty&lt;S, E&gt;"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/core/databinding/beans/IBeanValueProperty.java" type="org.eclipse.core.databinding.beans.IBeanValueProperty">
+        <filter comment="org.eclipse.org.databinding.beans can implement noextend interfaces because it is maintained concurrently" id="574619656">
+            <message_arguments>
+                <message_argument value="IValueProperty&lt;S, T&gt;"/>
+                <message_argument value="IBeanValueProperty&lt;S, T&gt;"/>
+            </message_arguments>
+        </filter>
+    </resource>
+</component>
diff --git a/bundles/org.eclipse.core.databinding.beans/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.core.databinding.beans/.settings/org.eclipse.jdt.core.prefs
index 27f8f29..8f0e0fa 100644
--- a/bundles/org.eclipse.core.databinding.beans/.settings/org.eclipse.jdt.core.prefs
+++ b/bundles/org.eclipse.core.databinding.beans/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,3 @@
-#Thu Feb 05 11:35:54 MST 2009
 eclipse.preferences.version=1
 org.eclipse.jdt.core.builder.cleanOutputFolder=clean
 org.eclipse.jdt.core.builder.duplicateResourceTask=warning
@@ -16,9 +15,9 @@
 org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
 org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.compliance=1.5
 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
 org.eclipse.jdt.core.compiler.debug.localVariable=generate
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -95,7 +94,7 @@
 org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
 org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
 org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.3
+org.eclipse.jdt.core.compiler.source=1.5
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
@@ -167,7 +166,12 @@
 org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
 org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
 org.eclipse.jdt.core.formatter.indentation.size=4
-org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
 org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
 org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
diff --git a/bundles/org.eclipse.core.databinding.beans/META-INF/MANIFEST.MF b/bundles/org.eclipse.core.databinding.beans/META-INF/MANIFEST.MF
index 73df536..4d00f69 100644
--- a/bundles/org.eclipse.core.databinding.beans/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.core.databinding.beans/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.core.databinding.beans
-Bundle-Version: 1.2.200.qualifier
+Bundle-Version: 1.5.0.qualifier
 Bundle-ClassPath: .
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
@@ -11,4 +11,4 @@
 Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.core.databinding.observable;bundle-version="[1.2.0,2.0.0)",
  org.eclipse.core.databinding.property;bundle-version="[1.3.0,2.0.0)"
-Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/bundles/org.eclipse.core.databinding.beans/pom.xml b/bundles/org.eclipse.core.databinding.beans/pom.xml
index 4d4ecbb..ff164b9 100644
--- a/bundles/org.eclipse.core.databinding.beans/pom.xml
+++ b/bundles/org.eclipse.core.databinding.beans/pom.xml
@@ -18,6 +18,6 @@
   </parent>
   <groupId>org.eclipse.core</groupId>
   <artifactId>org.eclipse.core.databinding.beans</artifactId>
-  <version>1.2.200-SNAPSHOT</version>
+  <version>1.5.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/BeanProperties.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/BeanProperties.java
index bbd9f8b..7fd756c 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/BeanProperties.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/BeanProperties.java
@@ -20,10 +20,12 @@
 import org.eclipse.core.databinding.property.map.IMapProperty;
 import org.eclipse.core.databinding.property.set.ISetProperty;
 import org.eclipse.core.databinding.property.value.IValueProperty;
+import org.eclipse.core.databinding.util.Policy;
 import org.eclipse.core.internal.databinding.beans.AnonymousBeanListProperty;
 import org.eclipse.core.internal.databinding.beans.AnonymousBeanMapProperty;
 import org.eclipse.core.internal.databinding.beans.AnonymousBeanSetProperty;
 import org.eclipse.core.internal.databinding.beans.AnonymousBeanValueProperty;
+import org.eclipse.core.internal.databinding.beans.AnonymousPojoValueProperty;
 import org.eclipse.core.internal.databinding.beans.BeanListProperty;
 import org.eclipse.core.internal.databinding.beans.BeanListPropertyDecorator;
 import org.eclipse.core.internal.databinding.beans.BeanMapProperty;
@@ -33,6 +35,9 @@
 import org.eclipse.core.internal.databinding.beans.BeanSetPropertyDecorator;
 import org.eclipse.core.internal.databinding.beans.BeanValueProperty;
 import org.eclipse.core.internal.databinding.beans.BeanValuePropertyDecorator;
+import org.eclipse.core.internal.databinding.beans.Util;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
 
 /**
  * A factory for creating properties for Java objects that conform to the <a
@@ -43,6 +48,11 @@
  */
 public class BeanProperties {
 	/**
+	 * @since 1.5
+	 */
+	public static final boolean DEBUG = true;
+
+	/**
 	 * Returns a value property for the given property name of an arbitrary bean
 	 * class. Objects lacking the named property are treated the same as if the
 	 * property always contains null.
@@ -52,8 +62,8 @@
 	 * @return a value property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanValueProperty value(String propertyName) {
-		return value(null, propertyName, null);
+	public static IBeanValueProperty<Object, Object> value(String propertyName) {
+		return value(propertyName, null);
 	}
 
 	/**
@@ -68,8 +78,25 @@
 	 * @return a value property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanValueProperty value(String propertyName, Class valueType) {
-		return value(null, propertyName, valueType);
+	public static <T> IBeanValueProperty<Object, T> value(String propertyName,
+			Class<T> valueType) {
+		String[] propertyNames = splitOffFirst(propertyName);
+
+		if (propertyNames.length == 1) {
+			return new BeanValuePropertyDecorator<Object, T>(
+					new AnonymousBeanValueProperty<Object, T>(propertyNames[0],
+							valueType), null);
+		}
+
+		IValueProperty<Object, Object> x = new AnonymousPojoValueProperty<Object, Object>(
+				propertyNames[0], Object.class);
+
+		IBeanValueProperty<Object, T> remainder = value(propertyNames[1],
+				valueType);
+
+		IValueProperty<Object, T> y = x.value(remainder);
+
+		return new BeanValuePropertyDecorator<Object, T>(y, null);
 	}
 
 	/**
@@ -83,61 +110,208 @@
 	 * @return a value property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanValueProperty value(Class beanClass, String propertyName) {
-		return value(beanClass, propertyName, null);
-	}
+	public static <S> IBeanValueProperty<S, ?> value(Class<S> beanClass,
+			String propertyName) {
+		String[] propertyNames = splitOffFirst(propertyName);
 
-	/**
-	 * Returns a value property for the given property name of the given bean
-	 * class.
-	 * 
-	 * @param beanClass
-	 *            the bean class
-	 * @param propertyName
-	 *            the property name. May be nested e.g. "parent.name"
-	 * @param valueType
-	 *            the value type of the returned value property
-	 * @return a value property for the given property name of the given bean
-	 *         class.
-	 */
-	public static IBeanValueProperty value(Class beanClass,
-			String propertyName, Class valueType) {
-		String[] propertyNames = split(propertyName);
-		if (propertyNames.length > 1)
-			valueType = null;
-
-		PropertyDescriptor propertyDescriptor;
-		IValueProperty property;
 		if (beanClass == null) {
-			propertyDescriptor = null;
-			property = new AnonymousBeanValueProperty(propertyNames[0],
-					valueType);
-		} else {
-			propertyDescriptor = BeanPropertyHelper.getPropertyDescriptor(
-					beanClass, propertyNames[0]);
-			property = new BeanValueProperty(propertyDescriptor, valueType);
+			// beanClass cannot be null.
+			throw new IllegalArgumentException();
 		}
 
-		IBeanValueProperty beanProperty = new BeanValuePropertyDecorator(
-				property, propertyDescriptor);
-		for (int i = 1; i < propertyNames.length; i++) {
-			beanProperty = beanProperty.value(propertyNames[i]);
+		PropertyDescriptor propertyDescriptor = BeanPropertyHelper
+				.getPropertyDescriptor(beanClass, propertyNames[0]);
+
+		if (propertyNames.length == 1) {
+			/*
+			 * If a non-null valueType is provided by the caller then it must
+			 * match the actual property type. If no valueType is provided by
+			 * the caller then set it to the actual type from the property
+			 * descriptor.
+			 */
+			Class<?> valueType = propertyDescriptor.getPropertyType();
+			valueType = Util.convertToObjectClass(valueType);
+
+			return valueUsingActualType(propertyDescriptor, valueType);
 		}
-		return beanProperty;
+
+		return valueGivenDescriptor(beanClass, propertyDescriptor,
+				propertyDescriptor.getPropertyType(), propertyNames[1]);
 	}
 
-	private static String[] split(String propertyName) {
-		if (propertyName.indexOf('.') == -1)
-			return new String[] { propertyName };
-		List propertyNames = new ArrayList();
-		int index;
-		while ((index = propertyName.indexOf('.')) != -1) {
-			propertyNames.add(propertyName.substring(0, index));
-			propertyName = propertyName.substring(index + 1);
+	private static <S, T> IBeanValueProperty<S, T> valueUsingActualType(
+			PropertyDescriptor propertyDescriptor, Class<T> valueType) {
+		IValueProperty<S, T> property = new BeanValueProperty<S, T>(
+				propertyDescriptor, valueType);
+		return new BeanValuePropertyDecorator<S, T>(property,
+				propertyDescriptor);
+	}
+
+	/**
+	 * Returns a value property for the given property name of the given bean
+	 * class.
+	 * 
+	 * @param beanClass
+	 *            the bean class
+	 * @param propertyName
+	 *            the property name. May be nested e.g. "parent.name"
+	 * @param valueType
+	 *            the value type of the returned value property
+	 * @return a value property for the given property name of the given bean
+	 *         class.
+	 */
+	public static <S, T> IBeanValueProperty<S, T> value(
+			Class<? extends S> beanClass, String propertyName,
+			Class<T> valueType) {
+		String[] propertyNames = splitOffFirst(propertyName);
+
+		if (beanClass == null) {
+			// beanClass cannot be null.
+			// For legacy reasons, we allow this through but log it.
+			// Three cycles after Kepler this can be removed.
+			// throw new IllegalArgumentException("beanClass cannot be null"); //$NON-NLS-1$
+			Policy.getLog().log(
+					new Status(IStatus.WARNING, Policy.JFACE_DATABINDING,
+							"beanClass cannot be null")); //$NON-NLS-1$
 		}
-		propertyNames.add(propertyName);
-		return (String[]) propertyNames
-				.toArray(new String[propertyNames.size()]);
+		if (valueType == null) {
+			// valueType cannot be null.
+			// For legacy reasons, we allow this through but log it.
+			// Three cycles after Kepler this can be removed.
+			// throw new IllegalArgumentException("valueType cannot be null"); //$NON-NLS-1$
+			Policy.getLog().log(
+					new Status(IStatus.WARNING, Policy.JFACE_DATABINDING,
+							"valueType cannot be null")); //$NON-NLS-1$
+		}
+
+		// This is here for legacy reasons only
+		if (beanClass == null && valueType == null) {
+			return (IBeanValueProperty<S, T>) value(propertyName);
+		}
+		if (beanClass == null) {
+			return (IBeanValueProperty<S, T>) value(propertyName, valueType);
+		}
+		if (valueType == null) {
+			return (IBeanValueProperty<S, T>) value(beanClass, propertyName);
+		}
+
+		PropertyDescriptor propertyDescriptor = BeanPropertyHelper
+				.getPropertyDescriptor(beanClass, propertyNames[0]);
+
+		if (propertyNames.length == 1) {
+			IValueProperty<S, T> property = new BeanValueProperty<S, T>(
+					propertyDescriptor, valueType);
+			return new BeanValuePropertyDecorator<S, T>(property,
+					propertyDescriptor);
+		}
+
+		return valueGivenDescriptor(beanClass, propertyDescriptor,
+				propertyDescriptor.getPropertyType(), propertyNames[1],
+				valueType);
+	}
+
+	/**
+	 * This is a private method used by the above to recursively chain
+	 * IValueProperty objects when the bean property name has multiple parts
+	 * ("parent.child").
+	 * <P>
+	 * This method is given the property descriptor for the getter method that
+	 * gets one from the parent (class S) to the first level child (class I). It
+	 * then makes a recursive call to get the IValueProperty that gets from the
+	 * first level child to the final property (class T).
+	 * 
+	 * @param <S>
+	 *            type of the parent object, being the object that contains the
+	 *            property specified by propertyDescriptor
+	 * @param <I>
+	 *            type of the intermediate object, being the first level child
+	 *            object and being the property type of the property specified
+	 *            by propertyDescriptor
+	 * @param <T>
+	 *            expected type of the final child given
+	 * @param sourceBeanClass
+	 * @param propertyDescriptor
+	 * @param childBeanClass
+	 * @param propertyName
+	 *            the property name. May be nested e.g. "parent.name"
+	 * @param valueType
+	 *            the expected type of the final child property which may be
+	 *            null if the caller does not know the type in advance
+	 * @return a value property that gets from S to T
+	 */
+	private static <S, I, T> IBeanValueProperty<S, T> valueGivenDescriptor(
+			Class<? extends S> sourceBeanClass,
+			PropertyDescriptor propertyDescriptor, Class<I> childBeanClass,
+			String propertyName, Class<T> valueType) {
+
+		IValueProperty<S, I> property = new BeanValueProperty<S, I>(
+				propertyDescriptor, childBeanClass);
+		IBeanValueProperty<S, I> decoratedProperty = new BeanValuePropertyDecorator<S, I>(
+				property, propertyDescriptor);
+
+		IBeanValueProperty<I, T> remainder = value(childBeanClass,
+				propertyName, valueType);
+
+		return decoratedProperty.value(remainder);
+	}
+
+	/**
+	 * This is a private method used by the above to recursively chain
+	 * IValueProperty objects when the bean property name has multiple parts
+	 * ("parent.child").
+	 * <P>
+	 * This method is given the property descriptor for the getter method that
+	 * gets one from the parent (class S) to the first level child (class I). It
+	 * then makes a recursive call to get the IValueProperty that gets from the
+	 * first level child to the final property (class T).
+	 * 
+	 * @param <S>
+	 *            type of the parent object, being the object that contains the
+	 *            property specified by propertyDescriptor
+	 * @param <I>
+	 *            type of the intermediate object, being the first level child
+	 *            object and being the property type of the property specified
+	 *            by propertyDescriptor
+	 * @param sourceBeanClass
+	 * @param propertyDescriptor
+	 * @param childBeanClass
+	 * @param propertyName
+	 *            the property name. May be nested e.g. "parent.name"
+	 * @return a value property that gets from S to T
+	 */
+	private static <S, I> IBeanValueProperty<S, ?> valueGivenDescriptor(
+			Class<? extends S> sourceBeanClass,
+			PropertyDescriptor propertyDescriptor, Class<I> childBeanClass,
+			String propertyName) {
+
+		IValueProperty<S, I> property = new BeanValueProperty<S, I>(
+				propertyDescriptor, childBeanClass);
+		IBeanValueProperty<S, I> decoratedProperty = new BeanValuePropertyDecorator<S, I>(
+				property, propertyDescriptor);
+
+		IBeanValueProperty<I, ?> remainder = value(childBeanClass, propertyName);
+
+		return decoratedProperty.value(remainder);
+	}
+
+	/**
+	 * Splits off the first part of a property name. For example, if
+	 * "parent.child.child2" is passed in then { "parent", "child.child2" } is
+	 * returned.
+	 * 
+	 * @param propertyName
+	 *            the property name. May be nested e.g. "parent.name"
+	 * @return a String array with either one element if there is no 'dot' in
+	 *         the property name, or two elements split at the position of the
+	 *         first 'dot'
+	 */
+	private static String[] splitOffFirst(String propertyName) {
+		int index = propertyName.indexOf('.');
+		if (index == -1) {
+			return new String[] { propertyName };
+		}
+		return new String[] { propertyName.substring(0, index),
+				propertyName.substring(index + 1) };
 	}
 
 	/**
@@ -150,16 +324,38 @@
 	 *            array of property names. May be nested e.g. "parent.name"
 	 * @return a value property array for the given property names of the given
 	 *         bean class.
+	 * @deprecated use valuesAsList because that returns a better typed result
 	 */
-	public static IBeanValueProperty[] values(Class beanClass,
+	public static <S> IBeanValueProperty<?, ?>[] values(Class<S> beanClass,
 			String[] propertyNames) {
-		IBeanValueProperty[] properties = new IBeanValueProperty[propertyNames.length];
+		IBeanValueProperty<?, ?>[] properties = new IBeanValueProperty[propertyNames.length];
 		for (int i = 0; i < properties.length; i++)
 			properties[i] = value(beanClass, propertyNames[i], null);
 		return properties;
 	}
 
 	/**
+	 * Returns a value property array for the given property names of the given
+	 * bean class.
+	 * 
+	 * @param beanClass
+	 *            the bean class
+	 * @param propertyNames
+	 *            array of property names. May be nested e.g. "parent.name"
+	 * @return a value property array for the given property names of the given
+	 *         bean class.
+	 * @since 1.5
+	 */
+	public static <S> List<IBeanValueProperty<S, Object>> valuesAsList(
+			Class<S> beanClass, String[] propertyNames) {
+		List<IBeanValueProperty<S, Object>> properties = new ArrayList<IBeanValueProperty<S, Object>>(
+				propertyNames.length);
+		for (int i = 0; i < propertyNames.length; i++)
+			properties.add(value(beanClass, propertyNames[i], null));
+		return properties;
+	}
+
+	/**
 	 * Returns a value property array for the given property names of an
 	 * arbitrary bean class.
 	 * 
@@ -167,9 +363,28 @@
 	 *            array of property names. May be nested e.g. "parent.name"
 	 * @return a value property array for the given property names of the given
 	 *         bean class.
+	 * @deprecated use valuesAsList because that returns a better typed result
 	 */
-	public static IBeanValueProperty[] values(String[] propertyNames) {
-		return values(null, propertyNames);
+	public static IBeanValueProperty<?, ?>[] values(String[] propertyNames) {
+		IBeanValueProperty<?, ?>[] properties = new IBeanValueProperty[propertyNames.length];
+		for (int i = 0; i < properties.length; i++)
+			properties[i] = value(propertyNames[i]);
+		return properties;
+	}
+
+	/**
+	 * Returns a value property array for the given property names of an
+	 * arbitrary bean class.
+	 * 
+	 * @param propertyNames
+	 *            array of property names. May be nested e.g. "parent.name"
+	 * @return a value property array for the given property names of the given
+	 *         bean class.
+	 * @since 1.5
+	 */
+	public static List<IBeanValueProperty<Object, Object>> valuesAsList(
+			String[] propertyNames) {
+		return valuesAsList(null, propertyNames);
 	}
 
 	/**
@@ -182,7 +397,7 @@
 	 * @return a set property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanSetProperty set(String propertyName) {
+	public static <S, E> IBeanSetProperty<S, E> set(String propertyName) {
 		return set(null, propertyName, null);
 	}
 
@@ -198,7 +413,8 @@
 	 * @return a set property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanSetProperty set(String propertyName, Class elementType) {
+	public static <S, E> IBeanSetProperty<S, E> set(String propertyName,
+			Class<E> elementType) {
 		return set(null, propertyName, elementType);
 	}
 
@@ -213,7 +429,8 @@
 	 * @return a set property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanSetProperty set(Class beanClass, String propertyName) {
+	public static <S, E> IBeanSetProperty<S, E> set(Class<S> beanClass,
+			String propertyName) {
 		return set(beanClass, propertyName, null);
 	}
 
@@ -230,19 +447,22 @@
 	 * @return a set property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanSetProperty set(Class beanClass, String propertyName,
-			Class elementType) {
+	public static <S, E> IBeanSetProperty<S, E> set(
+			Class<? extends S> beanClass, String propertyName,
+			Class<E> elementType) {
 		PropertyDescriptor propertyDescriptor;
-		ISetProperty property;
+		ISetProperty<S, E> property;
 		if (beanClass == null) {
 			propertyDescriptor = null;
-			property = new AnonymousBeanSetProperty(propertyName, elementType);
+			property = new AnonymousBeanSetProperty<S, E>(propertyName,
+					elementType);
 		} else {
 			propertyDescriptor = BeanPropertyHelper.getPropertyDescriptor(
 					beanClass, propertyName);
-			property = new BeanSetProperty(propertyDescriptor, elementType);
+			property = new BeanSetProperty<S, E>(propertyDescriptor,
+					elementType);
 		}
-		return new BeanSetPropertyDecorator(property, propertyDescriptor);
+		return new BeanSetPropertyDecorator<S, E>(property, propertyDescriptor);
 	}
 
 	/**
@@ -255,7 +475,7 @@
 	 * @return a list property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanListProperty list(String propertyName) {
+	public static <S, E> IBeanListProperty<S, E> list(String propertyName) {
 		return list(null, propertyName, null);
 	}
 
@@ -271,7 +491,8 @@
 	 * @return a list property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanListProperty list(String propertyName, Class elementType) {
+	public static <S, E> IBeanListProperty<S, E> list(String propertyName,
+			Class<E> elementType) {
 		return list(null, propertyName, elementType);
 	}
 
@@ -286,8 +507,29 @@
 	 * @return a list property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanListProperty list(Class beanClass, String propertyName) {
-		return list(beanClass, propertyName, null);
+	public static <S> IBeanListProperty<S, ?> list(Class<S> beanClass,
+			String propertyName) {
+		if (beanClass == null) {
+			return new BeanListPropertyDecorator<S, Object>(
+					new AnonymousBeanListProperty<S, Object>(propertyName, null),
+					null);
+		}
+
+		PropertyDescriptor propertyDescriptor = BeanPropertyHelper
+				.getPropertyDescriptor(beanClass, propertyName);
+
+		Class<?> elementType = propertyDescriptor.getPropertyType().isArray() ? propertyDescriptor
+				.getPropertyType().getComponentType() : Object.class;
+
+		return createBeanListProperty(beanClass, propertyDescriptor,
+				elementType);
+	}
+
+	private static <S, T> IBeanListProperty<S, T> createBeanListProperty(
+			Class<S> beanClass, PropertyDescriptor propertyDescriptor,
+			Class<T> valueType) {
+		return new BeanListPropertyDecorator<S, T>(new BeanListProperty<S, T>(
+				propertyDescriptor, valueType), propertyDescriptor);
 	}
 
 	/**
@@ -295,7 +537,9 @@
 	 * class.
 	 * 
 	 * @param beanClass
-	 *            the bean class
+	 *            the bean class, which may be a class that extends S because it
+	 *            may be a delegate and the property methods may be in this
+	 *            delegate but not in S itself
 	 * @param propertyName
 	 *            the property name
 	 * @param elementType
@@ -303,19 +547,22 @@
 	 * @return a list property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanListProperty list(Class beanClass, String propertyName,
-			Class elementType) {
+	public static <S, E> IBeanListProperty<S, E> list(
+			Class<? extends S> beanClass, String propertyName,
+			Class<E> elementType) {
 		PropertyDescriptor propertyDescriptor;
-		IListProperty property;
+		IListProperty<S, E> property;
 		if (beanClass == null) {
 			propertyDescriptor = null;
-			property = new AnonymousBeanListProperty(propertyName, elementType);
+			property = new AnonymousBeanListProperty<S, E>(propertyName,
+					elementType);
 		} else {
 			propertyDescriptor = BeanPropertyHelper.getPropertyDescriptor(
 					beanClass, propertyName);
-			property = new BeanListProperty(propertyDescriptor, elementType);
+			property = new BeanListProperty<S, E>(propertyDescriptor,
+					elementType);
 		}
-		return new BeanListPropertyDecorator(property, propertyDescriptor);
+		return new BeanListPropertyDecorator<S, E>(property, propertyDescriptor);
 	}
 
 	/**
@@ -328,7 +575,7 @@
 	 * @return a map property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanMapProperty map(String propertyName) {
+	public static <S, K, V> IBeanMapProperty<S, K, V> map(String propertyName) {
 		return map(null, propertyName, null, null);
 	}
 
@@ -346,8 +593,8 @@
 	 * @return a map property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanMapProperty map(String propertyName, Class keyType,
-			Class valueType) {
+	public static <S, K, V> IBeanMapProperty<S, K, V> map(String propertyName,
+			Class<K> keyType, Class<V> valueType) {
 		return map(null, propertyName, keyType, valueType);
 	}
 
@@ -362,7 +609,8 @@
 	 * @return a map property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanMapProperty map(Class beanClass, String propertyName) {
+	public static <S, K, V> IBeanMapProperty<S, K, V> map(Class<S> beanClass,
+			String propertyName) {
 		return map(beanClass, propertyName, null, null);
 	}
 
@@ -381,20 +629,22 @@
 	 * @return a map property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanMapProperty map(Class beanClass, String propertyName,
-			Class keyType, Class valueType) {
+	public static <S, K, V> IBeanMapProperty<S, K, V> map(
+			Class<? extends S> beanClass, String propertyName,
+			Class<K> keyType, Class<V> valueType) {
 		PropertyDescriptor propertyDescriptor;
-		IMapProperty property;
+		IMapProperty<S, K, V> property;
 		if (beanClass == null) {
 			propertyDescriptor = null;
-			property = new AnonymousBeanMapProperty(propertyName, keyType,
-					valueType);
+			property = new AnonymousBeanMapProperty<S, K, V>(propertyName,
+					keyType, valueType);
 		} else {
 			propertyDescriptor = BeanPropertyHelper.getPropertyDescriptor(
 					beanClass, propertyName);
-			property = new BeanMapProperty(propertyDescriptor, keyType,
-					valueType);
+			property = new BeanMapProperty<S, K, V>(propertyDescriptor,
+					keyType, valueType);
 		}
-		return new BeanMapPropertyDecorator(property, propertyDescriptor);
+		return new BeanMapPropertyDecorator<S, K, V>(property,
+				propertyDescriptor);
 	}
 }
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/BeansObservables.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/BeansObservables.java
index bc02766..fc79acc 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/BeansObservables.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/BeansObservables.java
@@ -15,8 +15,9 @@
 package org.eclipse.core.databinding.beans;
 
 import java.beans.PropertyDescriptor;
+import java.util.ArrayList;
+import java.util.List;
 
-import org.eclipse.core.databinding.observable.IObservable;
 import org.eclipse.core.databinding.observable.Realm;
 import org.eclipse.core.databinding.observable.list.IObservableList;
 import org.eclipse.core.databinding.observable.map.IObservableMap;
@@ -41,7 +42,7 @@
  * specification</a> for bound properties.
  * 
  * @since 1.1
- * 
+ * @deprecated use methods in BeanProperties
  */
 final public class BeansObservables {
 
@@ -53,6 +54,11 @@
 	/**
 	 * Returns an observable value in the default realm tracking the current
 	 * value of the named property of the given bean.
+	 * <P>
+	 * This method returns a wild card result. You should almost always be using
+	 * the form of this method that has the additional valueType parameter. By
+	 * passing the class of the value you will get back an appropriately
+	 * parameterized observable.
 	 * 
 	 * @param bean
 	 *            the object
@@ -61,11 +67,60 @@
 	 * @return an observable value tracking the current value of the named
 	 *         property of the given bean
 	 */
-	public static IObservableValue observeValue(Object bean, String propertyName) {
+	public static <S> IObservableValue<?> observeValue(S bean,
+			String propertyName) {
 		return observeValue(Realm.getDefault(), bean, propertyName);
 	}
 
 	/**
+	 * Returns an observable value in the default realm tracking the current
+	 * value of the named property of the given bean.
+	 * 
+	 * @param bean
+	 *            the object
+	 * @param propertyName
+	 *            the name of the property. May be nested e.g. "parent.name"
+	 * @param valueType
+	 *            the value type which must not be null
+	 * @return an observable value tracking the current value of the named
+	 *         property of the given bean
+	 * @since 1.5
+	 */
+	public static <S, T> IObservableValue<T> observeValue(S bean,
+			String propertyName, Class<T> valueType) {
+		return observeValue(Realm.getDefault(), bean, propertyName, valueType);
+	}
+
+	/**
+	 * Returns an observable value in the given realm tracking the current value
+	 * of the named property of the given bean.
+	 * <P>
+	 * This method returns a wild card result. You should almost always be using
+	 * the form of this method that has the additional valueType parameter. By
+	 * passing the class of the value you will get back an appropriately
+	 * parameterized observable.
+	 * 
+	 * @param realm
+	 *            the realm
+	 * @param bean
+	 *            the object
+	 * @param propertyName
+	 *            the name of the property. May be nested e.g. "parent.name"
+	 * @return an observable value tracking the current value of the named
+	 *         property of the given bean
+	 */
+	public static <S> IObservableValue<?> observeValue(Realm realm, S bean,
+			String propertyName) {
+		return observeValue(realm, Util.getClass(bean), bean, propertyName);
+	}
+
+	private static <S, S2 extends S> IObservableValue<?> observeValue(
+			Realm realm, Class<S2> beanClass, S bean, String propertyName) {
+		return BeanProperties.<S2> value(beanClass, propertyName).observe(
+				realm, beanClass.cast(bean));
+	}
+
+	/**
 	 * Returns an observable value in the given realm tracking the current value
 	 * of the named property of the given bean.
 	 * 
@@ -75,13 +130,16 @@
 	 *            the object
 	 * @param propertyName
 	 *            the name of the property. May be nested e.g. "parent.name"
+	 * @param valueType
+	 *            the value type which must not be null
 	 * @return an observable value tracking the current value of the named
 	 *         property of the given bean
+	 * @since 1.5
 	 */
-	public static IObservableValue observeValue(Realm realm, Object bean,
-			String propertyName) {
-		return BeanProperties.value(bean.getClass(), propertyName).observe(
-				realm, bean);
+	public static <S, T> IObservableValue<T> observeValue(Realm realm, S bean,
+			String propertyName, Class<T> valueType) {
+		return BeanProperties.<S, T> value(Util.getClass(bean), propertyName,
+				valueType).observe(realm, bean);
 	}
 
 	/**
@@ -99,8 +157,8 @@
 	 *         property for the beans in the given domain set
 	 * @since 1.2
 	 */
-	public static IObservableMap observeMap(IObservableSet domain,
-			String propertyName) {
+	public static <S> IObservableMap<S, Object> observeMap(
+			IObservableSet<S> domain, String propertyName) {
 		return BeanProperties.value(propertyName).observeDetail(domain);
 	}
 
@@ -117,9 +175,9 @@
 	 * @return an observable map tracking the current values of the named
 	 *         property for the beans in the given domain set
 	 */
-	public static IObservableMap observeMap(IObservableSet domain,
-			Class beanClass, String propertyName) {
-		return BeanProperties.value(beanClass, propertyName).observeDetail(
+	public static <S> IObservableMap<S, ?> observeMap(IObservableSet<S> domain,
+			Class<S> beanClass, String propertyName) {
+		return BeanProperties.<S> value(beanClass, propertyName).observeDetail(
 				domain);
 	}
 
@@ -137,7 +195,7 @@
 	 *         given bean object
 	 * @since 1.1
 	 */
-	public static IObservableMap observeMap(Realm realm, Object bean,
+	public static <S> IObservableMap<?, ?> observeMap(Realm realm, S bean,
 			String propertyName) {
 		return observeMap(realm, bean, propertyName, null, null);
 	}
@@ -162,10 +220,11 @@
 	 *         given bean object
 	 * @since 1.2
 	 */
-	public static IObservableMap observeMap(Realm realm, Object bean,
-			String propertyName, Class keyType, Class valueType) {
-		return BeanProperties.map(bean.getClass(), propertyName, keyType,
-				valueType).observe(realm, bean);
+	public static <S, K, V> IObservableMap<K, V> observeMap(Realm realm,
+			S bean, String propertyName, Class<K> keyType, Class<V> valueType) {
+		Class<? extends S> beanClass = Util.getClass(bean);
+		return BeanProperties.<Object, K, V> map(beanClass, propertyName,
+				keyType, valueType).observe(realm, bean);
 	}
 
 	/**
@@ -180,7 +239,8 @@
 	 *         given bean object
 	 * @since 1.2
 	 */
-	public static IObservableMap observeMap(Object bean, String propertyName) {
+	public static <S> IObservableMap<?, ?> observeMap(S bean,
+			String propertyName) {
 		return observeMap(Realm.getDefault(), bean, propertyName, null, null);
 	}
 
@@ -202,8 +262,8 @@
 	 *         given bean object
 	 * @since 1.2
 	 */
-	public static IObservableMap observeMap(Object bean, String propertyName,
-			Class keyType, Class valueType) {
+	public static <S, K, V> IObservableMap<K, V> observeMap(S bean,
+			String propertyName, Class<K> keyType, Class<V> valueType) {
 		return observeMap(Realm.getDefault(), bean, propertyName, keyType,
 				valueType);
 	}
@@ -221,12 +281,15 @@
 	 * @param propertyNames
 	 *            the array of property names. May be nested e.g. "parent.name"
 	 * @return an array of observable maps tracking the current values of the
-	 *         named propertys for the beans in the given domain set
+	 *         named properties for the beans in the given domain set
 	 * @since 1.2
+	 * @deprecated use instead observeMaps( IObservableSet<S> domain,
+	 *             List<String> propertyNames) because that method has better
+	 *             type safety
 	 */
-	public static IObservableMap[] observeMaps(IObservableSet domain,
-			String[] propertyNames) {
-		IObservableMap[] result = new IObservableMap[propertyNames.length];
+	public static <S> IObservableMap<?, ?>[] observeMaps(
+			IObservableSet<S> domain, String[] propertyNames) {
+		IObservableMap<?, ?>[] result = new IObservableMap[propertyNames.length];
 		for (int i = 0; i < propertyNames.length; i++) {
 			result[i] = observeMap(domain, propertyNames[i]);
 		}
@@ -236,6 +299,32 @@
 	/**
 	 * Returns an array of observable maps in the given observable set's realm
 	 * tracking the current values of the named properties for the beans in the
+	 * given set. Elements in the set which do not have the named property will
+	 * have null values, and attempts to
+	 * {@link IObservableMap#put(Object, Object) put} values to these elements
+	 * will be ignored.
+	 * 
+	 * @param domain
+	 *            the set of objects
+	 * @param propertyNames
+	 *            the array of property names. May be nested e.g. "parent.name"
+	 * @return an array of observable maps tracking the current values of the
+	 *         named properties for the beans in the given domain set
+	 * @since 1.5
+	 */
+	public static <S> List<IObservableMap<S, ?>> observeMaps2(
+			IObservableSet<S> domain, String[] propertyNames) {
+		List<IObservableMap<S, ?>> result = new ArrayList<IObservableMap<S, ?>>(
+				propertyNames.length);
+		for (int i = 0; i < propertyNames.length; i++) {
+			result.add(observeMap(domain, propertyNames[i]));
+		}
+		return result;
+	}
+
+	/**
+	 * Returns an array of observable maps in the given observable set's realm
+	 * tracking the current values of the named properties for the beans in the
 	 * given set.
 	 * 
 	 * @param domain
@@ -245,11 +334,16 @@
 	 * @param propertyNames
 	 *            the array of property names. May be nested e.g. "parent.name"
 	 * @return an array of observable maps tracking the current values of the
-	 *         named propertys for the beans in the given domain set
+	 *         named properties for the beans in the given domain set
+	 * @deprecated use instead observeMaps( IObservableSet<S> domain, Class<S>
+	 *             beanClass, List<String> propertyNames) because that method
+	 *             has better type safety
 	 */
+	// OK to ignore warning in deprecated method
+	@SuppressWarnings({ "unchecked", "rawtypes" })
 	public static IObservableMap[] observeMaps(IObservableSet domain,
 			Class beanClass, String[] propertyNames) {
-		IObservableMap[] result = new IObservableMap[propertyNames.length];
+		IObservableMap<?, ?>[] result = new IObservableMap[propertyNames.length];
 		for (int i = 0; i < propertyNames.length; i++) {
 			result[i] = observeMap(domain, beanClass, propertyNames[i]);
 		}
@@ -257,6 +351,31 @@
 	}
 
 	/**
+	 * Returns an array of observable maps in the given observable set's realm
+	 * tracking the current values of the named properties for the beans in the
+	 * given set.
+	 * 
+	 * @param domain
+	 *            the set of objects
+	 * @param beanClass
+	 *            the common base type of objects that may be in the set
+	 * @param propertyNames
+	 *            the array of property names. May be nested e.g. "parent.name"
+	 * @return an array of observable maps tracking the current values of the
+	 *         named properties for the beans in the given domain set
+	 * @since 1.5
+	 */
+	public static <S> List<IObservableMap<S, ?>> observeMaps2(
+			IObservableSet<S> domain, Class<S> beanClass, String[] propertyNames) {
+		List<IObservableMap<S, ?>> result = new ArrayList<IObservableMap<S, ?>>(
+				propertyNames.length);
+		for (int i = 0; i < propertyNames.length; i++) {
+			result.add(observeMap(domain, beanClass, propertyNames[i]));
+		}
+		return result;
+	}
+
+	/**
 	 * Returns an observable list in the given realm tracking the
 	 * collection-typed named property of the given bean object. The returned
 	 * list is mutable.
@@ -271,7 +390,7 @@
 	 *         of the given bean object
 	 * @see #observeList(Realm, Object, String, Class)
 	 */
-	public static IObservableList observeList(Realm realm, Object bean,
+	public static <S, E> IObservableList<E> observeList(Realm realm, S bean,
 			String propertyName) {
 		return observeList(realm, bean, propertyName, null);
 	}
@@ -290,7 +409,8 @@
 	 * @see #observeList(Realm, Object, String, Class)
 	 * @since 1.2
 	 */
-	public static IObservableList observeList(Object bean, String propertyName) {
+	public static <S, E> IObservableList<E> observeList(S bean,
+			String propertyName) {
 		return observeList(Realm.getDefault(), bean, propertyName);
 	}
 
@@ -317,8 +437,8 @@
 	 * @return an observable list tracking the collection-typed named property
 	 *         of the given bean object
 	 */
-	public static IObservableList observeList(Realm realm, Object bean,
-			String propertyName, Class elementType) {
+	public static <E> IObservableList<E> observeList(Realm realm, Object bean,
+			String propertyName, Class<E> elementType) {
 		return BeanProperties.list(bean.getClass(), propertyName, elementType)
 				.observe(realm, bean);
 	}
@@ -345,8 +465,8 @@
 	 *         of the given bean object
 	 * @since 1.2
 	 */
-	public static IObservableList observeList(Object bean, String propertyName,
-			Class elementType) {
+	public static <E> IObservableList<E> observeList(Object bean,
+			String propertyName, Class<E> elementType) {
 		return observeList(Realm.getDefault(), bean, propertyName, elementType);
 	}
 
@@ -363,7 +483,7 @@
 	 * @return an observable set tracking the collection-typed named property of
 	 *         the given bean object
 	 */
-	public static IObservableSet observeSet(Realm realm, Object bean,
+	public static <S, E> IObservableSet<E> observeSet(Realm realm, S bean,
 			String propertyName) {
 		return observeSet(realm, bean, propertyName, null);
 	}
@@ -380,7 +500,8 @@
 	 *         the given bean object
 	 * @since 1.2
 	 */
-	public static IObservableSet observeSet(Object bean, String propertyName) {
+	public static <S, E> IObservableSet<E> observeSet(S bean,
+			String propertyName) {
 		return observeSet(Realm.getDefault(), bean, propertyName);
 	}
 
@@ -394,8 +515,8 @@
 	 *            the name of the property. May be nested e.g. "parent.name"
 	 * @return an observable value factory
 	 */
-	public static IObservableFactory valueFactory(final Realm realm,
-			final String propertyName) {
+	public static IObservableFactory<Object, IObservableValue<Object>> valueFactory(
+			final Realm realm, final String propertyName) {
 		return BeanProperties.value(propertyName).valueFactory(realm);
 	}
 
@@ -408,7 +529,8 @@
 	 * @return an observable value factory
 	 * @since 1.2
 	 */
-	public static IObservableFactory valueFactory(String propertyName) {
+	public static IObservableFactory<Object, IObservableValue<Object>> valueFactory(
+			String propertyName) {
 		return valueFactory(Realm.getDefault(), propertyName);
 	}
 
@@ -423,9 +545,10 @@
 	 * @param elementType
 	 * @return an observable list factory
 	 */
-	public static IObservableFactory listFactory(final Realm realm,
-			final String propertyName, final Class elementType) {
-		return BeanProperties.list(propertyName, elementType)
+	public static <S, E> IObservableFactory<S, IObservableList<E>> listFactory(
+			final Realm realm, final String propertyName,
+			final Class<E> elementType) {
+		return BeanProperties.<S, E> list(propertyName, elementType)
 				.listFactory(realm);
 	}
 
@@ -439,8 +562,8 @@
 	 * @return an observable list factory
 	 * @since 1.2
 	 */
-	public static IObservableFactory listFactory(String propertyName,
-			Class elementType) {
+	public static <S, E> IObservableFactory<S, IObservableList<E>> listFactory(
+			String propertyName, Class<E> elementType) {
 		return listFactory(Realm.getDefault(), propertyName, elementType);
 	}
 
@@ -454,9 +577,9 @@
 	 *            the name of the property
 	 * @return an observable set factory
 	 */
-	public static IObservableFactory setFactory(final Realm realm,
-			final String propertyName) {
-		return BeanProperties.set(propertyName).setFactory(realm);
+	public static <S, E> IObservableFactory<S, IObservableSet<E>> setFactory(
+			final Realm realm, final String propertyName) {
+		return BeanProperties.<S, E> set(propertyName).setFactory(realm);
 	}
 
 	/**
@@ -468,7 +591,8 @@
 	 * @return an observable set factory
 	 * @since 1.2
 	 */
-	public static IObservableFactory setFactory(String propertyName) {
+	public static <S, E> IObservableFactory<S, IObservableSet<E>> setFactory(
+			String propertyName) {
 		return setFactory(Realm.getDefault(), propertyName);
 	}
 
@@ -491,15 +615,18 @@
 	 *             {@link #observeDetailValue(IObservableValue, String, Class)}
 	 *             instead
 	 */
-	public static IObservableValue observeDetailValue(Realm realm,
-			IObservableValue master, String propertyName, Class propertyType) {
+	public static <M, T> IObservableValue<T> observeDetailValue(Realm realm,
+			IObservableValue<M> master, String propertyName,
+			Class<T> propertyType) {
 		warnIfDifferentRealms(realm, master.getRealm());
 
-		IObservableValue value = MasterDetailObservables.detailValue(master,
+		IObservableValue<T> value = MasterDetailObservables.detailValue(
+				master,
 				BeanProperties.value(propertyName, propertyType).valueFactory(
 						realm), propertyType);
-		return new BeanObservableValueDecorator(value, BeanPropertyHelper
-				.getValueTypePropertyDescriptor(master, propertyName));
+		return new BeanObservableValueDecorator<T>(value,
+				BeanPropertyHelper.getValueTypePropertyDescriptor(master,
+						propertyName));
 	}
 
 	/* package */static void warnIfDifferentRealms(Realm detailRealm,
@@ -531,11 +658,10 @@
 	 * @see MasterDetailObservables
 	 * @since 1.2
 	 */
-	public static IObservableValue observeDetailValue(IObservableValue master,
-			String propertyName, Class propertyType) {
-		Class beanClass = null;
-		if (master.getValueType() instanceof Class)
-			beanClass = (Class) master.getValueType();
+	public static <M, T> IObservableValue<T> observeDetailValue(
+			IObservableValue<M> master, String propertyName,
+			Class<T> propertyType) {
+		Class<M> beanClass = master.getValueClass();
 		return observeDetailValue(master, beanClass, propertyName, propertyType);
 	}
 
@@ -566,16 +692,17 @@
 	 *             {@link #observeDetailValue(IObservableValue, Class, String, Class)}
 	 *             instead.
 	 */
-	public static IObservableValue observeDetailValue(Realm realm,
-			IObservableValue master, Class masterType, String propertyName,
-			Class propertyType) {
+	public static <M, T> IObservableValue<T> observeDetailValue(Realm realm,
+			IObservableValue<M> master, Class<M> masterType,
+			String propertyName, Class<T> propertyType) {
 		warnIfDifferentRealms(realm, master.getRealm());
 		Assert.isNotNull(masterType, "masterType cannot be null"); //$NON-NLS-1$
-		IObservableValue value = MasterDetailObservables.detailValue(master,
+		IObservableValue<T> value = MasterDetailObservables.detailValue(master,
 				BeanProperties.value(masterType, propertyName, propertyType)
 						.valueFactory(realm), propertyType);
-		return new BeanObservableValueDecorator(value, BeanPropertyHelper
-				.getPropertyDescriptor(masterType, propertyName));
+		return new BeanObservableValueDecorator<T>(value,
+				BeanPropertyHelper.getPropertyDescriptor(masterType,
+						propertyName));
 	}
 
 	/**
@@ -600,8 +727,9 @@
 	 * @see MasterDetailObservables
 	 * @since 1.2
 	 */
-	public static IObservableValue observeDetailValue(IObservableValue master,
-			Class masterType, String propertyName, Class propertyType) {
+	public static <M, T> IObservableValue<T> observeDetailValue(
+			IObservableValue<M> master, Class<M> masterType,
+			String propertyName, Class<T> propertyType) {
 		return BeanProperties.value(masterType, propertyName, propertyType)
 				.observeDetail(master);
 	}
@@ -624,13 +752,14 @@
 	 *             {@link #observeDetailList(IObservableValue, String, Class)}
 	 *             instead
 	 */
-	public static IObservableList observeDetailList(Realm realm,
-			IObservableValue master, String propertyName, Class propertyType) {
+	public static <M, E> IObservableList<E> observeDetailList(Realm realm,
+			IObservableValue<M> master, String propertyName,
+			Class<E> propertyType) {
 		warnIfDifferentRealms(realm, master.getRealm());
-		IObservableList observableList = MasterDetailObservables.detailList(
+		IObservableList<E> observableList = MasterDetailObservables.detailList(
 				master, BeanProperties.list(propertyName, propertyType)
 						.listFactory(realm), propertyType);
-		return new BeanObservableListDecorator(observableList,
+		return new BeanObservableListDecorator<E>(observableList,
 				BeanPropertyHelper.getValueTypePropertyDescriptor(master,
 						propertyName));
 	}
@@ -649,11 +778,10 @@
 	 * @see MasterDetailObservables
 	 * @since 1.2
 	 */
-	public static IObservableList observeDetailList(IObservableValue master,
-			String propertyName, Class propertyType) {
-		Class beanClass = null;
-		if (master.getValueType() instanceof Class)
-			beanClass = (Class) master.getValueType();
+	public static <M, E> IObservableList<E> observeDetailList(
+			IObservableValue<M> master, String propertyName,
+			Class<E> propertyType) {
+		Class<M> beanClass = master.getValueClass();
 		return BeanProperties.list(beanClass, propertyName, propertyType)
 				.observeDetail(master);
 	}
@@ -676,15 +804,17 @@
 	 *             {@link #observeDetailSet(IObservableValue, String, Class)}
 	 *             instead.
 	 */
-	public static IObservableSet observeDetailSet(Realm realm,
-			IObservableValue master, String propertyName, Class propertyType) {
+	public static <M, E> IObservableSet<E> observeDetailSet(Realm realm,
+			IObservableValue<M> master, String propertyName,
+			Class<E> propertyType) {
 		warnIfDifferentRealms(realm, master.getRealm());
 
-		IObservableSet observableSet = MasterDetailObservables.detailSet(
+		IObservableSet<E> observableSet = MasterDetailObservables.detailSet(
 				master, BeanProperties.set(propertyName, propertyType)
 						.setFactory(realm), propertyType);
-		return new BeanObservableSetDecorator(observableSet, BeanPropertyHelper
-				.getValueTypePropertyDescriptor(master, propertyName));
+		return new BeanObservableSetDecorator<E>(observableSet,
+				BeanPropertyHelper.getValueTypePropertyDescriptor(master,
+						propertyName));
 	}
 
 	/**
@@ -701,11 +831,10 @@
 	 * @see MasterDetailObservables
 	 * @since 1.2
 	 */
-	public static IObservableSet observeDetailSet(IObservableValue master,
-			String propertyName, Class propertyType) {
-		Class beanClass = null;
-		if (master.getValueType() instanceof Class)
-			beanClass = (Class) master.getValueType();
+	public static <M, E> IObservableSet<E> observeDetailSet(
+			IObservableValue<M> master, String propertyName,
+			Class<E> propertyType) {
+		Class<M> beanClass = master.getValueClass();
 		return BeanProperties.set(beanClass, propertyName, propertyType)
 				.observeDetail(master);
 	}
@@ -724,13 +853,15 @@
 	 * @deprecated Use {@link #observeDetailMap(IObservableValue, String)}
 	 *             instead
 	 */
-	public static IObservableMap observeDetailMap(Realm realm,
-			IObservableValue master, String propertyName) {
+	public static <M, K, V> IObservableMap<K, V> observeDetailMap(Realm realm,
+			IObservableValue<M> master, String propertyName) {
 		warnIfDifferentRealms(realm, master.getRealm());
-		IObservableMap observableMap = MasterDetailObservables.detailMap(
-				master, BeanProperties.map(propertyName).mapFactory(realm));
-		return new BeanObservableMapDecorator(observableMap, BeanPropertyHelper
-				.getValueTypePropertyDescriptor(master, propertyName));
+		IObservableMap<K, V> observableMap = MasterDetailObservables.detailMap(
+				master,
+				BeanProperties.<M, K, V> map(propertyName).mapFactory(realm));
+		return new BeanObservableMapDecorator<K, V>(observableMap,
+				BeanPropertyHelper.getValueTypePropertyDescriptor(master,
+						propertyName));
 	}
 
 	/**
@@ -743,12 +874,10 @@
 	 *         current value of the master observable value.
 	 * @since 1.2
 	 */
-	public static IObservableMap observeDetailMap(IObservableValue master,
-			String propertyName) {
-		Class beanClass = null;
-		if (master.getValueType() instanceof Class)
-			beanClass = (Class) master.getValueType();
-		return BeanProperties.map(beanClass, propertyName)
+	public static <M, K, V> IObservableMap<K, V> observeDetailMap(
+			IObservableValue<M> master, String propertyName) {
+		Class<M> beanClass = master.getValueClass();
+		return BeanProperties.<M, K, V> map(beanClass, propertyName)
 				.observeDetail(master);
 	}
 
@@ -775,9 +904,10 @@
 	 * @return an observable set tracking the collection-typed named property of
 	 *         the given bean object
 	 */
-	public static IObservableSet observeSet(Realm realm, Object bean,
-			String propertyName, Class elementType) {
-		return BeanProperties.set(bean.getClass(), propertyName, elementType)
+	public static <S, E> IObservableSet<E> observeSet(Realm realm, S bean,
+			String propertyName, Class<E> elementType) {
+		Class<? extends S> beanClass = Util.getClass(bean);
+		return BeanProperties.set(beanClass, propertyName, elementType)
 				.observe(realm, bean);
 	}
 
@@ -803,8 +933,8 @@
 	 *         the given bean object
 	 * @since 1.2
 	 */
-	public static IObservableSet observeSet(Object bean, String propertyName,
-			Class elementType) {
+	public static <S, E> IObservableSet<E> observeSet(S bean,
+			String propertyName, Class<E> elementType) {
 		return observeSet(Realm.getDefault(), bean, propertyName, elementType);
 	}
 
@@ -824,8 +954,9 @@
 	 * @return a factory for creating observable sets in the given realm,
 	 *         tracking the given property of a particular bean object
 	 */
-	public static IObservableFactory setFactory(final Realm realm,
-			final String propertyName, final Class elementType) {
+	public static <E> IObservableFactory<Object, IObservableSet<E>> setFactory(
+			final Realm realm, final String propertyName,
+			final Class<E> elementType) {
 		return BeanProperties.set(propertyName, elementType).setFactory(realm);
 	}
 
@@ -844,8 +975,8 @@
 	 *         tracking the given property of a particular bean object
 	 * @since 1.2
 	 */
-	public static IObservableFactory setFactory(String propertyName,
-			Class elementType) {
+	public static <E> IObservableFactory<Object, IObservableSet<E>> setFactory(
+			String propertyName, Class<E> elementType) {
 		return setFactory(Realm.getDefault(), propertyName, elementType);
 	}
 
@@ -864,12 +995,12 @@
 	 * 
 	 * @since 1.1
 	 */
-	public static IObservableFactory setToMapFactory(final Class beanClass,
-			final String propertyName) {
-		return new IObservableFactory() {
-			public IObservable createObservable(Object target) {
-				return observeMap((IObservableSet) target, beanClass,
-						propertyName);
+	public static <S> IObservableFactory<IObservableSet<S>, IObservableMap<S, ?>> setToMapFactory(
+			final Class<S> beanClass, final String propertyName) {
+		return new IObservableFactory<IObservableSet<S>, IObservableMap<S, ?>>() {
+			public IObservableMap<S, ?> createObservable(
+					IObservableSet<S> target) {
+				return observeMap(target, beanClass, propertyName);
 			}
 		};
 	}
@@ -888,9 +1019,9 @@
 	 * @return a factory for creating {@link IObservableMap} objects.
 	 * @since 1.1
 	 */
-	public static IObservableFactory mapPropertyFactory(final Realm realm,
-			final String propertyName) {
-		return BeanProperties.map(propertyName).mapFactory(realm);
+	public static <T, K, V> IObservableFactory<T, IObservableMap<K, V>> mapPropertyFactory(
+			final Realm realm, final String propertyName) {
+		return BeanProperties.<T, K, V> map(propertyName).mapFactory(realm);
 	}
 
 	/**
@@ -904,7 +1035,8 @@
 	 * @return a factory for creating {@link IObservableMap} objects.
 	 * @since 1.2
 	 */
-	public static IObservableFactory mapPropertyFactory(String propertyName) {
+	public static <T, K, V> IObservableFactory<T, IObservableMap<K, V>> mapPropertyFactory(
+			String propertyName) {
 		return mapPropertyFactory(Realm.getDefault(), propertyName);
 	}
 }
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanListProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanListProperty.java
index 95f80a0..075b505 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanListProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanListProperty.java
@@ -17,9 +17,14 @@
  * An {@link IListProperty} extension interface with convenience methods for
  * creating nested bean properties.
  * 
+ * @param <S>
+ *            type of the source object
+ * @param <E>
+ *            type of the elements in the list
  * @since 1.2
  */
-public interface IBeanListProperty extends IBeanProperty, IListProperty {
+public interface IBeanListProperty<S, E> extends IBeanProperty,
+		IListProperty<S, E> {
 	/**
 	 * Returns a master-detail combination of this property and the specified
 	 * value property.
@@ -31,7 +36,7 @@
 	 *         property.
 	 * @see #values(IBeanValueProperty)
 	 */
-	public IBeanListProperty values(String propertyName);
+	public <V> IBeanListProperty<S, V> values(String propertyName);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -46,7 +51,8 @@
 	 *         value property.
 	 * @see #values(IBeanValueProperty)
 	 */
-	public IBeanListProperty values(String propertyName, Class valueType);
+	public <V> IBeanListProperty<S, V> values(String propertyName,
+			Class<V> valueType);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -71,5 +77,5 @@
 	 * @return a master-detail combination of this property and the specified
 	 *         value property.
 	 */
-	public IBeanListProperty values(IBeanValueProperty property);
+	public <V> IBeanListProperty<S, V> values(IBeanValueProperty<E, V> property);
 }
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanMapProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanMapProperty.java
index 1cfde35..5e0b6b6 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanMapProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanMapProperty.java
@@ -19,11 +19,18 @@
  * An {@link IMapProperty} extension interface with convenience methods for
  * creating nested bean properties.
  * 
+ * @param <S>
+ *            type of the source object
+ * @param <K>
+ *            type of the keys to the map
+ * @param <V>
+ *            type of the values in the map
  * @since 1.2
  * @noextend This interface is not intended to be extended by clients.
  * @noimplement This interface is not intended to be implemented by clients.
  */
-public interface IBeanMapProperty extends IBeanProperty, IMapProperty {
+public interface IBeanMapProperty<S, K, V> extends IBeanProperty,
+		IMapProperty<S, K, V> {
 	/**
 	 * Returns a master-detail combination of this property and the specified
 	 * value property.
@@ -35,7 +42,7 @@
 	 *         value property.
 	 * @see #values(IBeanValueProperty)
 	 */
-	public IBeanMapProperty values(String propertyName);
+	public <T> IBeanMapProperty<S, K, T> values(String propertyName);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -50,7 +57,8 @@
 	 *         value property.
 	 * @see #values(IBeanValueProperty)
 	 */
-	public IBeanMapProperty values(String propertyName, Class valueType);
+	public <V2> IBeanMapProperty<S, K, V2> values(String propertyName,
+			Class<V2> valueType);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -65,5 +73,6 @@
 	 * @return a master-detail combination of this property and the specified
 	 *         value property.
 	 */
-	public IBeanMapProperty values(IBeanValueProperty property);
+	public <V2> IBeanMapProperty<S, K, V2> values(
+			IBeanValueProperty<V, V2> property);
 }
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanSetProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanSetProperty.java
index a5e70ae..88332fb 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanSetProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanSetProperty.java
@@ -17,11 +17,16 @@
  * An {@link ISetProperty} extension interface with convenience methods for
  * creating nested bean properties.
  * 
+ * @param <S>
+ *            type of the source object
+ * @param <E>
+ *            type of the elements in the set
  * @since 1.2
  * @noextend This interface is not intended to be extended by clients.
  * @noimplement This interface is not intended to be implemented by clients.
  */
-public interface IBeanSetProperty extends IBeanProperty, ISetProperty {
+public interface IBeanSetProperty<S, E> extends IBeanProperty,
+		ISetProperty<S, E> {
 	/**
 	 * Returns a master-detail combination of this property and the specified
 	 * value property.
@@ -33,7 +38,7 @@
 	 *         value property.
 	 * @see #values(IBeanValueProperty)
 	 */
-	public IBeanMapProperty values(String propertyName);
+	public <T> IBeanMapProperty<S, E, T> values(String propertyName);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -48,7 +53,8 @@
 	 *         value property.
 	 * @see #values(IBeanValueProperty)
 	 */
-	public IBeanMapProperty values(String propertyName, Class valueType);
+	public <T> IBeanMapProperty<S, E, T> values(String propertyName,
+			Class<T> valueType);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -75,5 +81,6 @@
 	 * @return a master-detail combination of this property and the specified
 	 *         value property.
 	 */
-	public IBeanMapProperty values(IBeanValueProperty property);
+	public <T> IBeanMapProperty<S, E, T> values(
+			IBeanValueProperty<E, T> property);
 }
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanValueProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanValueProperty.java
index 72153a6..310ee39 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanValueProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/IBeanValueProperty.java
@@ -17,11 +17,15 @@
  * An {@link IValueProperty} extension interface with convenience methods for
  * creating nested bean properties.
  * 
+ * @param <S>
+ * @param <T>
+ * 
  * @since 1.2
  * @noextend This interface is not intended to be extended by clients.
  * @noimplement This interface is not intended to be implemented by clients.
  */
-public interface IBeanValueProperty extends IBeanProperty, IValueProperty {
+public interface IBeanValueProperty<S, T> extends IBeanProperty,
+		IValueProperty<S, T> {
 	/**
 	 * Returns a master-detail combination of this property and the specified
 	 * value property.
@@ -33,7 +37,7 @@
 	 *         value property.
 	 * @see #value(IBeanValueProperty)
 	 */
-	public IBeanValueProperty value(String propertyName);
+	public <V> IBeanValueProperty<S, V> value(String propertyName);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -48,7 +52,8 @@
 	 *         value property.
 	 * @see #value(IBeanValueProperty)
 	 */
-	public IBeanValueProperty value(String propertyName, Class valueType);
+	public <V> IBeanValueProperty<S, V> value(String propertyName,
+			Class<V> valueType);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -71,7 +76,7 @@
 	 * @return a master-detail combination of this property and the specified
 	 *         value property.
 	 */
-	public IBeanValueProperty value(IBeanValueProperty property);
+	public <V> IBeanValueProperty<S, V> value(IBeanValueProperty<T, V> property);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -83,7 +88,7 @@
 	 *         list property.
 	 * @see #list(IBeanListProperty)
 	 */
-	public IBeanListProperty list(String propertyName);
+	public <E> IBeanListProperty<S, E> list(String propertyName);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -97,7 +102,8 @@
 	 *         list property.
 	 * @see #list(IBeanListProperty)
 	 */
-	public IBeanListProperty list(String propertyName, Class elementType);
+	public <E> IBeanListProperty<S, E> list(String propertyName,
+			Class<E> elementType);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -122,7 +128,7 @@
 	 * @return a master-detail combination of this property and the specified
 	 *         list property.
 	 */
-	public IBeanListProperty list(IBeanListProperty property);
+	public <E> IBeanListProperty<S, E> list(IBeanListProperty<T, E> property);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -134,7 +140,7 @@
 	 *         set property.
 	 * @see #set(IBeanSetProperty)
 	 */
-	public IBeanSetProperty set(String propertyName);
+	public <E> IBeanSetProperty<S, E> set(String propertyName);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -148,7 +154,8 @@
 	 *         set property.
 	 * @see #set(IBeanSetProperty)
 	 */
-	public IBeanSetProperty set(String propertyName, Class elementType);
+	public <E> IBeanSetProperty<S, E> set(String propertyName,
+			Class<E> elementType);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -173,7 +180,7 @@
 	 * @return a master-detail combination of this property and the specified
 	 *         set property.
 	 */
-	public IBeanSetProperty set(IBeanSetProperty property);
+	public <E> IBeanSetProperty<S, E> set(IBeanSetProperty<T, E> property);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -185,7 +192,7 @@
 	 *         map property.
 	 * @see #map(IBeanMapProperty)
 	 */
-	public IBeanMapProperty map(String propertyName);
+	public <K, V> IBeanMapProperty<S, K, V> map(String propertyName);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -201,8 +208,8 @@
 	 *         map property.
 	 * @see #map(IBeanMapProperty)
 	 */
-	public IBeanMapProperty map(String propertyName, Class keyType,
-			Class valueType);
+	public <K, V> IBeanMapProperty<S, K, V> map(String propertyName,
+			Class<K> keyType, Class<V> valueType);
 
 	/**
 	 * Returns a master-detail combination of this property and the specified
@@ -213,7 +220,7 @@
 	 * 
 	 * <pre>
 	 * // Observes the Contact-typed &quot;supervisor&quot; property of a
-	 * // Contact class 
+	 * // Contact class
 	 * IBeanValueProperty supervisor = BeanProperties.value(Contact.class,
 	 * 		&quot;supervisor&quot;);
 	 * // Observes the property &quot;phoneNumbers&quot; of a Contact object--a property mapping
@@ -229,5 +236,6 @@
 	 * @return a master-detail combination of this property and the specified
 	 *         map property.
 	 */
-	public IBeanMapProperty map(IBeanMapProperty property);
+	public <K, V> IBeanMapProperty<S, K, V> map(
+			IBeanMapProperty<? super T, K, V> property);
 }
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/PojoObservables.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/PojoObservables.java
index ecdcb2b..a49a967 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/PojoObservables.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/PojoObservables.java
@@ -14,6 +14,8 @@
 package org.eclipse.core.databinding.beans;
 
 import java.beans.PropertyChangeEvent;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.eclipse.core.databinding.observable.Realm;
 import org.eclipse.core.databinding.observable.list.IObservableList;
@@ -27,6 +29,7 @@
 import org.eclipse.core.internal.databinding.beans.BeanObservableSetDecorator;
 import org.eclipse.core.internal.databinding.beans.BeanObservableValueDecorator;
 import org.eclipse.core.internal.databinding.beans.BeanPropertyHelper;
+import org.eclipse.core.internal.databinding.beans.Util;
 
 /**
  * A factory for creating observable objects for POJOs (plain old java objects)
@@ -35,6 +38,7 @@
  * factory is identical to {@link BeansObservables} except for this fact.
  * 
  * @since 1.1
+ * @deprecated use methods in PojoProperties
  */
 final public class PojoObservables {
 
@@ -49,7 +53,8 @@
 	 * @return an observable value tracking the current value of the named
 	 *         property of the given pojo
 	 */
-	public static IObservableValue observeValue(Object pojo, String propertyName) {
+	public static <S> IObservableValue<?> observeValue(S pojo,
+			String propertyName) {
 		return observeValue(Realm.getDefault(), pojo, propertyName);
 	}
 
@@ -66,10 +71,15 @@
 	 * @return an observable value tracking the current value of the named
 	 *         property of the given pojo
 	 */
-	public static IObservableValue observeValue(Realm realm, Object pojo,
+	public static <S> IObservableValue<?> observeValue(Realm realm, S pojo,
 			String propertyName) {
-		return PojoProperties.value(pojo.getClass(), propertyName).observe(
-				realm, pojo);
+		return observeValue(realm, Util.getClass(pojo), pojo, propertyName);
+	}
+
+	private static <S, S2 extends S> IObservableValue<?> observeValue(
+			Realm realm, Class<S2> pojoClass, S pojo, String propertyName) {
+		return PojoProperties.<S2> value(pojoClass, propertyName).observe(
+				realm, pojoClass.cast(pojo));
 	}
 
 	/**
@@ -87,8 +97,8 @@
 	 *         property for the beans in the given domain set
 	 * @since 1.2
 	 */
-	public static IObservableMap observeMap(IObservableSet domain,
-			String propertyName) {
+	public static <S> IObservableMap<S, Object> observeMap(
+			IObservableSet<S> domain, String propertyName) {
 		return PojoProperties.value(propertyName).observeDetail(domain);
 	}
 
@@ -105,9 +115,9 @@
 	 * @return an observable map tracking the current values of the named
 	 *         property for the pojos in the given domain set
 	 */
-	public static IObservableMap observeMap(IObservableSet domain,
-			Class pojoClass, String propertyName) {
-		return PojoProperties.value(pojoClass, propertyName).observeDetail(
+	public static <S> IObservableMap<S, ?> observeMap(IObservableSet<S> domain,
+			Class<S> pojoClass, String propertyName) {
+		return PojoProperties.<S> value(pojoClass, propertyName).observeDetail(
 				domain);
 	}
 
@@ -124,12 +134,15 @@
 	 * @param propertyNames
 	 *            the array of property names. May be nested e.g. "parent.name"
 	 * @return an array of observable maps tracking the current values of the
-	 *         named propertys for the beans in the given domain set
+	 *         named properties for the beans in the given domain set
+	 * @deprecated use instead observeMaps( IObservableSet<S> domain,
+	 *             List<String> propertyNames) because that method has better
+	 *             type safety
 	 * @since 1.2
 	 */
-	public static IObservableMap[] observeMaps(IObservableSet domain,
-			String[] propertyNames) {
-		IObservableMap[] result = new IObservableMap[propertyNames.length];
+	public static <S> IObservableMap<?, ?>[] observeMaps(
+			IObservableSet<S> domain, String[] propertyNames) {
+		IObservableMap<?, ?>[] result = new IObservableMap[propertyNames.length];
 		for (int i = 0; i < propertyNames.length; i++) {
 			result[i] = observeMap(domain, propertyNames[i]);
 		}
@@ -138,7 +151,33 @@
 
 	/**
 	 * Returns an array of observable maps in the given observable set's realm
-	 * tracking the current values of the named propertys for the pojos in the
+	 * tracking the current values of the named properties for the beans in the
+	 * given set. Elements in the set which do not have the named property will
+	 * have null values, and attempts to
+	 * {@link IObservableMap#put(Object, Object) put} values to these elements
+	 * will be ignored.
+	 * 
+	 * @param domain
+	 *            the set of objects
+	 * @param propertyNames
+	 *            the array of property names. May be nested e.g. "parent.name"
+	 * @return an array of observable maps tracking the current values of the
+	 *         named properties for the beans in the given domain set
+	 * @since 1.5
+	 */
+	public static <S> List<IObservableMap<S, ?>> observeMaps2(
+			IObservableSet<S> domain, String[] propertyNames) {
+		List<IObservableMap<S, ?>> result = new ArrayList<IObservableMap<S, ?>>(
+				propertyNames.length);
+		for (int i = 0; i < propertyNames.length; i++) {
+			result.add(observeMap(domain, propertyNames[i]));
+		}
+		return result;
+	}
+
+	/**
+	 * Returns an array of observable maps in the given observable set's realm
+	 * tracking the current values of the named properties for the pojos in the
 	 * given set.
 	 * 
 	 * @param domain
@@ -148,11 +187,14 @@
 	 * @param propertyNames
 	 *            the array of property names. May be nested e.g. "parent.name"
 	 * @return an array of observable maps tracking the current values of the
-	 *         named propertys for the pojos in the given domain set
+	 *         named properties for the pojos in the given domain set
+	 * @deprecated use instead observeMaps( IObservableSet<S> domain, Class<S>
+	 *             beanClass, List<String> propertyNames) because that method
+	 *             has better type safety
 	 */
-	public static IObservableMap[] observeMaps(IObservableSet domain,
-			Class pojoClass, String[] propertyNames) {
-		IObservableMap[] result = new IObservableMap[propertyNames.length];
+	public static <S> IObservableMap<?, ?>[] observeMaps(
+			IObservableSet<S> domain, Class<S> pojoClass, String[] propertyNames) {
+		IObservableMap<?, ?>[] result = new IObservableMap[propertyNames.length];
 		for (int i = 0; i < propertyNames.length; i++) {
 			result[i] = observeMap(domain, pojoClass, propertyNames[i]);
 		}
@@ -160,6 +202,31 @@
 	}
 
 	/**
+	 * Returns an array of observable maps in the given observable set's realm
+	 * tracking the current values of the named properties for the pojos in the
+	 * given set.
+	 * 
+	 * @param domain
+	 *            the set of objects
+	 * @param pojoClass
+	 *            the common base type of objects that may be in the set
+	 * @param propertyNames
+	 *            the array of property names. May be nested e.g. "parent.name"
+	 * @return an array of observable maps tracking the current values of the
+	 *         named properties for the pojos in the given domain set
+	 * @since 1.5
+	 */
+	public static <S> List<IObservableMap<S, ?>> observeMaps2(
+			IObservableSet<S> domain, Class<S> pojoClass, String[] propertyNames) {
+		List<IObservableMap<S, ?>> result = new ArrayList<IObservableMap<S, ?>>(
+				propertyNames.length);
+		for (int i = 0; i < propertyNames.length; i++) {
+			result.add(observeMap(domain, pojoClass, propertyNames[i]));
+		}
+		return result;
+	}
+
+	/**
 	 * Returns an observable map in the given realm tracking the map-typed named
 	 * property of the given pojo object.
 	 * 
@@ -172,7 +239,7 @@
 	 * @return an observable map tracking the map-typed named property of the
 	 *         given pojo object
 	 */
-	public static IObservableMap observeMap(Realm realm, Object pojo,
+	public static <S> IObservableMap<?, ?> observeMap(Realm realm, S pojo,
 			String propertyName) {
 		return observeMap(realm, pojo, propertyName, null, null);
 	}
@@ -197,8 +264,8 @@
 	 *         given pojo object
 	 * @since 1.2
 	 */
-	public static IObservableMap observeMap(Realm realm, Object pojo,
-			String propertyName, Class keyType, Class valueType) {
+	public static <S, K, V> IObservableMap<K, V> observeMap(Realm realm,
+			S pojo, String propertyName, Class<K> keyType, Class<V> valueType) {
 		return PojoProperties.map(pojo.getClass(), propertyName, keyType,
 				valueType).observe(realm, pojo);
 	}
@@ -215,7 +282,8 @@
 	 *         given pojo object
 	 * @since 1.2
 	 */
-	public static IObservableMap observeMap(Object pojo, String propertyName) {
+	public static <S> IObservableMap<?, ?> observeMap(S pojo,
+			String propertyName) {
 		return observeMap(Realm.getDefault(), pojo, propertyName, null, null);
 	}
 
@@ -237,8 +305,8 @@
 	 *         given pojo object
 	 * @since 1.2
 	 */
-	public static IObservableMap observeMap(Object pojo, String propertyName,
-			Class keyType, Class valueType) {
+	public static <S, K, V> IObservableMap<K, V> observeMap(S pojo,
+			String propertyName, Class<K> keyType, Class<V> valueType) {
 		return observeMap(Realm.getDefault(), pojo, propertyName, keyType,
 				valueType);
 	}
@@ -258,7 +326,7 @@
 	 *         of the given pojo object
 	 * @see #observeList(Realm, Object, String, Class)
 	 */
-	public static IObservableList observeList(Realm realm, Object pojo,
+	public static <S> IObservableList<?> observeList(Realm realm, S pojo,
 			String propertyName) {
 		return observeList(realm, pojo, propertyName, null);
 	}
@@ -277,7 +345,7 @@
 	 * @see #observeList(Realm, Object, String, Class)
 	 * @since 1.2
 	 */
-	public static IObservableList observeList(Object pojo, String propertyName) {
+	public static <S> IObservableList<?> observeList(S pojo, String propertyName) {
 		return observeList(Realm.getDefault(), pojo, propertyName);
 	}
 
@@ -304,8 +372,8 @@
 	 * @return an observable list tracking the collection-typed named property
 	 *         of the given bean object
 	 */
-	public static IObservableList observeList(Realm realm, Object pojo,
-			String propertyName, Class elementType) {
+	public static <S, E> IObservableList<E> observeList(Realm realm, S pojo,
+			String propertyName, Class<E> elementType) {
 		return PojoProperties.list(pojo.getClass(), propertyName, elementType)
 				.observe(realm, pojo);
 	}
@@ -332,8 +400,8 @@
 	 *         of the given bean object
 	 * @since 1.2
 	 */
-	public static IObservableList observeList(Object pojo, String propertyName,
-			Class elementType) {
+	public static <S, E> IObservableList<E> observeList(S pojo,
+			String propertyName, Class<E> elementType) {
 		return observeList(Realm.getDefault(), pojo, propertyName, elementType);
 	}
 
@@ -350,7 +418,7 @@
 	 * @return an observable set tracking the collection-typed named property of
 	 *         the given pojo object
 	 */
-	public static IObservableSet observeSet(Realm realm, Object pojo,
+	public static <S> IObservableSet<?> observeSet(Realm realm, S pojo,
 			String propertyName) {
 		return observeSet(realm, pojo, propertyName, null);
 	}
@@ -367,7 +435,7 @@
 	 *         the given pojo object
 	 * @since 1.2
 	 */
-	public static IObservableSet observeSet(Object pojo, String propertyName) {
+	public static <S> IObservableSet<?> observeSet(S pojo, String propertyName) {
 		return observeSet(Realm.getDefault(), pojo, propertyName);
 	}
 
@@ -389,8 +457,8 @@
 	 * @return an observable set that tracks the current value of the named
 	 *         property for given pojo object
 	 */
-	public static IObservableSet observeSet(Realm realm, Object pojo,
-			String propertyName, Class elementType) {
+	public static <S, E> IObservableSet<E> observeSet(Realm realm, S pojo,
+			String propertyName, Class<E> elementType) {
 		return PojoProperties.set(pojo.getClass(), propertyName, elementType)
 				.observe(realm, pojo);
 	}
@@ -412,8 +480,8 @@
 	 *         property for given pojo object
 	 * @since 1.2
 	 */
-	public static IObservableSet observeSet(Object pojo, String propertyName,
-			Class elementType) {
+	public static <S, E> IObservableSet<E> observeSet(S pojo,
+			String propertyName, Class<E> elementType) {
 		return observeSet(Realm.getDefault(), pojo, propertyName, elementType);
 	}
 
@@ -427,8 +495,8 @@
 	 *            the name of the property. May be nested e.g. "parent.name"
 	 * @return an observable value factory
 	 */
-	public static IObservableFactory valueFactory(final Realm realm,
-			final String propertyName) {
+	public static IObservableFactory<Object, IObservableValue<Object>> valueFactory(
+			final Realm realm, final String propertyName) {
 		return PojoProperties.value(propertyName).valueFactory(realm);
 	}
 
@@ -441,7 +509,8 @@
 	 * @return an observable value factory
 	 * @since 1.2
 	 */
-	public static IObservableFactory valueFactory(String propertyName) {
+	public static IObservableFactory<Object, IObservableValue<Object>> valueFactory(
+			String propertyName) {
 		return valueFactory(Realm.getDefault(), propertyName);
 	}
 
@@ -456,8 +525,9 @@
 	 * @param elementType
 	 * @return an observable list factory
 	 */
-	public static IObservableFactory listFactory(final Realm realm,
-			final String propertyName, final Class elementType) {
+	public static <E> IObservableFactory<Object, IObservableList<E>> listFactory(
+			final Realm realm, final String propertyName,
+			final Class<E> elementType) {
 		return PojoProperties.list(propertyName, elementType)
 				.listFactory(realm);
 	}
@@ -472,8 +542,8 @@
 	 * @return an observable list factory
 	 * @since 1.2
 	 */
-	public static IObservableFactory listFactory(String propertyName,
-			Class elementType) {
+	public static <E> IObservableFactory<Object, IObservableList<E>> listFactory(
+			String propertyName, Class<E> elementType) {
 		return listFactory(Realm.getDefault(), propertyName, elementType);
 	}
 
@@ -487,8 +557,8 @@
 	 *            the name of the property
 	 * @return an observable set factory
 	 */
-	public static IObservableFactory setFactory(final Realm realm,
-			final String propertyName) {
+	public static IObservableFactory<Object, IObservableSet<Object>> setFactory(
+			final Realm realm, final String propertyName) {
 		return PojoProperties.set(propertyName).setFactory(realm);
 	}
 
@@ -501,7 +571,8 @@
 	 * @return an observable set factory
 	 * @since 1.2
 	 */
-	public static IObservableFactory setFactory(String propertyName) {
+	public static IObservableFactory<Object, IObservableSet<Object>> setFactory(
+			String propertyName) {
 		return setFactory(Realm.getDefault(), propertyName);
 	}
 
@@ -520,8 +591,9 @@
 	 *            element type will be <code>null</code>.
 	 * @return an observable set factory for creating observable sets
 	 */
-	public static IObservableFactory setFactory(final Realm realm,
-			final String propertyName, final Class elementType) {
+	public static <E> IObservableFactory<Object, IObservableSet<E>> setFactory(
+			final Realm realm, final String propertyName,
+			final Class<E> elementType) {
 		return PojoProperties.set(propertyName, elementType).setFactory(realm);
 	}
 
@@ -539,8 +611,8 @@
 	 * @return an observable set factory for creating observable sets
 	 * @since 1.2
 	 */
-	public static IObservableFactory setFactory(String propertyName,
-			Class elementType) {
+	public static <E> IObservableFactory<Object, IObservableSet<E>> setFactory(
+			String propertyName, Class<E> elementType) {
 		return setFactory(Realm.getDefault(), propertyName, elementType);
 	}
 
@@ -557,8 +629,8 @@
 	 *            the name of the property
 	 * @return a factory for creating {@link IObservableMap} objects.
 	 */
-	public static IObservableFactory mapPropertyFactory(final Realm realm,
-			final String propertyName) {
+	public static IObservableFactory<Object, IObservableMap<Object, Object>> mapPropertyFactory(
+			final Realm realm, final String propertyName) {
 		return PojoProperties.map(propertyName).mapFactory(realm);
 	}
 
@@ -573,7 +645,8 @@
 	 * @return a factory for creating {@link IObservableMap} objects.
 	 * @since 1.2
 	 */
-	public static IObservableFactory mapPropertyFactory(String propertyName) {
+	public static IObservableFactory<Object, IObservableMap<Object, Object>> mapPropertyFactory(
+			String propertyName) {
 		return mapPropertyFactory(Realm.getDefault(), propertyName);
 	}
 
@@ -596,15 +669,18 @@
 	 *             {@link #observeDetailValue(IObservableValue, String, Class)}
 	 *             instead
 	 */
-	public static IObservableValue observeDetailValue(Realm realm,
-			IObservableValue master, String propertyName, Class propertyType) {
+	public static <M, T> IObservableValue<T> observeDetailValue(Realm realm,
+			IObservableValue<M> master, String propertyName,
+			Class<T> propertyType) {
 		BeansObservables.warnIfDifferentRealms(realm, master.getRealm());
 
-		IObservableValue value = MasterDetailObservables.detailValue(master,
+		IObservableValue<T> value = MasterDetailObservables.detailValue(
+				master,
 				PojoProperties.value(propertyName, propertyType).valueFactory(
 						realm), propertyType);
-		return new BeanObservableValueDecorator(value, BeanPropertyHelper
-				.getValueTypePropertyDescriptor(master, propertyName));
+		return new BeanObservableValueDecorator<T>(value,
+				BeanPropertyHelper.getValueTypePropertyDescriptor(master,
+						propertyName));
 	}
 
 	/**
@@ -622,13 +698,11 @@
 	 * @see MasterDetailObservables
 	 * @since 1.2
 	 */
-	public static IObservableValue observeDetailValue(IObservableValue master,
-			String propertyName, Class propertyType) {
-		Class pojoClass = null;
-		if (master.getValueType() instanceof Class)
-			pojoClass = (Class) master.getValueType();
-		return PojoProperties.value(pojoClass, propertyName, propertyType)
-				.observeDetail(master);
+	public static <M, T> IObservableValue<T> observeDetailValue(
+			IObservableValue<M> master, String propertyName,
+			Class<T> propertyType) {
+		return PojoProperties.value(master.getValueClass(), propertyName,
+				propertyType).observeDetail(master);
 	}
 
 	/**
@@ -649,13 +723,14 @@
 	 *             {@link #observeDetailList(IObservableValue, String, Class)}
 	 *             instead
 	 */
-	public static IObservableList observeDetailList(Realm realm,
-			IObservableValue master, String propertyName, Class propertyType) {
+	public static <M, E> IObservableList<E> observeDetailList(Realm realm,
+			IObservableValue<M> master, String propertyName,
+			Class<E> propertyType) {
 		BeansObservables.warnIfDifferentRealms(realm, master.getRealm());
-		IObservableList observableList = MasterDetailObservables.detailList(
+		IObservableList<E> observableList = MasterDetailObservables.detailList(
 				master, PojoProperties.list(propertyName, propertyType)
 						.listFactory(realm), propertyType);
-		return new BeanObservableListDecorator(observableList,
+		return new BeanObservableListDecorator<E>(observableList,
 				BeanPropertyHelper.getValueTypePropertyDescriptor(master,
 						propertyName));
 	}
@@ -674,13 +749,11 @@
 	 * @see MasterDetailObservables
 	 * @since 1.2
 	 */
-	public static IObservableList observeDetailList(IObservableValue master,
-			String propertyName, Class propertyType) {
-		Class pojoClass = null;
-		if (master.getValueType() instanceof Class)
-			pojoClass = (Class) master.getValueType();
-		return PojoProperties.list(pojoClass, propertyName).observeDetail(
-				master);
+	public static <M, E> IObservableList<E> observeDetailList(
+			IObservableValue<M> master, String propertyName,
+			Class<E> propertyType) {
+		return PojoProperties.<M, E> list(master.getValueClass(), propertyName)
+				.observeDetail(master);
 	}
 
 	/**
@@ -701,15 +774,17 @@
 	 *             {@link #observeDetailSet(IObservableValue, String, Class)}
 	 *             instead.
 	 */
-	public static IObservableSet observeDetailSet(Realm realm,
-			IObservableValue master, String propertyName, Class propertyType) {
+	public static <M, E> IObservableSet<E> observeDetailSet(Realm realm,
+			IObservableValue<M> master, String propertyName,
+			Class<E> propertyType) {
 		BeansObservables.warnIfDifferentRealms(realm, master.getRealm());
 
-		IObservableSet observableSet = MasterDetailObservables.detailSet(
+		IObservableSet<E> observableSet = MasterDetailObservables.detailSet(
 				master, PojoProperties.set(propertyName, propertyType)
 						.setFactory(realm), propertyType);
-		return new BeanObservableSetDecorator(observableSet, BeanPropertyHelper
-				.getValueTypePropertyDescriptor(master, propertyName));
+		return new BeanObservableSetDecorator<E>(observableSet,
+				BeanPropertyHelper.getValueTypePropertyDescriptor(master,
+						propertyName));
 	}
 
 	/**
@@ -726,13 +801,11 @@
 	 * @see MasterDetailObservables
 	 * @since 1.2
 	 */
-	public static IObservableSet observeDetailSet(IObservableValue master,
-			String propertyName, Class propertyType) {
-		Class pojoClass = null;
-		if (master.getValueType() instanceof Class)
-			pojoClass = (Class) master.getValueType();
-		return PojoProperties.set(pojoClass, propertyName, propertyType)
-				.observeDetail(master);
+	public static <M, E> IObservableSet<E> observeDetailSet(
+			IObservableValue<M> master, String propertyName,
+			Class<E> propertyType) {
+		return PojoProperties.set(master.getValueClass(), propertyName,
+				propertyType).observeDetail(master);
 	}
 
 	/**
@@ -747,13 +820,15 @@
 	 * @deprecated Use {@link #observeDetailMap(IObservableValue, String)}
 	 *             instead
 	 */
-	public static IObservableMap observeDetailMap(Realm realm,
-			IObservableValue master, String propertyName) {
+	public static <M> IObservableMap<Object, Object> observeDetailMap(
+			Realm realm, IObservableValue<M> master, String propertyName) {
 		BeansObservables.warnIfDifferentRealms(realm, master.getRealm());
-		IObservableMap observableMap = MasterDetailObservables.detailMap(
-				master, PojoProperties.map(propertyName).mapFactory(realm));
-		return new BeanObservableMapDecorator(observableMap, BeanPropertyHelper
-				.getValueTypePropertyDescriptor(master, propertyName));
+		IObservableMap<Object, Object> observableMap = MasterDetailObservables
+				.<M, Object, Object> detailMap(master,
+						PojoProperties.<M> map(propertyName).mapFactory(realm));
+		return new BeanObservableMapDecorator<Object, Object>(observableMap,
+				BeanPropertyHelper.getValueTypePropertyDescriptor(master,
+						propertyName));
 	}
 
 	/**
@@ -766,12 +841,9 @@
 	 *         current value of the master observable value.
 	 * @since 1.2
 	 */
-	public static IObservableMap observeDetailMap(IObservableValue master,
-			String propertyName) {
-		Class pojoClass = null;
-		if (master.getValueType() instanceof Class)
-			pojoClass = (Class) master.getValueType();
-		return PojoProperties.map(pojoClass, propertyName)
+	public static <M> IObservableMap<Object, Object> observeDetailMap(
+			IObservableValue<M> master, String propertyName) {
+		return PojoProperties.map(master.getValueClass(), propertyName)
 				.observeDetail(master);
 	}
 }
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/PojoProperties.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/PojoProperties.java
index 90ccdf6..053dac9 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/PojoProperties.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/databinding/beans/PojoProperties.java
@@ -54,8 +54,23 @@
 	 * @return a value property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanValueProperty value(String propertyName) {
-		return value(null, propertyName, null);
+	public static IBeanValueProperty<Object, Object> value(String propertyName) {
+		String[] propertyNames = splitOffFirst(propertyName);
+
+		if (propertyNames.length == 1) {
+			return new PojoValuePropertyDecorator<Object, Object>(
+					new AnonymousPojoValueProperty<Object, Object>(
+							propertyNames[0], null), null);
+		}
+
+		IValueProperty<Object, Object> x = new AnonymousPojoValueProperty<Object, Object>(
+				propertyNames[0], Object.class);
+
+		IBeanValueProperty<Object, Object> remainder = value(propertyNames[1]);
+
+		IValueProperty<Object, Object> y = x.value(remainder);
+
+		return new PojoValuePropertyDecorator<Object, Object>(y, null);
 	}
 
 	/**
@@ -70,13 +85,37 @@
 	 * @return a value property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanValueProperty value(String propertyName, Class valueType) {
-		return value(null, propertyName, valueType);
+	public static <T> IBeanValueProperty<Object, T> value(String propertyName,
+			Class<T> valueType) {
+		String[] propertyNames = splitOffFirst(propertyName);
+
+		if (propertyNames.length == 1) {
+			return new PojoValuePropertyDecorator<Object, T>(
+					new AnonymousPojoValueProperty<Object, T>(propertyNames[0],
+							valueType), null);
+		}
+
+		IValueProperty<Object, Object> x = new AnonymousPojoValueProperty<Object, Object>(
+				propertyNames[0], Object.class);
+
+		IBeanValueProperty<Object, T> remainder = value(propertyNames[1],
+				valueType);
+
+		IValueProperty<Object, T> y = x.value(remainder);
+
+		return new PojoValuePropertyDecorator<Object, T>(y, null);
 	}
 
 	/**
 	 * Returns a value property for the given property name of the given bean
 	 * class.
+	 * <P>
+	 * The property must be available in the class given by the
+	 * <code>beanClass</code> parameter. For example suppose Foo is a class and
+	 * Bar extends Foo. There are methods getMyProperty and setMyProperty in Bar
+	 * but not in Foo. value(Foo.class, "myProperty") is called to get an
+	 * IValueProperty instance. The IValueProperty is then used to get the
+	 * property value from an object of type Bar. Null will always be returned.
 	 * 
 	 * @param beanClass
 	 *            the bean class
@@ -85,8 +124,40 @@
 	 * @return a value property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanValueProperty value(Class beanClass, String propertyName) {
-		return value(beanClass, propertyName, null);
+	public static <S> IBeanValueProperty<S, ?> value(Class<S> beanClass,
+			String propertyName) {
+		String[] propertyNames = splitOffFirst(propertyName);
+
+		if (beanClass == null) {
+			// beanClass cannot be null.
+			throw new IllegalArgumentException();
+		}
+
+		PropertyDescriptor propertyDescriptor = BeanPropertyHelper
+				.getPropertyDescriptor(beanClass, propertyNames[0]);
+
+		if (propertyNames.length == 1) {
+			/*
+			 * If a non-null valueType is provided by the caller then it must
+			 * match the actual property type. If no valueType is provided by
+			 * the caller then set it to the actual type from the property
+			 * descriptor.
+			 */
+			Class<?> valueType = propertyDescriptor.getPropertyType();
+
+			return valueUsingActualType(propertyDescriptor, valueType);
+		}
+
+		return valueGivenDescriptor(beanClass, propertyDescriptor,
+				propertyDescriptor.getPropertyType(), propertyNames[1]);
+	}
+
+	private static <S, T> IBeanValueProperty<S, T> valueUsingActualType(
+			PropertyDescriptor propertyDescriptor, Class<T> valueType) {
+		IValueProperty<S, T> property = new PojoValueProperty<S, T>(
+				propertyDescriptor, valueType);
+		return new PojoValuePropertyDecorator<S, T>(property,
+				propertyDescriptor);
 	}
 
 	/**
@@ -102,45 +173,137 @@
 	 * @return a value property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanValueProperty value(Class beanClass,
-			String propertyName, Class valueType) {
-		String[] propertyNames = split(propertyName);
-		if (propertyNames.length > 1)
-			valueType = null;
+	public static <S, T> IBeanValueProperty<S, T> value(
+			Class<? extends S> beanClass, String propertyName,
+			Class<T> valueType) {
+		String[] propertyNames = splitOffFirst(propertyName);
 
-		IValueProperty property;
-		PropertyDescriptor propertyDescriptor;
 		if (beanClass == null) {
-			propertyDescriptor = null;
-			property = new PojoValuePropertyDecorator(
-					new AnonymousPojoValueProperty(propertyNames[0], valueType),
-					null);
-		} else {
-			propertyDescriptor = BeanPropertyHelper.getPropertyDescriptor(
-					beanClass, propertyNames[0]);
-			property = new PojoValueProperty(propertyDescriptor, valueType);
+			// beanClass cannot be null.
+			throw new IllegalArgumentException();
+		}
+		if (valueType == null) {
+			// valueType cannot be null.
+			throw new IllegalArgumentException();
 		}
 
-		IBeanValueProperty beanProperty = new PojoValuePropertyDecorator(
-				property, propertyDescriptor);
-		for (int i = 1; i < propertyNames.length; i++) {
-			beanProperty = beanProperty.value(propertyNames[i]);
+		PropertyDescriptor propertyDescriptor = BeanPropertyHelper
+				.getPropertyDescriptor(beanClass, propertyNames[0]);
+
+		if (propertyNames.length == 1) {
+			IValueProperty<S, T> property = new PojoValueProperty<S, T>(
+					propertyDescriptor, valueType);
+			return new PojoValuePropertyDecorator<S, T>(property,
+					propertyDescriptor);
 		}
-		return beanProperty;
+
+		return valueGivenDescriptor(beanClass, propertyDescriptor,
+				propertyDescriptor.getPropertyType(), propertyNames[1],
+				valueType);
 	}
 
-	private static String[] split(String propertyName) {
-		if (propertyName.indexOf('.') == -1)
+	/**
+	 * This is a private method used by the above to recursively chain
+	 * IValueProperty objects when the bean property name has multiple parts
+	 * ("parent.child").
+	 * <P>
+	 * This method is given the property descriptor for the getter method that
+	 * gets one from the parent (class S) to the first level child (class I). It
+	 * then makes a recursive call to get the IValueProperty that gets from the
+	 * first level child to the final property (class T).
+	 * 
+	 * @param <S>
+	 *            type of the parent object, being the object that contains the
+	 *            property specified by propertyDescriptor
+	 * @param <I>
+	 *            type of the intermediate object, being the first level child
+	 *            object and being the property type of the property specified
+	 *            by propertyDescriptor
+	 * @param sourceBeanClass
+	 * @param propertyDescriptor
+	 * @param childBeanClass
+	 * @param propertyName
+	 *            the property name. May be nested e.g. "parent.name"
+	 * @return a value property that gets from S to T
+	 */
+	private static <S, I> IBeanValueProperty<S, ?> valueGivenDescriptor(
+			Class<? extends S> sourceBeanClass,
+			PropertyDescriptor propertyDescriptor, Class<I> childBeanClass,
+			String propertyName) {
+
+		IValueProperty<S, I> property = new PojoValueProperty<S, I>(
+				propertyDescriptor, childBeanClass);
+		IBeanValueProperty<S, I> decoratedProperty = new PojoValuePropertyDecorator<S, I>(
+				property, propertyDescriptor);
+
+		IBeanValueProperty<I, ?> remainder = value(childBeanClass, propertyName);
+
+		return decoratedProperty.value(remainder);
+	}
+
+	/**
+	 * This is a private method used by the above to recursively chain
+	 * IValueProperty objects when the bean property name has multiple parts
+	 * ("parent.child").
+	 * <P>
+	 * This method is given the property descriptor for the getter method that
+	 * gets one from the parent (class S) to the first level child (class I). It
+	 * then makes a recursive call to get the IValueProperty that gets from the
+	 * first level child to the final property (class T).
+	 * 
+	 * @param <S>
+	 *            type of the parent object, being the object that contains the
+	 *            property specified by propertyDescriptor
+	 * @param <I>
+	 *            type of the intermediate object, being the first level child
+	 *            object and being the property type of the property specified
+	 *            by propertyDescriptor
+	 * @param <T>
+	 *            expected type of the final child given
+	 * @param sourceBeanClass
+	 * @param propertyDescriptor
+	 * @param childBeanClass
+	 * @param propertyName
+	 *            the property name. May be nested e.g. "parent.name"
+	 * @param valueType
+	 *            the expected type of the final child property which may be
+	 *            null if the caller does not know the type in advance
+	 * @return a value property that gets from S to T
+	 */
+	private static <S, I, T> IBeanValueProperty<S, T> valueGivenDescriptor(
+			Class<? extends S> sourceBeanClass,
+			PropertyDescriptor propertyDescriptor, Class<I> childBeanClass,
+			String propertyName, Class<T> valueType) {
+
+		IValueProperty<S, I> property = new PojoValueProperty<S, I>(
+				propertyDescriptor, childBeanClass);
+		IBeanValueProperty<S, I> decoratedProperty = new PojoValuePropertyDecorator<S, I>(
+				property, propertyDescriptor);
+
+		IBeanValueProperty<I, T> remainder = value(childBeanClass,
+				propertyName, valueType);
+
+		return decoratedProperty.value(remainder);
+	}
+
+	/**
+	 * Splits off the first part of a property name. For example, if
+	 * "parent.child.child2" is passed in then { "parent", "child.child2" } is
+	 * returned.
+	 * 
+	 * @param propertyName
+	 *            the property name. May be nested e.g. "parent.name"
+	 * @return a String array with either one element if there is no 'dot' in
+	 *         the property name, or two elements split at the position of the
+	 *         first 'dot'
+	 */
+	private static String[] splitOffFirst(String propertyName) {
+		int index = propertyName.indexOf('.');
+		if (index == -1) {
 			return new String[] { propertyName };
-		List propertyNames = new ArrayList();
-		int index;
-		while ((index = propertyName.indexOf('.')) != -1) {
-			propertyNames.add(propertyName.substring(0, index));
-			propertyName = propertyName.substring(index + 1);
 		}
-		propertyNames.add(propertyName);
-		return (String[]) propertyNames
-				.toArray(new String[propertyNames.size()]);
+		return new String[] { propertyName.substring(0, index),
+				propertyName.substring(index + 1) };
 	}
 
 	/**
@@ -153,16 +316,38 @@
 	 *            array of property names. May be nested e.g. "parent.name"
 	 * @return a value property array for the given property names of the given
 	 *         bean class.
+	 * @deprecated use instead valuesAsList because that returns better typing
 	 */
-	public static IBeanValueProperty[] values(Class beanClass,
+	public static <S> IBeanValueProperty<?, ?>[] values(Class<S> beanClass,
 			String[] propertyNames) {
-		IBeanValueProperty[] properties = new IBeanValueProperty[propertyNames.length];
+		IBeanValueProperty<?, ?>[] properties = new IBeanValueProperty[propertyNames.length];
 		for (int i = 0; i < properties.length; i++)
 			properties[i] = value(beanClass, propertyNames[i], null);
 		return properties;
 	}
 
 	/**
+	 * Returns a value property array for the given property names of the given
+	 * bean class.
+	 * 
+	 * @param beanClass
+	 *            the bean class
+	 * @param propertyNames
+	 *            array of property names. May be nested e.g. "parent.name"
+	 * @return a value property array for the given property names of the given
+	 *         bean class.
+	 * @since 1.5
+	 */
+	public static <S> List<IBeanValueProperty<S, Object>> valuesAsList(
+			Class<S> beanClass, String[] propertyNames) {
+		List<IBeanValueProperty<S, Object>> properties = new ArrayList<IBeanValueProperty<S, Object>>(
+				propertyNames.length);
+		for (int i = 0; i < propertyNames.length; i++)
+			properties.add(value(beanClass, propertyNames[i], null));
+		return properties;
+	}
+
+	/**
 	 * Returns a value property array for the given property names of an
 	 * arbitrary bean class.
 	 * 
@@ -170,12 +355,28 @@
 	 *            array of property names. May be nested e.g. "parent.name"
 	 * @return a value property array for the given property names of the given
 	 *         bean class.
+	 * @deprecated use instead valuesAsList because that returns better typing
 	 */
-	public static IBeanValueProperty[] values(String[] propertyNames) {
+	public static IBeanValueProperty<?, ?>[] values(String[] propertyNames) {
 		return values(null, propertyNames);
 	}
 
 	/**
+	 * Returns a value property array for the given property names of an
+	 * arbitrary bean class.
+	 * 
+	 * @param propertyNames
+	 *            array of property names. May be nested e.g. "parent.name"
+	 * @return a value property array for the given property names of the given
+	 *         bean class.
+	 * @since 1.5
+	 */
+	public static <S> List<IBeanValueProperty<S, Object>> valuesAsList(
+			String[] propertyNames) {
+		return valuesAsList(null, propertyNames);
+	}
+
+	/**
 	 * Returns a set property for the given property name of an arbitrary bean
 	 * class. Objects lacking the named property are treated the same as if the
 	 * property always contains an empty set.
@@ -185,7 +386,7 @@
 	 * @return a set property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanSetProperty set(String propertyName) {
+	public static IBeanSetProperty<Object, Object> set(String propertyName) {
 		return set(null, propertyName, null);
 	}
 
@@ -201,7 +402,8 @@
 	 * @return a set property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanSetProperty set(String propertyName, Class elementType) {
+	public static <S, E> IBeanSetProperty<S, E> set(String propertyName,
+			Class<E> elementType) {
 		return set(null, propertyName, elementType);
 	}
 
@@ -216,7 +418,8 @@
 	 * @return a set property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanSetProperty set(Class beanClass, String propertyName) {
+	public static <S, E> IBeanSetProperty<S, E> set(Class<S> beanClass,
+			String propertyName) {
 		return set(beanClass, propertyName, null);
 	}
 
@@ -233,19 +436,22 @@
 	 * @return a set property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanSetProperty set(Class beanClass, String propertyName,
-			Class elementType) {
+	public static <S, E> IBeanSetProperty<S, E> set(
+			Class<? extends S> beanClass, String propertyName,
+			Class<E> elementType) {
 		PropertyDescriptor propertyDescriptor;
-		ISetProperty property;
+		ISetProperty<S, E> property;
 		if (beanClass == null) {
 			propertyDescriptor = null;
-			property = new AnonymousPojoSetProperty(propertyName, elementType);
+			property = new AnonymousPojoSetProperty<S, E>(propertyName,
+					elementType);
 		} else {
 			propertyDescriptor = BeanPropertyHelper.getPropertyDescriptor(
 					beanClass, propertyName);
-			property = new PojoSetProperty(propertyDescriptor, elementType);
+			property = new PojoSetProperty<S, E>(propertyDescriptor,
+					elementType);
 		}
-		return new PojoSetPropertyDecorator(property, propertyDescriptor);
+		return new PojoSetPropertyDecorator<S, E>(property, propertyDescriptor);
 	}
 
 	/**
@@ -258,7 +464,7 @@
 	 * @return a list property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanListProperty list(String propertyName) {
+	public static <E> IBeanListProperty<Object, E> list(String propertyName) {
 		return list(null, propertyName, null);
 	}
 
@@ -274,7 +480,8 @@
 	 * @return a list property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanListProperty list(String propertyName, Class elementType) {
+	public static <E> IBeanListProperty<Object, E> list(String propertyName,
+			Class<E> elementType) {
 		return list(null, propertyName, elementType);
 	}
 
@@ -289,7 +496,8 @@
 	 * @return a list property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanListProperty list(Class beanClass, String propertyName) {
+	public static <S, E> IBeanListProperty<S, E> list(Class<S> beanClass,
+			String propertyName) {
 		return list(beanClass, propertyName, null);
 	}
 
@@ -306,19 +514,22 @@
 	 * @return a list property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanListProperty list(Class beanClass, String propertyName,
-			Class elementType) {
+	public static <S, E> IBeanListProperty<S, E> list(
+			Class<? extends S> beanClass, String propertyName,
+			Class<E> elementType) {
 		PropertyDescriptor propertyDescriptor;
-		IListProperty property;
+		IListProperty<S, E> property;
 		if (beanClass == null) {
 			propertyDescriptor = null;
-			property = new AnonymousPojoListProperty(propertyName, elementType);
+			property = new AnonymousPojoListProperty<S, E>(propertyName,
+					elementType);
 		} else {
 			propertyDescriptor = BeanPropertyHelper.getPropertyDescriptor(
 					beanClass, propertyName);
-			property = new PojoListProperty(propertyDescriptor, elementType);
+			property = new PojoListProperty<S, E>(propertyDescriptor,
+					elementType);
 		}
-		return new PojoListPropertyDecorator(property, propertyDescriptor);
+		return new PojoListPropertyDecorator<S, E>(property, propertyDescriptor);
 	}
 
 	/**
@@ -331,7 +542,8 @@
 	 * @return a map property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanMapProperty map(String propertyName) {
+	public static <S> IBeanMapProperty<S, Object, Object> map(
+			String propertyName) {
 		return map(null, propertyName, null, null);
 	}
 
@@ -349,8 +561,8 @@
 	 * @return a map property for the given property name of an arbitrary bean
 	 *         class.
 	 */
-	public static IBeanMapProperty map(String propertyName, Class keyType,
-			Class valueType) {
+	public static <S, K, V> IBeanMapProperty<S, K, V> map(String propertyName,
+			Class<K> keyType, Class<V> valueType) {
 		return map(null, propertyName, keyType, valueType);
 	}
 
@@ -365,7 +577,8 @@
 	 * @return a map property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanMapProperty map(Class beanClass, String propertyName) {
+	public static <S, K, V> IBeanMapProperty<S, K, V> map(Class<S> beanClass,
+			String propertyName) {
 		return map(beanClass, propertyName, null, null);
 	}
 
@@ -384,20 +597,22 @@
 	 * @return a map property for the given property name of the given bean
 	 *         class.
 	 */
-	public static IBeanMapProperty map(Class beanClass, String propertyName,
-			Class keyType, Class valueType) {
+	public static <S, K, V> IBeanMapProperty<S, K, V> map(
+			Class<? extends S> beanClass, String propertyName,
+			Class<K> keyType, Class<V> valueType) {
 		PropertyDescriptor propertyDescriptor;
-		IMapProperty property;
+		IMapProperty<S, K, V> property;
 		if (beanClass == null) {
 			propertyDescriptor = null;
-			property = new AnonymousPojoMapProperty(propertyName, keyType,
-					valueType);
+			property = new AnonymousPojoMapProperty<S, K, V>(propertyName,
+					keyType, valueType);
 		} else {
 			propertyDescriptor = BeanPropertyHelper.getPropertyDescriptor(
 					beanClass, propertyName);
-			property = new PojoMapProperty(propertyDescriptor, keyType,
-					valueType);
+			property = new PojoMapProperty<S, K, V>(propertyDescriptor,
+					keyType, valueType);
 		}
-		return new PojoMapPropertyDecorator(property, propertyDescriptor);
+		return new PojoMapPropertyDecorator<S, K, V>(property,
+				propertyDescriptor);
 	}
 }
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanListProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanListProperty.java
index 3c81add..c90afd8 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanListProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanListProperty.java
@@ -20,33 +20,36 @@
 import org.eclipse.core.databinding.property.list.IListProperty;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class AnonymousBeanListProperty extends DelegatingListProperty {
+public class AnonymousBeanListProperty<S, E> extends
+		DelegatingListProperty<S, E> {
 	private final String propertyName;
 
-	private Map delegates;
+	private Map<Class<? extends S>, IListProperty<S, E>> delegates;
 
 	/**
 	 * @param propertyName
 	 * @param elementType
 	 */
-	public AnonymousBeanListProperty(String propertyName, Class elementType) {
+	public AnonymousBeanListProperty(String propertyName, Class<E> elementType) {
 		super(elementType);
 		this.propertyName = propertyName;
-		this.delegates = new HashMap();
+		this.delegates = new HashMap<Class<? extends S>, IListProperty<S, E>>();
 	}
 
-	protected IListProperty doGetDelegate(Object source) {
-		Class beanClass = source.getClass();
+	protected IListProperty<S, E> doGetDelegate(S source) {
+		Class<? extends S> beanClass = Util.getClass(source);
 		if (delegates.containsKey(beanClass))
-			return (IListProperty) delegates.get(beanClass);
+			return delegates.get(beanClass);
 
-		IListProperty delegate;
+		IListProperty<S, E> delegate;
 		try {
-			delegate = BeanProperties.list(beanClass, propertyName,
-					(Class) getElementType());
+			delegate = BeanProperties.<S, E> list(beanClass, propertyName,
+					getElementClass());
 		} catch (IllegalArgumentException noSuchProperty) {
 			delegate = null;
 		}
@@ -56,7 +59,7 @@
 
 	public String toString() {
 		String s = "?." + propertyName + "[]"; //$NON-NLS-1$ //$NON-NLS-2$
-		Class elementType = (Class) getElementType();
+		Class<E> elementType = getElementClass();
 		if (elementType != null)
 			s += "<" + BeanPropertyHelper.shortClassName(elementType) + ">"; //$NON-NLS-1$//$NON-NLS-2$
 		return s;
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanMapProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanMapProperty.java
index 06d8a52..60e9d07 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanMapProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanMapProperty.java
@@ -20,35 +20,39 @@
 import org.eclipse.core.databinding.property.map.IMapProperty;
 
 /**
+ * @param <S>
+ * @param <K>
+ * @param <V>
  * @since 3.3
  * 
  */
-public class AnonymousBeanMapProperty extends DelegatingMapProperty {
+public class AnonymousBeanMapProperty<S, K, V> extends
+		DelegatingMapProperty<S, K, V> {
 	private final String propertyName;
 
-	private Map delegates;
+	private Map<Class<? extends S>, IMapProperty<S, K, V>> delegates;
 
 	/**
 	 * @param propertyName
 	 * @param keyType
 	 * @param valueType
 	 */
-	public AnonymousBeanMapProperty(String propertyName, Class keyType,
-			Class valueType) {
+	public AnonymousBeanMapProperty(String propertyName, Class<K> keyType,
+			Class<V> valueType) {
 		super(keyType, valueType);
 		this.propertyName = propertyName;
-		this.delegates = new HashMap();
+		this.delegates = new HashMap<Class<? extends S>, IMapProperty<S, K, V>>();
 	}
 
-	protected IMapProperty doGetDelegate(Object source) {
-		Class beanClass = source.getClass();
+	protected IMapProperty<S, K, V> doGetDelegate(S source) {
+		Class<? extends S> beanClass = Util.getClass(source);
 		if (delegates.containsKey(beanClass))
-			return (IMapProperty) delegates.get(beanClass);
+			return delegates.get(beanClass);
 
-		IMapProperty delegate;
+		IMapProperty<S, K, V> delegate;
 		try {
 			delegate = BeanProperties.map(beanClass, propertyName,
-					(Class) getKeyType(), (Class) getValueType());
+					getKeyClass(), getValueClass());
 		} catch (IllegalArgumentException noSuchProperty) {
 			delegate = null;
 		}
@@ -58,8 +62,8 @@
 
 	public String toString() {
 		String s = "?." + propertyName + "{:}"; //$NON-NLS-1$ //$NON-NLS-2$
-		Class keyType = (Class) getKeyType();
-		Class valueType = (Class) getValueType();
+		Class<K> keyType = getKeyClass();
+		Class<V> valueType = getValueClass();
 		if (keyType != null || valueType != null) {
 			s += " <" + BeanPropertyHelper.shortClassName(keyType) + ", " //$NON-NLS-1$//$NON-NLS-2$
 					+ BeanPropertyHelper.shortClassName(valueType) + ">"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanSetProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanSetProperty.java
index 6ef3b48..a4940ba 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanSetProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanSetProperty.java
@@ -20,33 +20,35 @@
 import org.eclipse.core.databinding.property.set.ISetProperty;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class AnonymousBeanSetProperty extends DelegatingSetProperty {
+public class AnonymousBeanSetProperty<S, E> extends DelegatingSetProperty<S, E> {
 	private final String propertyName;
 
-	private Map delegates;
+	private Map<Class<? extends S>, ISetProperty<S, E>> delegates;
 
 	/**
 	 * @param propertyName
 	 * @param elementType
 	 */
-	public AnonymousBeanSetProperty(String propertyName, Class elementType) {
+	public AnonymousBeanSetProperty(String propertyName, Class<E> elementType) {
 		super(elementType);
 		this.propertyName = propertyName;
-		this.delegates = new HashMap();
+		this.delegates = new HashMap<Class<? extends S>, ISetProperty<S, E>>();
 	}
 
-	protected ISetProperty doGetDelegate(Object source) {
-		Class beanClass = source.getClass();
+	protected ISetProperty<S, E> doGetDelegate(S source) {
+		Class<? extends S> beanClass = Util.getClass(source);
 		if (delegates.containsKey(beanClass))
-			return (ISetProperty) delegates.get(beanClass);
+			return delegates.get(beanClass);
 
-		ISetProperty delegate;
+		ISetProperty<S, E> delegate;
 		try {
-			delegate = BeanProperties.set(beanClass, propertyName,
-					(Class) getElementType());
+			delegate = BeanProperties.<S, E> set(beanClass, propertyName,
+					getElementClass());
 		} catch (IllegalArgumentException noSuchProperty) {
 			delegate = null;
 		}
@@ -56,7 +58,7 @@
 
 	public String toString() {
 		String s = "?." + propertyName + "{}"; //$NON-NLS-1$ //$NON-NLS-2$
-		Class elementType = (Class) getElementType();
+		Class<E> elementType = getElementClass();
 		if (elementType != null)
 			s += "<" + BeanPropertyHelper.shortClassName(elementType) + ">"; //$NON-NLS-1$//$NON-NLS-2$
 		return s;
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanValueProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanValueProperty.java
index 38fd3b3..b9ec7dc 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanValueProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousBeanValueProperty.java
@@ -22,36 +22,40 @@
 import org.eclipse.core.databinding.property.value.IValueProperty;
 
 /**
+ * @param <S>
+ * @param <T>
  * @since 3.3
  * 
  */
-public class AnonymousBeanValueProperty extends DelegatingValueProperty {
+public class AnonymousBeanValueProperty<S, T> extends
+		DelegatingValueProperty<S, T> {
 	private final String propertyName;
 
-	private Map delegates;
+	private Map<Class<? extends S>, IValueProperty<S, T>> delegates;
 
 	/**
 	 * @param propertyName
 	 * @param valueType
 	 */
-	public AnonymousBeanValueProperty(String propertyName, Class valueType) {
+	public AnonymousBeanValueProperty(String propertyName, Class<T> valueType) {
 		super(valueType);
 		this.propertyName = propertyName;
-		this.delegates = new HashMap();
+		this.delegates = new HashMap<Class<? extends S>, IValueProperty<S, T>>();
 	}
 
-	protected IValueProperty doGetDelegate(Object source) {
-		return getClassDelegate(source.getClass());
+	protected IValueProperty<S, T> doGetDelegate(S source) {
+		Class<? extends S> beanClass = Util.getClass(source);
+		return getClassDelegate(beanClass);
 	}
 
-	private IValueProperty getClassDelegate(Class beanClass) {
+	private IValueProperty<S, T> getClassDelegate(Class<? extends S> beanClass) {
 		if (delegates.containsKey(beanClass))
-			return (IValueProperty) delegates.get(beanClass);
+			return delegates.get(beanClass);
 
-		IValueProperty delegate;
+		IValueProperty<S, T> delegate;
 		try {
-			delegate = BeanProperties.value(beanClass, propertyName,
-					(Class) getValueType());
+			delegate = BeanProperties.<S, T> value(beanClass, propertyName,
+					getValueClass());
 		} catch (IllegalArgumentException noSuchProperty) {
 			delegate = null;
 		}
@@ -59,25 +63,27 @@
 		return delegate;
 	}
 
-	public IObservableValue observeDetail(IObservableValue master) {
+	public <M extends S> IObservableValue<T> observeDetail(
+			IObservableValue<M> master) {
 		Object valueType = getValueType();
 		if (valueType == null)
 			valueType = inferValueType(master.getValueType());
-		return MasterDetailObservables.detailValue(master, valueFactory(master
-				.getRealm()), valueType);
+		return MasterDetailObservables.detailValue(master,
+				valueFactory(master.getRealm()), valueType);
 	}
 
 	private Object inferValueType(Object masterObservableValueType) {
 		if (masterObservableValueType instanceof Class) {
-			return getClassDelegate((Class) masterObservableValueType)
-					.getValueType();
+			return getClassDelegate(
+					(Class<? extends S>) masterObservableValueType)
+					.getValueClass();
 		}
 		return null;
 	}
 
 	public String toString() {
 		String s = "?." + propertyName; //$NON-NLS-1$
-		Class valueType = (Class) getValueType();
+		Class<T> valueType = getValueClass();
 		if (valueType != null)
 			s += "<" + BeanPropertyHelper.shortClassName(valueType) + ">"; //$NON-NLS-1$//$NON-NLS-2$
 		return s;
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoListProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoListProperty.java
index 9abc7df..ac817bb 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoListProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoListProperty.java
@@ -20,33 +20,36 @@
 import org.eclipse.core.databinding.property.list.IListProperty;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class AnonymousPojoListProperty extends DelegatingListProperty {
+public class AnonymousPojoListProperty<S, E> extends
+		DelegatingListProperty<S, E> {
 	private final String propertyName;
 
-	private Map delegates;
+	private Map<Class<? extends S>, IListProperty<S, E>> delegates;
 
 	/**
 	 * @param propertyName
 	 * @param elementType
 	 */
-	public AnonymousPojoListProperty(String propertyName, Class elementType) {
+	public AnonymousPojoListProperty(String propertyName, Class<E> elementType) {
 		super(elementType);
 		this.propertyName = propertyName;
-		this.delegates = new HashMap();
+		this.delegates = new HashMap<Class<? extends S>, IListProperty<S, E>>();
 	}
 
-	protected IListProperty doGetDelegate(Object source) {
-		Class beanClass = source.getClass();
+	protected IListProperty<S, E> doGetDelegate(S source) {
+		Class<? extends S> beanClass = Util.getClass(source);
 		if (delegates.containsKey(beanClass))
-			return (IListProperty) delegates.get(beanClass);
+			return delegates.get(beanClass);
 
-		IListProperty delegate;
+		IListProperty<S, E> delegate;
 		try {
-			delegate = PojoProperties.list(beanClass, propertyName,
-					(Class) getElementType());
+			delegate = PojoProperties.<S, E> list(beanClass, propertyName,
+					getElementClass());
 		} catch (IllegalArgumentException noSuchProperty) {
 			delegate = null;
 		}
@@ -56,7 +59,7 @@
 
 	public String toString() {
 		String s = "?." + propertyName + "{}"; //$NON-NLS-1$ //$NON-NLS-2$
-		Class elementType = (Class) getElementType();
+		Class<E> elementType = getElementClass();
 		if (elementType != null)
 			s += "<" + BeanPropertyHelper.shortClassName(elementType) + ">"; //$NON-NLS-1$//$NON-NLS-2$
 		return s;
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoMapProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoMapProperty.java
index 10ce37d..ea6528a 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoMapProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoMapProperty.java
@@ -20,35 +20,39 @@
 import org.eclipse.core.databinding.property.map.IMapProperty;
 
 /**
+ * @param <S>
+ * @param <K>
+ * @param <V>
  * @since 3.3
  * 
  */
-public class AnonymousPojoMapProperty extends DelegatingMapProperty {
+public class AnonymousPojoMapProperty<S, K, V> extends
+		DelegatingMapProperty<S, K, V> {
 	private final String propertyName;
 
-	private Map delegates;
+	private Map<Class<? extends S>, IMapProperty<S, K, V>> delegates;
 
 	/**
 	 * @param propertyName
 	 * @param keyType
 	 * @param valueType
 	 */
-	public AnonymousPojoMapProperty(String propertyName, Class keyType,
-			Class valueType) {
+	public AnonymousPojoMapProperty(String propertyName, Class<K> keyType,
+			Class<V> valueType) {
 		super(keyType, valueType);
 		this.propertyName = propertyName;
-		this.delegates = new HashMap();
+		this.delegates = new HashMap<Class<? extends S>, IMapProperty<S, K, V>>();
 	}
 
-	protected IMapProperty doGetDelegate(Object source) {
-		Class beanClass = source.getClass();
+	protected IMapProperty<S, K, V> doGetDelegate(S source) {
+		Class<? extends S> beanClass = Util.getClass(source);
 		if (delegates.containsKey(beanClass))
-			return (IMapProperty) delegates.get(beanClass);
+			return delegates.get(beanClass);
 
-		IMapProperty delegate;
+		IMapProperty<S, K, V> delegate;
 		try {
-			delegate = PojoProperties.map(beanClass, propertyName,
-					(Class) getKeyType(), (Class) getValueType());
+			delegate = PojoProperties.<S, K, V> map(beanClass, propertyName,
+					getKeyClass(), getValueClass());
 		} catch (IllegalArgumentException noSuchProperty) {
 			delegate = null;
 		}
@@ -58,8 +62,8 @@
 
 	public String toString() {
 		String s = "?." + propertyName + "{:}"; //$NON-NLS-1$ //$NON-NLS-2$
-		Class keyType = (Class) getKeyType();
-		Class valueType = (Class) getValueType();
+		Class<K> keyType = getKeyClass();
+		Class<V> valueType = getValueClass();
 		if (keyType != null || valueType != null) {
 			s += "<" + BeanPropertyHelper.shortClassName(keyType) + ", " //$NON-NLS-1$//$NON-NLS-2$
 					+ BeanPropertyHelper.shortClassName(valueType) + ">"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoSetProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoSetProperty.java
index 7f33181..d3d107a 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoSetProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoSetProperty.java
@@ -20,33 +20,35 @@
 import org.eclipse.core.databinding.property.set.ISetProperty;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class AnonymousPojoSetProperty extends DelegatingSetProperty {
+public class AnonymousPojoSetProperty<S, E> extends DelegatingSetProperty<S, E> {
 	private final String propertyName;
 
-	private Map delegates;
+	private Map<Class<? extends S>, ISetProperty<S, E>> delegates;
 
 	/**
 	 * @param propertyName
 	 * @param elementType
 	 */
-	public AnonymousPojoSetProperty(String propertyName, Class elementType) {
+	public AnonymousPojoSetProperty(String propertyName, Class<E> elementType) {
 		super(elementType);
 		this.propertyName = propertyName;
-		this.delegates = new HashMap();
+		this.delegates = new HashMap<Class<? extends S>, ISetProperty<S, E>>();
 	}
 
-	protected ISetProperty doGetDelegate(Object source) {
-		Class beanClass = source.getClass();
+	protected ISetProperty<S, E> doGetDelegate(S source) {
+		Class<? extends S> beanClass = Util.getClass(source);
 		if (delegates.containsKey(beanClass))
-			return (ISetProperty) delegates.get(beanClass);
+			return delegates.get(beanClass);
 
-		ISetProperty delegate;
+		ISetProperty<S, E> delegate;
 		try {
-			delegate = PojoProperties.set(beanClass, propertyName,
-					(Class) getElementType());
+			delegate = PojoProperties.<S, E> set(beanClass, propertyName,
+					getElementClass());
 		} catch (IllegalArgumentException noSuchProperty) {
 			delegate = null;
 		}
@@ -56,7 +58,7 @@
 
 	public String toString() {
 		String s = "?." + propertyName + "{}"; //$NON-NLS-1$ //$NON-NLS-2$
-		Class elementType = (Class) getElementType();
+		Class<?> elementType = getElementClass();
 		if (elementType != null)
 			s += "<" + BeanPropertyHelper.shortClassName(elementType) + ">"; //$NON-NLS-1$//$NON-NLS-2$
 		return s;
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoValueProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoValueProperty.java
index 2d55936..c89204a 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoValueProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/AnonymousPojoValueProperty.java
@@ -22,36 +22,40 @@
 import org.eclipse.core.databinding.property.value.IValueProperty;
 
 /**
+ * @param <S>
+ * @param <T>
  * @since 3.3
  * 
  */
-public class AnonymousPojoValueProperty extends DelegatingValueProperty {
+public class AnonymousPojoValueProperty<S, T> extends
+		DelegatingValueProperty<S, T> {
 	private final String propertyName;
 
-	private Map delegates;
+	private Map<Class<? extends S>, IValueProperty<S, T>> delegates;
 
 	/**
 	 * @param propertyName
 	 * @param valueType
 	 */
-	public AnonymousPojoValueProperty(String propertyName, Class valueType) {
+	public AnonymousPojoValueProperty(String propertyName, Class<T> valueType) {
 		super(valueType);
 		this.propertyName = propertyName;
-		this.delegates = new HashMap();
+		this.delegates = new HashMap<Class<? extends S>, IValueProperty<S, T>>();
 	}
 
-	protected IValueProperty doGetDelegate(Object source) {
-		return getClassDelegate(source.getClass());
+	protected IValueProperty<S, T> doGetDelegate(S source) {
+		Class<? extends S> beanClass = Util.getClass(source);
+		return getClassDelegate(beanClass);
 	}
 
-	private IValueProperty getClassDelegate(Class pojoClass) {
+	private IValueProperty<S, T> getClassDelegate(Class<? extends S> pojoClass) {
 		if (delegates.containsKey(pojoClass))
-			return (IValueProperty) delegates.get(pojoClass);
+			return delegates.get(pojoClass);
 
-		IValueProperty delegate;
+		IValueProperty<S, T> delegate;
 		try {
-			delegate = PojoProperties.value(pojoClass, propertyName,
-					(Class) getValueType());
+			delegate = PojoProperties.<S, T> value(pojoClass, propertyName,
+					getValueClass());
 		} catch (IllegalArgumentException noSuchProperty) {
 			delegate = null;
 		}
@@ -59,25 +63,26 @@
 		return delegate;
 	}
 
-	public IObservableValue observeDetail(IObservableValue master) {
+	public <M extends S> IObservableValue<T> observeDetail(
+			IObservableValue<M> master) {
 		Object valueType = getValueType();
 		if (valueType == null)
 			valueType = inferValueType(master.getValueType());
-		return MasterDetailObservables.detailValue(master, valueFactory(master
-				.getRealm()), valueType);
+		return MasterDetailObservables.detailValue(master,
+				valueFactory(master.getRealm()), valueType);
 	}
 
 	private Object inferValueType(Object masterObservableValueType) {
 		if (masterObservableValueType instanceof Class) {
 			return getClassDelegate((Class) masterObservableValueType)
-					.getValueType();
+					.getValueClass();
 		}
 		return null;
 	}
 
 	public String toString() {
 		String s = "?." + propertyName; //$NON-NLS-1$
-		Class valueType = (Class) getValueType();
+		Class<T> valueType = getValueClass();
 		if (valueType != null)
 			s += "<" + BeanPropertyHelper.shortClassName(valueType) + ">"; //$NON-NLS-1$//$NON-NLS-2$
 		return s;
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanListProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanListProperty.java
index 281891f..530bdef 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanListProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanListProperty.java
@@ -20,77 +20,105 @@
 import java.util.List;
 
 import org.eclipse.core.databinding.observable.Diffs;
-import org.eclipse.core.databinding.observable.IDiff;
 import org.eclipse.core.databinding.observable.list.ListDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.list.SimpleListProperty;
+import org.eclipse.core.databinding.util.Policy;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class BeanListProperty extends SimpleListProperty {
+public class BeanListProperty<S, E> extends SimpleListProperty<S, E> {
 	private final PropertyDescriptor propertyDescriptor;
-	private final Class elementType;
+	private final Class<E> elementType;
 
 	/**
 	 * @param propertyDescriptor
 	 * @param elementType
 	 */
 	public BeanListProperty(PropertyDescriptor propertyDescriptor,
-			Class elementType) {
+			Class<E> elementType) {
+		if (elementType == null) {
+			// elementType cannot be null.
+			// For legacy reasons, we allow this through but log it.
+			// Three cycles after Kepler this should be replaced by the
+			// exception (currently
+			// commented out) because it is not type safe.
+			// throw new IllegalArgumentException("elementType cannot be null."); //$NON-NLS-1$
+			Policy.getLog().log(
+					new Status(IStatus.WARNING, Policy.JFACE_DATABINDING,
+							"elementType cannot be null")); //$NON-NLS-1$
+
+			if (propertyDescriptor.getPropertyType().isArray()) {
+				elementType = (Class<E>) propertyDescriptor.getPropertyType()
+						.getComponentType();
+			} else {
+				elementType = (Class<E>) Object.class;
+			}
+		}
+
+		BeanPropertyHelper.checkCollectionPropertyElementType(
+				propertyDescriptor, elementType);
 		this.propertyDescriptor = propertyDescriptor;
-		this.elementType = elementType == null ? BeanPropertyHelper
-				.getCollectionPropertyElementType(propertyDescriptor)
-				: elementType;
+		this.elementType = elementType;
 	}
 
 	public Object getElementType() {
 		return elementType;
 	}
 
-	protected List doGetList(Object source) {
-		return asList(BeanPropertyHelper.readProperty(source,
+	public Class<E> getElementClass() {
+		return elementType;
+	}
+
+	protected List<E> doGetList(S source) {
+		return (List<E>) asList(BeanPropertyHelper.readProperty(source,
 				propertyDescriptor));
 	}
 
-	private List asList(Object propertyValue) {
+	private List<?> asList(Object propertyValue) {
 		if (propertyValue == null)
-			return Collections.EMPTY_LIST;
+			return Collections.emptyList();
 		if (propertyDescriptor.getPropertyType().isArray())
 			return Arrays.asList((Object[]) propertyValue);
-		return (List) propertyValue;
+		return (List<?>) propertyValue;
 	}
 
-	protected void doSetList(Object source, List list, ListDiff diff) {
+	protected void doSetList(S source, List<E> list, ListDiff<E> diff) {
 		doSetList(source, list);
 	}
 
-	protected void doSetList(Object source, List list) {
+	protected void doSetList(S source, List<E> list) {
 		BeanPropertyHelper.writeProperty(source, propertyDescriptor,
 				convertListToBeanPropertyType(list));
 	}
 
-	private Object convertListToBeanPropertyType(List list) {
+	private Object convertListToBeanPropertyType(List<E> list) {
 		Object propertyValue = list;
 		if (propertyDescriptor.getPropertyType().isArray()) {
-			Class componentType = propertyDescriptor.getPropertyType()
+			Class<?> componentType = propertyDescriptor.getPropertyType()
 					.getComponentType();
-			Object[] array = (Object[]) Array.newInstance(componentType, list
-					.size());
+			Object[] array = (Object[]) Array.newInstance(componentType,
+					list.size());
 			list.toArray(array);
 			propertyValue = array;
 		}
 		return propertyValue;
 	}
 
-	public INativePropertyListener adaptListener(
-			final ISimplePropertyListener listener) {
-		return new BeanPropertyListener(this, propertyDescriptor, listener) {
-			protected IDiff computeDiff(Object oldValue, Object newValue) {
-				return Diffs
-						.computeListDiff(asList(oldValue), asList(newValue));
+	public INativePropertyListener<S> adaptListener(
+			final ISimplePropertyListener<ListDiff<E>> listener) {
+		return new BeanPropertyListener<S, ListDiff<E>>(this,
+				propertyDescriptor, listener) {
+			protected ListDiff<E> computeDiff(Object oldValue, Object newValue) {
+				return Diffs.computeAndCastListDiff(asList(oldValue),
+						asList(newValue), elementType);
 			}
 		};
 	}
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanListPropertyDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanListPropertyDecorator.java
index d54bbdc..67a56ef 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanListPropertyDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanListPropertyDecorator.java
@@ -26,51 +26,61 @@
 import org.eclipse.core.databinding.property.list.ListProperty;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class BeanListPropertyDecorator extends ListProperty implements
-		IBeanListProperty {
-	private final IListProperty delegate;
+public class BeanListPropertyDecorator<S, E> extends ListProperty<S, E>
+		implements IBeanListProperty<S, E> {
+	private final IListProperty<S, E> delegate;
 	private final PropertyDescriptor propertyDescriptor;
 
 	/**
 	 * @param delegate
 	 * @param propertyDescriptor
 	 */
-	public BeanListPropertyDecorator(IListProperty delegate,
+	public BeanListPropertyDecorator(IListProperty<S, E> delegate,
 			PropertyDescriptor propertyDescriptor) {
 		this.delegate = delegate;
 		this.propertyDescriptor = propertyDescriptor;
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return delegate.getElementType();
 	}
 
-	protected List doGetList(Object source) {
+	public Class<E> getElementClass() {
+		return delegate.getElementClass();
+	}
+
+	protected List<E> doGetList(S source) {
 		return delegate.getList(source);
 	}
 
-	protected void doSetList(Object source, List list) {
+	protected void doSetList(S source, List<E> list) {
 		delegate.setList(source, list);
 	}
 
-	protected void doUpdateList(Object source, ListDiff diff) {
+	protected void doUpdateList(S source, ListDiff<E> diff) {
 		delegate.updateList(source, diff);
 	}
 
-	public IBeanListProperty values(String propertyName) {
+	public <V> IBeanListProperty<S, V> values(String propertyName) {
 		return values(propertyName, null);
 	}
 
-	public IBeanListProperty values(String propertyName, Class valueType) {
-		Class beanClass = (Class) delegate.getElementType();
+	public <V> IBeanListProperty<S, V> values(String propertyName,
+			Class<V> valueType) {
+		Class<E> beanClass = delegate.getElementClass();
 		return values(BeanProperties.value(beanClass, propertyName, valueType));
 	}
 
-	public IBeanListProperty values(IBeanValueProperty property) {
-		return new BeanListPropertyDecorator(super.values(property),
+	public <V> IBeanListProperty<S, V> values(IBeanValueProperty<E, V> property) {
+		return new BeanListPropertyDecorator<S, V>(super.values(property),
 				property.getPropertyDescriptor());
 	}
 
@@ -78,19 +88,20 @@
 		return propertyDescriptor;
 	}
 
-	public IObservableList observe(Object source) {
-		return new BeanObservableListDecorator(delegate.observe(source),
+	public IObservableList<E> observe(S source) {
+		return new BeanObservableListDecorator<E>(delegate.observe(source),
 				propertyDescriptor);
 	}
 
-	public IObservableList observe(Realm realm, Object source) {
-		return new BeanObservableListDecorator(delegate.observe(realm, source),
-				propertyDescriptor);
+	public IObservableList<E> observe(Realm realm, S source) {
+		return new BeanObservableListDecorator<E>(delegate.observe(realm,
+				source), propertyDescriptor);
 	}
 
-	public IObservableList observeDetail(IObservableValue master) {
-		return new BeanObservableListDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <M extends S> IObservableList<E> observeDetail(
+			IObservableValue<M> master) {
+		return new BeanObservableListDecorator<E>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanMapProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanMapProperty.java
index 99c247a..b5f0458 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanMapProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanMapProperty.java
@@ -17,20 +17,22 @@
 import java.util.Map;
 
 import org.eclipse.core.databinding.observable.Diffs;
-import org.eclipse.core.databinding.observable.IDiff;
 import org.eclipse.core.databinding.observable.map.MapDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.map.SimpleMapProperty;
 
 /**
+ * @param <S>
+ * @param <K>
+ * @param <V>
  * @since 3.3
  * 
  */
-public class BeanMapProperty extends SimpleMapProperty {
+public class BeanMapProperty<S, K, V> extends SimpleMapProperty<S, K, V> {
 	private final PropertyDescriptor propertyDescriptor;
-	private final Class keyType;
-	private final Class valueType;
+	private final Class<K> keyType;
+	private final Class<V> valueType;
 
 	/**
 	 * @param propertyDescriptor
@@ -38,7 +40,7 @@
 	 * @param valueType
 	 */
 	public BeanMapProperty(PropertyDescriptor propertyDescriptor,
-			Class keyType, Class valueType) {
+			Class<K> keyType, Class<V> valueType) {
 		this.propertyDescriptor = propertyDescriptor;
 		this.keyType = keyType;
 		this.valueType = valueType;
@@ -52,30 +54,40 @@
 		return valueType;
 	}
 
-	protected Map doGetMap(Object source) {
-		return asMap(BeanPropertyHelper
-				.readProperty(source, propertyDescriptor));
+	public Class<K> getKeyClass() {
+		return keyType;
 	}
 
-	private Map asMap(Object propertyValue) {
+	public Class<V> getValueClass() {
+		return valueType;
+	}
+
+	protected Map<K, V> doGetMap(S source) {
+		return (Map<K, V>) asMap(BeanPropertyHelper.readProperty(source,
+				propertyDescriptor));
+	}
+
+	private Map<?, ?> asMap(Object propertyValue) {
 		if (propertyValue == null)
-			return Collections.EMPTY_MAP;
-		return (Map) propertyValue;
+			return Collections.emptyMap();
+		return (Map<?, ?>) propertyValue;
 	}
 
-	protected void doSetMap(Object source, Map map, MapDiff diff) {
+	protected void doSetMap(S source, Map<K, V> map, MapDiff<K, V> diff) {
 		doSetMap(source, map);
 	}
 
-	protected void doSetMap(Object source, Map map) {
+	protected void doSetMap(S source, Map<K, V> map) {
 		BeanPropertyHelper.writeProperty(source, propertyDescriptor, map);
 	}
 
-	public INativePropertyListener adaptListener(
-			final ISimplePropertyListener listener) {
-		return new BeanPropertyListener(this, propertyDescriptor, listener) {
-			protected IDiff computeDiff(Object oldValue, Object newValue) {
-				return Diffs.computeMapDiff(asMap(oldValue), asMap(newValue));
+	public INativePropertyListener<S> adaptListener(
+			final ISimplePropertyListener<MapDiff<K, V>> listener) {
+		return new BeanPropertyListener<S, MapDiff<K, V>>(this,
+				propertyDescriptor, listener) {
+			protected MapDiff<K, V> computeDiff(Object oldValue, Object newValue) {
+				return Diffs.computeAndCastMapDiff(asMap(oldValue),
+						asMap(newValue), keyType, valueType);
 			}
 		};
 	}
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanMapPropertyDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanMapPropertyDecorator.java
index e7b47c2..6290c15 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanMapPropertyDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanMapPropertyDecorator.java
@@ -26,19 +26,22 @@
 import org.eclipse.core.databinding.property.map.MapProperty;
 
 /**
+ * @param <S>
+ * @param <K>
+ * @param <V>
  * @since 3.3
  * 
  */
-public class BeanMapPropertyDecorator extends MapProperty implements
-		IBeanMapProperty {
-	private final IMapProperty delegate;
+public class BeanMapPropertyDecorator<S, K, V> extends MapProperty<S, K, V>
+		implements IBeanMapProperty<S, K, V> {
+	private final IMapProperty<S, K, V> delegate;
 	private final PropertyDescriptor propertyDescriptor;
 
 	/**
 	 * @param delegate
 	 * @param propertyDescriptor
 	 */
-	public BeanMapPropertyDecorator(IMapProperty delegate,
+	public BeanMapPropertyDecorator(IMapProperty<S, K, V> delegate,
 			PropertyDescriptor propertyDescriptor) {
 		this.delegate = delegate;
 		this.propertyDescriptor = propertyDescriptor;
@@ -48,53 +51,70 @@
 		return propertyDescriptor;
 	}
 
+	/**
+	 * @deprecated use getKeyClass instead
+	 */
 	public Object getKeyType() {
 		return delegate.getKeyType();
 	}
 
+	/**
+	 * @deprecated use getValueClass instead
+	 */
 	public Object getValueType() {
 		return delegate.getValueType();
 	}
 
-	protected Map doGetMap(Object source) {
+	public Class<K> getKeyClass() {
+		return delegate.getKeyClass();
+	}
+
+	public Class<V> getValueClass() {
+		return delegate.getValueClass();
+	}
+
+	protected Map<K, V> doGetMap(S source) {
 		return delegate.getMap(source);
 	}
 
-	protected void doSetMap(Object source, Map map) {
+	protected void doSetMap(S source, Map<K, V> map) {
 		delegate.setMap(source, map);
 	}
 
-	protected void doUpdateMap(Object source, MapDiff diff) {
+	protected void doUpdateMap(S source, MapDiff<K, V> diff) {
 		delegate.updateMap(source, diff);
 	}
 
-	public IBeanMapProperty values(String propertyName) {
+	public <T> IBeanMapProperty<S, K, T> values(String propertyName) {
 		return values(propertyName, null);
 	}
 
-	public IBeanMapProperty values(String propertyName, Class valueType) {
-		Class beanClass = (Class) delegate.getValueType();
+	public <T> IBeanMapProperty<S, K, T> values(String propertyName,
+			Class<T> valueType) {
+		Class<V> beanClass = delegate.getValueClass();
 		return values(BeanProperties.value(beanClass, propertyName, valueType));
 	}
 
-	public IBeanMapProperty values(IBeanValueProperty property) {
-		return new BeanMapPropertyDecorator(super.values(property),
+	public <T> IBeanMapProperty<S, K, T> values(
+			IBeanValueProperty<V, T> property) {
+		return new BeanMapPropertyDecorator<S, K, T>(super.values(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IObservableMap observe(Object source) {
-		return new BeanObservableMapDecorator(delegate.observe(source),
+	public IObservableMap<K, V> observe(S source) {
+		return new BeanObservableMapDecorator<K, V>(delegate.observe(source),
 				propertyDescriptor);
 	}
 
-	public IObservableMap observe(Realm realm, Object source) {
-		return new BeanObservableMapDecorator(delegate.observe(realm, source),
-				propertyDescriptor);
+	public IObservableMap<K, V> observe(Realm realm, S source) {
+		return new BeanObservableMapDecorator<K, V>(delegate.observe(realm,
+				source), propertyDescriptor);
 	}
 
-	public IObservableMap observeDetail(IObservableValue master) {
-		return new BeanObservableMapDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <U extends S> IObservableMap<K, V> observeDetail(
+			IObservableValue<U> master) {
+		return new BeanObservableMapDecorator<K, V>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableListDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableListDecorator.java
index 672399a..75f0b78 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableListDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableListDecorator.java
@@ -23,9 +23,11 @@
 /**
  * {@link IBeanObservable} decorator for an {@link IObservableList}.
  * 
+ * @param <E>
+ * 
  * @since 3.3
  */
-public class BeanObservableListDecorator extends DecoratingObservableList
+public class BeanObservableListDecorator<E> extends DecoratingObservableList<E>
 		implements IBeanObservable {
 	private PropertyDescriptor propertyDescriptor;
 
@@ -33,7 +35,7 @@
 	 * @param decorated
 	 * @param propertyDescriptor
 	 */
-	public BeanObservableListDecorator(IObservableList decorated,
+	public BeanObservableListDecorator(IObservableList<E> decorated,
 			PropertyDescriptor propertyDescriptor) {
 		super(decorated, true);
 		this.propertyDescriptor = propertyDescriptor;
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableMapDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableMapDecorator.java
index f48d193..8911c6b 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableMapDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableMapDecorator.java
@@ -23,17 +23,20 @@
 /**
  * {@link IBeanObservable} decorator for an {@link IObservableMap}.
  * 
+ * @param <K>
+ * @param <V>
+ * 
  * @since 3.3
  */
-public class BeanObservableMapDecorator extends DecoratingObservableMap
-		implements IBeanObservable {
+public class BeanObservableMapDecorator<K, V> extends
+		DecoratingObservableMap<K, V> implements IBeanObservable {
 	private PropertyDescriptor propertyDescriptor;
 
 	/**
 	 * @param decorated
 	 * @param propertyDescriptor
 	 */
-	public BeanObservableMapDecorator(IObservableMap decorated,
+	public BeanObservableMapDecorator(IObservableMap<K, V> decorated,
 			PropertyDescriptor propertyDescriptor) {
 		super(decorated, true);
 		this.propertyDescriptor = propertyDescriptor;
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableSetDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableSetDecorator.java
index b560b5e..57f233c 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableSetDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableSetDecorator.java
@@ -23,9 +23,11 @@
 /**
  * {@link IBeanObservable} decorator for an {@link IObservableSet}.
  * 
+ * @param <E>
+ * 
  * @since 3.3
  */
-public class BeanObservableSetDecorator extends DecoratingObservableSet
+public class BeanObservableSetDecorator<E> extends DecoratingObservableSet<E>
 		implements IBeanObservable {
 	private PropertyDescriptor propertyDescriptor;
 
@@ -33,7 +35,7 @@
 	 * @param decorated
 	 * @param propertyDescriptor
 	 */
-	public BeanObservableSetDecorator(IObservableSet decorated,
+	public BeanObservableSetDecorator(IObservableSet<E> decorated,
 			PropertyDescriptor propertyDescriptor) {
 		super(decorated, true);
 		this.propertyDescriptor = propertyDescriptor;
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableValueDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableValueDecorator.java
index e8e2b2f..169d714 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableValueDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanObservableValueDecorator.java
@@ -23,17 +23,19 @@
 /**
  * {@link IBeanObservable} decorator for an {@link IObservableValue}.
  * 
+ * @param <T>
+ * 
  * @since 3.3
  */
-public class BeanObservableValueDecorator extends DecoratingObservableValue
-		implements IBeanObservable {
+public class BeanObservableValueDecorator<T> extends
+		DecoratingObservableValue<T> implements IBeanObservable {
 	private PropertyDescriptor propertyDescriptor;
 
 	/**
 	 * @param decorated
 	 * @param propertyDescriptor
 	 */
-	public BeanObservableValueDecorator(IObservableValue decorated,
+	public BeanObservableValueDecorator(IObservableValue<T> decorated,
 			PropertyDescriptor propertyDescriptor) {
 		super(decorated, true);
 		this.propertyDescriptor = propertyDescriptor;
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyHelper.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyHelper.java
index 83d1ebf..ed8436d 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyHelper.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyHelper.java
@@ -21,8 +21,9 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
-import org.eclipse.core.databinding.beans.BeansObservables;
+import org.eclipse.core.databinding.beans.BeanProperties;
 import org.eclipse.core.databinding.observable.value.IObservableValue;
 import org.eclipse.core.databinding.util.Policy;
 import org.eclipse.core.runtime.IStatus;
@@ -64,15 +65,13 @@
 			 */
 			throw new RuntimeException(e.getCause());
 		} catch (Exception e) {
-			if (BeansObservables.DEBUG) {
-				Policy
-						.getLog()
-						.log(
-								new Status(
-										IStatus.WARNING,
-										Policy.JFACE_DATABINDING,
-										IStatus.OK,
-										"Could not change value of " + source + "." + propertyDescriptor.getName(), e)); //$NON-NLS-1$ //$NON-NLS-2$
+			if (BeanProperties.DEBUG) {
+				Policy.getLog()
+						.log(new Status(
+								IStatus.WARNING,
+								Policy.JFACE_DATABINDING,
+								IStatus.OK,
+								"Could not change value of " + source + "." + propertyDescriptor.getName(), e)); //$NON-NLS-1$ //$NON-NLS-2$
 			}
 		}
 	}
@@ -97,7 +96,7 @@
 			if (!readMethod.isAccessible()) {
 				readMethod.setAccessible(true);
 			}
-			return readMethod.invoke(source, null);
+			return readMethod.invoke(source, (Object[]) null);
 		} catch (InvocationTargetException e) {
 			/*
 			 * InvocationTargetException wraps any exception thrown by the
@@ -105,15 +104,13 @@
 			 */
 			throw new RuntimeException(e.getCause());
 		} catch (Exception e) {
-			if (BeansObservables.DEBUG) {
-				Policy
-						.getLog()
-						.log(
-								new Status(
-										IStatus.WARNING,
-										Policy.JFACE_DATABINDING,
-										IStatus.OK,
-										"Could not read value of " + source + "." + propertyDescriptor.getName(), e)); //$NON-NLS-1$ //$NON-NLS-2$
+			if (BeanProperties.DEBUG) {
+				Policy.getLog()
+						.log(new Status(
+								IStatus.WARNING,
+								Policy.JFACE_DATABINDING,
+								IStatus.OK,
+								"Could not read value of " + source + "." + propertyDescriptor.getName(), e)); //$NON-NLS-1$ //$NON-NLS-2$
 			}
 			return null;
 		}
@@ -125,14 +122,40 @@
 	 * 
 	 * @param descriptor
 	 *            the property being inspected
-	 * @return the element type of the given collection-typed property if it is
-	 *         an array property, or Object.class otherwise.
+	 * @param elementType
+	 * @throws IllegalArgumentException
+	 *             if the information in the property descriptor is not
+	 *             consistent with the given element type
 	 */
-	public static Class getCollectionPropertyElementType(
-			PropertyDescriptor descriptor) {
-		Class propertyType = descriptor.getPropertyType();
-		return propertyType.isArray() ? propertyType.getComponentType()
-				: Object.class;
+	public static void checkCollectionPropertyElementType(
+			PropertyDescriptor descriptor, Class<?> elementType) {
+		Class<?> propertyType = descriptor.getPropertyType();
+		if (propertyType.isArray()) {
+			if (propertyType.getComponentType() != elementType) {
+				/*
+				 * Probably these should be expected to match. However the test
+				 * cases use an Object array for all tests but then pass in some
+				 * other class as the class of elements in the array. There may
+				 * be users who do this, so as long is the given element type is
+				 * derived from the actual element type then we only print a
+				 * warning.
+				 */
+				if (propertyType.getComponentType().isAssignableFrom(
+						elementType)) {
+					Policy.getLog()
+							.log(new Status(
+									IStatus.WARNING,
+									Policy.JFACE_DATABINDING,
+									"elementType (" + elementType.getName() + ") does not match the actual type of elements in the array property (" + propertyType.getComponentType().getName() + ").")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				} else {
+					throw new IllegalArgumentException(
+							"elementType (" + elementType.getName() + ") does not match the actual type of elements in the array property (" + propertyType.getComponentType().getName() + ")."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				}
+			}
+		} else if (propertyType != Set.class && propertyType != List.class) {
+			throw new IllegalArgumentException(
+					"bean property is not array, Set, or List."); //$NON-NLS-1$
+		}
 	}
 
 	/**
@@ -141,7 +164,7 @@
 	 * @return the PropertyDescriptor for the named property on the given bean
 	 *         class
 	 */
-	public static PropertyDescriptor getPropertyDescriptor(Class beanClass,
+	public static PropertyDescriptor getPropertyDescriptor(Class<?> beanClass,
 			String propertyName) {
 		if (!beanClass.isInterface()) {
 			BeanInfo beanInfo;
@@ -162,10 +185,10 @@
 		} else {
 			try {
 				PropertyDescriptor propertyDescriptors[];
-				List pds = new ArrayList();
+				List<PropertyDescriptor> pds = new ArrayList<PropertyDescriptor>();
 				getInterfacePropertyDescriptors(pds, beanClass);
 				if (pds.size() > 0) {
-					propertyDescriptors = (PropertyDescriptor[]) pds
+					propertyDescriptors = pds
 							.toArray(new PropertyDescriptor[pds.size()]);
 					PropertyDescriptor descriptor;
 					for (int i = 0; i < propertyDescriptors.length; i++) {
@@ -195,7 +218,7 @@
 	 * @throws IntrospectionException
 	 */
 	private static void getInterfacePropertyDescriptors(
-			List propertyDescriptors, Class iface)
+			List<PropertyDescriptor> propertyDescriptors, Class<?> iface)
 			throws IntrospectionException {
 		BeanInfo beanInfo = Introspector.getBeanInfo(iface);
 		PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
@@ -203,7 +226,7 @@
 			PropertyDescriptor pd = pds[i];
 			propertyDescriptors.add(pd);
 		}
-		Class[] subIntfs = iface.getInterfaces();
+		Class<?>[] subIntfs = iface.getInterfaces();
 		for (int j = 0; j < subIntfs.length; j++) {
 			getInterfacePropertyDescriptors(propertyDescriptors, subIntfs[j]);
 		}
@@ -215,9 +238,9 @@
 	 * @return property descriptor or <code>null</code>
 	 */
 	/* package */public static PropertyDescriptor getValueTypePropertyDescriptor(
-			IObservableValue observable, String propertyName) {
+			IObservableValue<?> observable, String propertyName) {
 		if (observable.getValueType() != null)
-			return getPropertyDescriptor((Class) observable.getValueType(),
+			return getPropertyDescriptor((Class<?>) observable.getValueType(),
 					propertyName);
 		return null;
 	}
@@ -227,7 +250,7 @@
 	 * @return String description of property descriptor
 	 */
 	public static String propertyName(PropertyDescriptor propertyDescriptor) {
-		Class beanClass = propertyDescriptor.getReadMethod()
+		Class<?> beanClass = propertyDescriptor.getReadMethod()
 				.getDeclaringClass();
 		return shortClassName(beanClass)
 				+ "." + propertyDescriptor.getName() + ""; //$NON-NLS-1$ //$NON-NLS-2$
@@ -237,7 +260,7 @@
 	 * @param beanClass
 	 * @return class name excluding package
 	 */
-	public static String shortClassName(Class beanClass) {
+	public static String shortClassName(Class<?> beanClass) {
 		if (beanClass == null)
 			return "?"; //$NON-NLS-1$
 		String className = beanClass.getName();
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyListener.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyListener.java
index 01b3275..d867b41 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyListener.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyListener.java
@@ -21,16 +21,18 @@
 import org.eclipse.core.databinding.property.NativePropertyListener;
 
 /**
+ * @param <S>
+ * @param <D>
  * @since 3.3
  * 
  */
-public abstract class BeanPropertyListener extends NativePropertyListener
-		implements PropertyChangeListener {
+public abstract class BeanPropertyListener<S, D extends IDiff> extends
+		NativePropertyListener<S, D> implements PropertyChangeListener {
 	private final PropertyDescriptor propertyDescriptor;
 
 	protected BeanPropertyListener(IProperty property,
 			PropertyDescriptor propertyDescriptor,
-			ISimplePropertyListener listener) {
+			ISimplePropertyListener<D> listener) {
 		super(property, listener);
 		this.propertyDescriptor = propertyDescriptor;
 	}
@@ -40,7 +42,7 @@
 				|| propertyDescriptor.getName().equals(evt.getPropertyName())) {
 			Object oldValue = evt.getOldValue();
 			Object newValue = evt.getNewValue();
-			IDiff diff;
+			D diff;
 			if (evt.getPropertyName() == null || oldValue == null
 					|| newValue == null)
 				diff = null;
@@ -50,15 +52,15 @@
 		}
 	}
 
-	protected abstract IDiff computeDiff(Object oldValue, Object newValue);
+	protected abstract D computeDiff(Object oldValue, Object newValue);
 
 	protected void doAddTo(Object source) {
-		BeanPropertyListenerSupport.hookListener(source, propertyDescriptor
-				.getName(), this);
+		BeanPropertyListenerSupport.hookListener(source,
+				propertyDescriptor.getName(), this);
 	}
 
 	protected void doRemoveFrom(Object source) {
-		BeanPropertyListenerSupport.unhookListener(source, propertyDescriptor
-				.getName(), this);
+		BeanPropertyListenerSupport.unhookListener(source,
+				propertyDescriptor.getName(), this);
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyListenerSupport.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyListenerSupport.java
index 23975db..274f305 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyListenerSupport.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanPropertyListenerSupport.java
@@ -15,7 +15,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
-import org.eclipse.core.databinding.beans.BeansObservables;
+import org.eclipse.core.databinding.beans.BeanProperties;
 import org.eclipse.core.databinding.util.Policy;
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.IStatus;
@@ -126,7 +126,7 @@
 	 * Logs a message to the Data Binding logger.
 	 */
 	private static void log(int severity, String message, Throwable throwable) {
-		if (BeansObservables.DEBUG) {
+		if (BeanProperties.DEBUG) {
 			Policy.getLog().log(
 					new Status(severity, Policy.JFACE_DATABINDING, IStatus.OK,
 							message, throwable));
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanSetProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanSetProperty.java
index 50714cb..7fecf8d 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanSetProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanSetProperty.java
@@ -20,75 +20,110 @@
 import java.util.Set;
 
 import org.eclipse.core.databinding.observable.Diffs;
-import org.eclipse.core.databinding.observable.IDiff;
 import org.eclipse.core.databinding.observable.set.SetDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.set.SimpleSetProperty;
+import org.eclipse.core.databinding.util.Policy;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class BeanSetProperty extends SimpleSetProperty {
+public class BeanSetProperty<S, E> extends SimpleSetProperty<S, E> {
 	private final PropertyDescriptor propertyDescriptor;
-	private final Class elementType;
+	private final Class<E> elementType;
 
 	/**
 	 * @param propertyDescriptor
 	 * @param elementType
 	 */
 	public BeanSetProperty(PropertyDescriptor propertyDescriptor,
-			Class elementType) {
+			Class<E> elementType) {
+		if (elementType == null) {
+			// elementType cannot be null.
+			// For legacy reasons, we allow this through but log it.
+			// Three cycles after Kepler this should be replaced by the
+			// exception (currently
+			// commented out) because it is not type safe.
+			// throw new IllegalArgumentException("elementType cannot be null."); //$NON-NLS-1$
+			Policy.getLog().log(
+					new Status(IStatus.WARNING, Policy.JFACE_DATABINDING,
+							"elementType cannot be null")); //$NON-NLS-1$
+
+			if (propertyDescriptor.getPropertyType().isArray()) {
+				elementType = (Class<E>) propertyDescriptor.getPropertyType()
+						.getComponentType();
+			} else {
+				elementType = (Class<E>) Object.class;
+			}
+		}
+
+		BeanPropertyHelper.checkCollectionPropertyElementType(
+				propertyDescriptor, elementType);
 		this.propertyDescriptor = propertyDescriptor;
-		this.elementType = elementType == null ? BeanPropertyHelper
-				.getCollectionPropertyElementType(propertyDescriptor)
-				: elementType;
+		this.elementType = elementType;
 	}
 
 	public Object getElementType() {
 		return elementType;
 	}
 
-	protected Set doGetSet(Object source) {
+	public Class<E> getElementClass() {
+		return elementType;
+	}
+
+	protected Set<E> doGetSet(S source) {
 		return asSet(BeanPropertyHelper
 				.readProperty(source, propertyDescriptor));
 	}
 
-	private Set asSet(Object propertyValue) {
-		if (propertyValue == null)
-			return Collections.EMPTY_SET;
-		if (propertyDescriptor.getPropertyType().isArray())
-			return new HashSet(Arrays.asList((Object[]) propertyValue));
-		return (Set) propertyValue;
+	private Set<E> asSet(Object propertyValue) {
+		if (propertyValue == null) {
+			return Collections.emptySet();
+		}
+		if (propertyDescriptor.getPropertyType().isArray()) {
+			Set<E> result = new HashSet<E>();
+			for (Object element : Arrays.asList((Object[]) propertyValue)) {
+				result.add(elementType.cast(element));
+			}
+			return result;
+		}
+		return new TypedSet<E>(((Set<?>) propertyValue), elementType);
 	}
 
-	protected void doSetSet(Object source, Set set, SetDiff diff) {
+	protected void doSetSet(S source, Set<E> set, SetDiff<E> diff) {
 		doSetSet(source, set);
 	}
 
-	protected void doSetSet(Object source, Set set) {
+	protected void doSetSet(S source, Set<E> set) {
 		BeanPropertyHelper.writeProperty(source, propertyDescriptor,
 				convertSetToBeanPropertyType(set));
 	}
 
-	private Object convertSetToBeanPropertyType(Set set) {
+	private Object convertSetToBeanPropertyType(Set<E> set) {
 		Object propertyValue = set;
 		if (propertyDescriptor.getPropertyType().isArray()) {
-			Class componentType = propertyDescriptor.getPropertyType()
+			Class<?> componentType = propertyDescriptor.getPropertyType()
 					.getComponentType();
-			Object[] array = (Object[]) Array.newInstance(componentType, set
-					.size());
+			Object[] array = (Object[]) Array.newInstance(componentType,
+					set.size());
 			propertyValue = set.toArray(array);
 		}
 		return propertyValue;
 	}
 
-	public INativePropertyListener adaptListener(
-			final ISimplePropertyListener listener) {
-		return new BeanPropertyListener(this, propertyDescriptor, listener) {
-			protected IDiff computeDiff(Object oldValue, Object newValue) {
-				return Diffs.computeSetDiff(asSet(oldValue), asSet(newValue));
+	public INativePropertyListener<S> adaptListener(
+			final ISimplePropertyListener<SetDiff<E>> listener) {
+		return new BeanPropertyListener<S, SetDiff<E>>(this,
+				propertyDescriptor, listener) {
+			protected SetDiff<E> computeDiff(Object oldValue, Object newValue) {
+				return Diffs.computeAndCastSetDiff(asSet(oldValue),
+						asSet(newValue), elementType);
 			}
 		};
 	}
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanSetPropertyDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanSetPropertyDecorator.java
index 3b52f7c..9177748 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanSetPropertyDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanSetPropertyDecorator.java
@@ -27,19 +27,21 @@
 import org.eclipse.core.databinding.property.set.SetProperty;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class BeanSetPropertyDecorator extends SetProperty implements
-		IBeanSetProperty {
-	private final ISetProperty delegate;
+public class BeanSetPropertyDecorator<S, E> extends SetProperty<S, E> implements
+		IBeanSetProperty<S, E> {
+	private final ISetProperty<S, E> delegate;
 	private final PropertyDescriptor propertyDescriptor;
 
 	/**
 	 * @param delegate
 	 * @param propertyDescriptor
 	 */
-	public BeanSetPropertyDecorator(ISetProperty delegate,
+	public BeanSetPropertyDecorator(ISetProperty<S, E> delegate,
 			PropertyDescriptor propertyDescriptor) {
 		this.delegate = delegate;
 		this.propertyDescriptor = propertyDescriptor;
@@ -49,49 +51,59 @@
 		return propertyDescriptor;
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return delegate.getElementType();
 	}
 
-	protected Set doGetSet(Object source) {
+	public Class<E> getElementClass() {
+		return delegate.getElementClass();
+	}
+
+	protected Set<E> doGetSet(S source) {
 		return delegate.getSet(source);
 	}
 
-	protected void doSetSet(Object source, Set set) {
+	protected void doSetSet(S source, Set<E> set) {
 		delegate.setSet(source, set);
 	}
 
-	protected void doUpdateSet(Object source, SetDiff diff) {
+	protected void doUpdateSet(S source, SetDiff<E> diff) {
 		delegate.updateSet(source, diff);
 	}
 
-	public IBeanMapProperty values(String propertyName) {
+	public <T> IBeanMapProperty<S, E, T> values(String propertyName) {
 		return values(propertyName, null);
 	}
 
-	public IBeanMapProperty values(String propertyName, Class valueType) {
-		Class beanClass = (Class) delegate.getElementType();
+	public <T> IBeanMapProperty<S, E, T> values(String propertyName,
+			Class<T> valueType) {
+		Class<E> beanClass = delegate.getElementClass();
 		return values(BeanProperties.value(beanClass, propertyName, valueType));
 	}
 
-	public IBeanMapProperty values(IBeanValueProperty property) {
-		return new BeanMapPropertyDecorator(super.values(property),
+	public <T> IBeanMapProperty<S, E, T> values(
+			IBeanValueProperty<E, T> property) {
+		return new BeanMapPropertyDecorator<S, E, T>(super.values(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IObservableSet observe(Object source) {
-		return new BeanObservableSetDecorator(delegate.observe(source),
+	public IObservableSet<E> observe(S source) {
+		return new BeanObservableSetDecorator<E>(delegate.observe(source),
 				propertyDescriptor);
 	}
 
-	public IObservableSet observe(Realm realm, Object source) {
-		return new BeanObservableSetDecorator(delegate.observe(realm, source),
-				propertyDescriptor);
+	public IObservableSet<E> observe(Realm realm, S source) {
+		return new BeanObservableSetDecorator<E>(
+				delegate.observe(realm, source), propertyDescriptor);
 	}
 
-	public IObservableSet observeDetail(IObservableValue master) {
-		return new BeanObservableSetDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <M extends S> IObservableSet<E> observeDetail(
+			IObservableValue<M> master) {
+		return new BeanObservableSetDecorator<E>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanValueProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanValueProperty.java
index 85e6c97..3d8f108 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanValueProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanValueProperty.java
@@ -15,47 +15,65 @@
 import java.beans.PropertyDescriptor;
 
 import org.eclipse.core.databinding.observable.Diffs;
-import org.eclipse.core.databinding.observable.IDiff;
+import org.eclipse.core.databinding.observable.value.ValueDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.value.SimpleValueProperty;
 
 /**
+ * @param <S>
+ * @param <T>
  * @since 3.3
  * 
  */
-public class BeanValueProperty extends SimpleValueProperty {
+public class BeanValueProperty<S, T> extends SimpleValueProperty<S, T> {
 	private final PropertyDescriptor propertyDescriptor;
-	private final Class valueType;
+	private final Class<T> valueType;
 
 	/**
 	 * @param propertyDescriptor
 	 * @param valueType
 	 */
 	public BeanValueProperty(PropertyDescriptor propertyDescriptor,
-			Class valueType) {
+			Class<T> valueType) {
+		if (valueType == null) {
+			throw new IllegalArgumentException("valueType cannot be null."); //$NON-NLS-1$
+		}
+		Class<?> propertyType = propertyDescriptor.getPropertyType();
+		propertyType = Util.convertToObjectClass(propertyType);
+		if (valueType != propertyType) {
+			throw new IllegalArgumentException(
+					"valueType does not match the actual property type."); //$NON-NLS-1$
+		}
 		this.propertyDescriptor = propertyDescriptor;
-		this.valueType = valueType == null ? propertyDescriptor
-				.getPropertyType() : valueType;
+		this.valueType = valueType;
 	}
 
-	public Object getValueType() {
+	public Class<T> getValueType() {
 		return valueType;
 	}
 
-	protected Object doGetValue(Object source) {
-		return BeanPropertyHelper.readProperty(source, propertyDescriptor);
+	public Class<T> getValueClass() {
+		return valueType;
 	}
 
-	protected void doSetValue(Object source, Object value) {
+	protected T doGetValue(S source) {
+		Object value = BeanPropertyHelper.readProperty(source,
+				propertyDescriptor);
+		return valueType.cast(value);
+	}
+
+	protected void doSetValue(S source, T value) {
 		BeanPropertyHelper.writeProperty(source, propertyDescriptor, value);
 	}
 
-	public INativePropertyListener adaptListener(
-			final ISimplePropertyListener listener) {
-		return new BeanPropertyListener(this, propertyDescriptor, listener) {
-			protected IDiff computeDiff(Object oldValue, Object newValue) {
-				return Diffs.createValueDiff(oldValue, newValue);
+	public INativePropertyListener<S> adaptListener(
+			final ISimplePropertyListener<ValueDiff<T>> listener) {
+		return new BeanPropertyListener<S, ValueDiff<T>>(this,
+				propertyDescriptor, listener) {
+			protected ValueDiff<T> computeDiff(Object oldValue, Object newValue) {
+				return Diffs.createValueDiff(valueType.cast(oldValue),
+						valueType.cast(newValue));
 			}
 		};
 	}
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanValuePropertyDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanValuePropertyDecorator.java
index 034afba..0473390 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanValuePropertyDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/BeanValuePropertyDecorator.java
@@ -28,19 +28,21 @@
 import org.eclipse.core.databinding.property.value.ValueProperty;
 
 /**
+ * @param <S>
+ * @param <T>
  * @since 3.3
  * 
  */
-public class BeanValuePropertyDecorator extends ValueProperty implements
-		IBeanValueProperty {
-	private final IValueProperty delegate;
+public class BeanValuePropertyDecorator<S, T> extends ValueProperty<S, T>
+		implements IBeanValueProperty<S, T> {
+	private final IValueProperty<S, T> delegate;
 	private final PropertyDescriptor propertyDescriptor;
 
 	/**
 	 * @param delegate
 	 * @param propertyDescriptor
 	 */
-	public BeanValuePropertyDecorator(IValueProperty delegate,
+	public BeanValuePropertyDecorator(IValueProperty<S, T> delegate,
 			PropertyDescriptor propertyDescriptor) {
 		this.delegate = delegate;
 		this.propertyDescriptor = propertyDescriptor;
@@ -50,104 +52,124 @@
 		return propertyDescriptor;
 	}
 
+	/**
+	 * @deprecated use getValueClass instead
+	 */
 	public Object getValueType() {
 		return delegate.getValueType();
 	}
 
-	protected Object doGetValue(Object source) {
+	public Class<T> getValueClass() {
+		return delegate.getValueClass();
+	}
+
+	protected T doGetValue(S source) {
 		return delegate.getValue(source);
 	}
 
-	protected void doSetValue(Object source, Object value) {
+	protected void doSetValue(S source, T value) {
 		delegate.setValue(source, value);
 	}
 
-	public IBeanValueProperty value(String propertyName) {
+	public <V> IBeanValueProperty<S, V> value(String propertyName) {
 		return value(propertyName, null);
 	}
 
-	public IBeanValueProperty value(String propertyName, Class valueType) {
-		Class beanClass = (Class) delegate.getValueType();
+	/**
+	 * @param propertyName
+	 * @param valueType
+	 * @return x
+	 */
+	public <V> IBeanValueProperty<S, V> value(String propertyName,
+			Class<V> valueType) {
+		Class<T> beanClass = delegate.getValueClass();
 		return value(BeanProperties.value(beanClass, propertyName, valueType));
 	}
 
-	public IBeanValueProperty value(IBeanValueProperty property) {
-		return new BeanValuePropertyDecorator(super.value(property),
+	public <V> IBeanValueProperty<S, V> value(IBeanValueProperty<T, V> property) {
+		return new BeanValuePropertyDecorator<S, V>(super.value(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IBeanListProperty list(String propertyName) {
+	public <E> IBeanListProperty<S, E> list(String propertyName) {
 		return list(propertyName, null);
 	}
 
-	public IBeanListProperty list(String propertyName, Class elementType) {
-		Class beanClass = (Class) delegate.getValueType();
+	public <E> IBeanListProperty<S, E> list(String propertyName,
+			Class<E> elementType) {
+		Class<T> beanClass = delegate.getValueClass();
 		return list(BeanProperties.list(beanClass, propertyName, elementType));
 	}
 
-	public IBeanListProperty list(IBeanListProperty property) {
-		return new BeanListPropertyDecorator(super.list(property),
+	public <E> IBeanListProperty<S, E> list(IBeanListProperty<T, E> property) {
+		return new BeanListPropertyDecorator<S, E>(super.list(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IBeanSetProperty set(String propertyName) {
+	public <E> IBeanSetProperty<S, E> set(String propertyName) {
 		return set(propertyName, null);
 	}
 
-	public IBeanSetProperty set(String propertyName, Class elementType) {
-		Class beanClass = (Class) delegate.getValueType();
+	public <E> IBeanSetProperty<S, E> set(String propertyName,
+			Class<E> elementType) {
+		Class<T> beanClass = delegate.getValueClass();
 		return set(BeanProperties.set(beanClass, propertyName, elementType));
 	}
 
-	public IBeanSetProperty set(IBeanSetProperty property) {
-		return new BeanSetPropertyDecorator(super.set(property),
+	public <E> IBeanSetProperty<S, E> set(IBeanSetProperty<T, E> property) {
+		return new BeanSetPropertyDecorator<S, E>(super.set(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IBeanMapProperty map(String propertyName) {
+	public <K, V> IBeanMapProperty<S, K, V> map(String propertyName) {
 		return map(propertyName, null, null);
 	}
 
-	public IBeanMapProperty map(String propertyName, Class keyType,
-			Class valueType) {
-		Class beanClass = (Class) delegate.getValueType();
+	public <K, V> IBeanMapProperty<S, K, V> map(String propertyName,
+			Class<K> keyType, Class<V> valueType) {
+		Class<T> beanClass = delegate.getValueClass();
 		return map(BeanProperties.map(beanClass, propertyName, keyType,
 				valueType));
 	}
 
-	public IBeanMapProperty map(IBeanMapProperty property) {
-		return new BeanMapPropertyDecorator(super.map(property),
+	public <K, V> IBeanMapProperty<S, K, V> map(
+			IBeanMapProperty<? super T, K, V> property) {
+		return new BeanMapPropertyDecorator<S, K, V>(super.map(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IObservableValue observe(Object source) {
-		return new BeanObservableValueDecorator(delegate.observe(source),
+	public IObservableValue<T> observe(S source) {
+		return new BeanObservableValueDecorator<T>(delegate.observe(source),
 				propertyDescriptor);
 	}
 
-	public IObservableValue observe(Realm realm, Object source) {
-		return new BeanObservableValueDecorator(
-				delegate.observe(realm, source), propertyDescriptor);
+	public IObservableValue<T> observe(Realm realm, S source) {
+		return new BeanObservableValueDecorator<T>(delegate.observe(realm,
+				source), propertyDescriptor);
 	}
 
-	public IObservableValue observeDetail(IObservableValue master) {
-		return new BeanObservableValueDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <M extends S> IObservableValue<T> observeDetail(
+			IObservableValue<M> master) {
+		return new BeanObservableValueDecorator<T>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
-	public IObservableList observeDetail(IObservableList master) {
-		return new BeanObservableListDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <M extends S> IObservableList<T> observeDetail(
+			IObservableList<M> master) {
+		return new BeanObservableListDecorator<T>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
-	public IObservableMap observeDetail(IObservableSet master) {
-		return new BeanObservableMapDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <M extends S> IObservableMap<M, T> observeDetail(
+			IObservableSet<M> master) {
+		return new BeanObservableMapDecorator<M, T>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
-	public IObservableMap observeDetail(IObservableMap master) {
-		return new BeanObservableMapDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <K, M extends S> IObservableMap<K, T> observeDetail(
+			IObservableMap<K, M> master) {
+		return new BeanObservableMapDecorator<K, T>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoListProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoListProperty.java
index 44634d4..d8ec127 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoListProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoListProperty.java
@@ -23,68 +23,96 @@
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.list.SimpleListProperty;
+import org.eclipse.core.databinding.util.Policy;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class PojoListProperty extends SimpleListProperty {
+public class PojoListProperty<S, E> extends SimpleListProperty<S, E> {
 	private final PropertyDescriptor propertyDescriptor;
-	private final Class elementType;
+	private final Class<E> elementType;
 
 	/**
 	 * @param propertyDescriptor
 	 * @param elementType
 	 */
 	public PojoListProperty(PropertyDescriptor propertyDescriptor,
-			Class elementType) {
+			Class<E> elementType) {
+		if (elementType == null) {
+			// elementType cannot be null.
+			// For legacy reasons, we allow this through but log it.
+			// Three cycles after Kepler this should be replaced by the
+			// exception (currently
+			// commented out) because it is not type safe.
+			// throw new IllegalArgumentException("elementType cannot be null."); //$NON-NLS-1$
+			Policy.getLog().log(
+					new Status(IStatus.WARNING, Policy.JFACE_DATABINDING,
+							"elementType cannot be null")); //$NON-NLS-1$
+
+			if (propertyDescriptor.getPropertyType().isArray()) {
+				elementType = (Class<E>) propertyDescriptor.getPropertyType()
+						.getComponentType();
+			} else {
+				elementType = (Class<E>) Object.class;
+			}
+		}
+
+		BeanPropertyHelper.checkCollectionPropertyElementType(
+				propertyDescriptor, elementType);
 		this.propertyDescriptor = propertyDescriptor;
-		this.elementType = elementType == null ? BeanPropertyHelper
-				.getCollectionPropertyElementType(propertyDescriptor)
-				: elementType;
+		this.elementType = elementType;
 	}
 
-	public Object getElementType() {
+	public Class<E> getElementType() {
 		return elementType;
 	}
 
-	protected List doGetList(Object source) {
-		return asList(BeanPropertyHelper.readProperty(source,
+	public Class<E> getElementClass() {
+		return elementType;
+	}
+
+	protected List<E> doGetList(S source) {
+		return (List<E>) asList(BeanPropertyHelper.readProperty(source,
 				propertyDescriptor));
 	}
 
-	private List asList(Object propertyValue) {
+	private List<?> asList(Object propertyValue) {
 		if (propertyValue == null)
-			return Collections.EMPTY_LIST;
+			return Collections.emptyList();
 		if (propertyDescriptor.getPropertyType().isArray())
 			return Arrays.asList((Object[]) propertyValue);
-		return (List) propertyValue;
+		return (List<?>) propertyValue;
 	}
 
-	protected void doSetList(Object source, List list, ListDiff diff) {
+	protected void doSetList(S source, List<E> list, ListDiff<E> diff) {
 		doSetList(source, list);
 	}
 
-	protected void doSetList(Object source, List list) {
+	protected void doSetList(S source, List<E> list) {
 		BeanPropertyHelper.writeProperty(source, propertyDescriptor,
 				convertListToBeanPropertyType(list));
 	}
 
-	private Object convertListToBeanPropertyType(List list) {
+	private Object convertListToBeanPropertyType(List<E> list) {
 		Object propertyValue = list;
 		if (propertyDescriptor.getPropertyType().isArray()) {
-			Class componentType = propertyDescriptor.getPropertyType()
+			Class<?> componentType = propertyDescriptor.getPropertyType()
 					.getComponentType();
-			Object[] array = (Object[]) Array.newInstance(componentType, list
-					.size());
+			Object[] array = (Object[]) Array.newInstance(componentType,
+					list.size());
 			list.toArray(array);
 			propertyValue = array;
 		}
 		return propertyValue;
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<S> adaptListener(
+			ISimplePropertyListener<ListDiff<E>> listener) {
 		return null;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoListPropertyDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoListPropertyDecorator.java
index a77ced2..56fb396 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoListPropertyDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoListPropertyDecorator.java
@@ -26,51 +26,61 @@
 import org.eclipse.core.databinding.property.list.ListProperty;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class PojoListPropertyDecorator extends ListProperty implements
-		IBeanListProperty {
-	private final IListProperty delegate;
+public class PojoListPropertyDecorator<S, E> extends ListProperty<S, E>
+		implements IBeanListProperty<S, E> {
+	private final IListProperty<S, E> delegate;
 	private final PropertyDescriptor propertyDescriptor;
 
 	/**
 	 * @param delegate
 	 * @param propertyDescriptor
 	 */
-	public PojoListPropertyDecorator(IListProperty delegate,
+	public PojoListPropertyDecorator(IListProperty<S, E> delegate,
 			PropertyDescriptor propertyDescriptor) {
 		this.delegate = delegate;
 		this.propertyDescriptor = propertyDescriptor;
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return delegate.getElementType();
 	}
 
-	protected List doGetList(Object source) {
+	public Class<E> getElementClass() {
+		return delegate.getElementClass();
+	}
+
+	protected List<E> doGetList(S source) {
 		return delegate.getList(source);
 	}
 
-	protected void doSetList(Object source, List list) {
+	protected void doSetList(S source, List<E> list) {
 		delegate.setList(source, list);
 	}
 
-	protected void doUpdateList(Object source, ListDiff diff) {
+	protected void doUpdateList(S source, ListDiff<E> diff) {
 		delegate.updateList(source, diff);
 	}
 
-	public IBeanListProperty values(String propertyName) {
+	public <T> IBeanListProperty<S, T> values(String propertyName) {
 		return values(propertyName, null);
 	}
 
-	public IBeanListProperty values(String propertyName, Class valueType) {
-		Class beanClass = (Class) delegate.getElementType();
+	public <T> IBeanListProperty<S, T> values(String propertyName,
+			Class<T> valueType) {
+		Class<E> beanClass = delegate.getElementClass();
 		return values(PojoProperties.value(beanClass, propertyName, valueType));
 	}
 
-	public IBeanListProperty values(IBeanValueProperty property) {
-		return new PojoListPropertyDecorator(super.values(property),
+	public <T> IBeanListProperty<S, T> values(IBeanValueProperty<E, T> property) {
+		return new PojoListPropertyDecorator<S, T>(super.values(property),
 				property.getPropertyDescriptor());
 	}
 
@@ -78,19 +88,20 @@
 		return propertyDescriptor;
 	}
 
-	public IObservableList observe(Object source) {
-		return new BeanObservableListDecorator(delegate.observe(source),
+	public IObservableList<E> observe(S source) {
+		return new BeanObservableListDecorator<E>(delegate.observe(source),
 				propertyDescriptor);
 	}
 
-	public IObservableList observe(Realm realm, Object source) {
-		return new BeanObservableListDecorator(delegate.observe(realm, source),
-				propertyDescriptor);
+	public IObservableList<E> observe(Realm realm, S source) {
+		return new BeanObservableListDecorator<E>(delegate.observe(realm,
+				source), propertyDescriptor);
 	}
 
-	public IObservableList observeDetail(IObservableValue master) {
-		return new BeanObservableListDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <M extends S> IObservableList<E> observeDetail(
+			IObservableValue<M> master) {
+		return new BeanObservableListDecorator<E>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoMapProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoMapProperty.java
index 5c81d48..a8275bf 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoMapProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoMapProperty.java
@@ -13,7 +13,7 @@
 package org.eclipse.core.internal.databinding.beans;
 
 import java.beans.PropertyDescriptor;
-import java.util.HashMap;
+import java.util.Collections;
 import java.util.Map;
 
 import org.eclipse.core.databinding.observable.map.MapDiff;
@@ -22,13 +22,16 @@
 import org.eclipse.core.databinding.property.map.SimpleMapProperty;
 
 /**
+ * @param <S>
+ * @param <K>
+ * @param <V>
  * @since 3.3
  * 
  */
-public class PojoMapProperty extends SimpleMapProperty {
+public class PojoMapProperty<S, K, V> extends SimpleMapProperty<S, K, V> {
 	private final PropertyDescriptor propertyDescriptor;
-	private final Class keyType;
-	private final Class valueType;
+	private final Class<K> keyType;
+	private final Class<V> valueType;
 
 	/**
 	 * @param propertyDescriptor
@@ -36,7 +39,7 @@
 	 * @param valueType
 	 */
 	public PojoMapProperty(PropertyDescriptor propertyDescriptor,
-			Class keyType, Class valueType) {
+			Class<K> keyType, Class<V> valueType) {
 		this.propertyDescriptor = propertyDescriptor;
 		this.keyType = keyType;
 		this.valueType = valueType;
@@ -50,27 +53,35 @@
 		return valueType;
 	}
 
-	protected Map doGetMap(Object source) {
-		return asMap(BeanPropertyHelper
-				.readProperty(source, propertyDescriptor));
+	public Class<K> getKeyClass() {
+		return keyType;
 	}
 
-	private Map asMap(Object propertyValue) {
+	public Class<V> getValueClass() {
+		return valueType;
+	}
+
+	protected Map<K, V> doGetMap(S source) {
+		return (Map<K, V>) asMap(BeanPropertyHelper.readProperty(source,
+				propertyDescriptor));
+	}
+
+	private Map<?, ?> asMap(Object propertyValue) {
 		if (propertyValue == null)
-			return new HashMap();
-		return (Map) propertyValue;
+			return Collections.emptyMap();
+		return (Map<?, ?>) propertyValue;
 	}
 
-	protected void doSetMap(Object source, Map map, MapDiff diff) {
+	protected void doSetMap(S source, Map<K, V> map, MapDiff<K, V> diff) {
 		doSetMap(source, map);
 	}
 
-	protected void doSetMap(Object source, Map map) {
+	protected void doSetMap(S source, Map<K, V> map) {
 		BeanPropertyHelper.writeProperty(source, propertyDescriptor, map);
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<S> adaptListener(
+			ISimplePropertyListener<MapDiff<K, V>> listener) {
 		return null;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoMapPropertyDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoMapPropertyDecorator.java
index fa318a9..1d7d8f1 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoMapPropertyDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoMapPropertyDecorator.java
@@ -26,41 +26,58 @@
 import org.eclipse.core.databinding.property.map.MapProperty;
 
 /**
+ * @param <S>
+ * @param <K>
+ * @param <V>
  * @since 3.3
  * 
  */
-public class PojoMapPropertyDecorator extends MapProperty implements
-		IBeanMapProperty {
-	private final IMapProperty delegate;
+public class PojoMapPropertyDecorator<S, K, V> extends MapProperty<S, K, V>
+		implements IBeanMapProperty<S, K, V> {
+	private final IMapProperty<S, K, V> delegate;
 	private final PropertyDescriptor propertyDescriptor;
 
 	/**
 	 * @param delegate
 	 * @param propertyDescriptor
 	 */
-	public PojoMapPropertyDecorator(IMapProperty delegate,
+	public PojoMapPropertyDecorator(IMapProperty<S, K, V> delegate,
 			PropertyDescriptor propertyDescriptor) {
 		this.delegate = delegate;
 		this.propertyDescriptor = propertyDescriptor;
 	}
 
+	/**
+	 * @deprecated use getKeyClass instead
+	 */
 	public Object getKeyType() {
 		return delegate.getKeyType();
 	}
 
+	/**
+	 * @deprecated use getValueClass instead
+	 */
 	public Object getValueType() {
 		return delegate.getValueType();
 	}
 
-	protected Map doGetMap(Object source) {
+	public Class<K> getKeyClass() {
+		return delegate.getKeyClass();
+	}
+
+	public Class<V> getValueClass() {
+		return delegate.getValueClass();
+	}
+
+	protected Map<K, V> doGetMap(S source) {
 		return delegate.getMap(source);
 	}
 
-	protected void doSetMap(Object source, Map map) {
+	protected void doSetMap(S source, Map<K, V> map) {
 		delegate.setMap(source, map);
 	}
 
-	protected void doUpdateMap(Object source, MapDiff diff) {
+	protected void doUpdateMap(S source, MapDiff<K, V> diff) {
 		delegate.updateMap(source, diff);
 	}
 
@@ -68,33 +85,36 @@
 		return propertyDescriptor;
 	}
 
-	public IBeanMapProperty values(String propertyName) {
+	public <T> IBeanMapProperty<S, K, T> values(String propertyName) {
 		return values(propertyName, null);
 	}
 
-	public IBeanMapProperty values(String propertyName, Class valueType) {
-		Class beanClass = (Class) delegate.getValueType();
+	public <T> IBeanMapProperty<S, K, T> values(String propertyName,
+			Class<T> valueType) {
+		Class<V> beanClass = delegate.getValueClass();
 		return values(PojoProperties.value(beanClass, propertyName, valueType));
 	}
 
-	public IBeanMapProperty values(IBeanValueProperty property) {
-		return new PojoMapPropertyDecorator(super.values(property),
+	public <T> IBeanMapProperty<S, K, T> values(
+			IBeanValueProperty<V, T> property) {
+		return new PojoMapPropertyDecorator<S, K, T>(super.values(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IObservableMap observe(Object source) {
-		return new BeanObservableMapDecorator(delegate.observe(source),
+	public IObservableMap<K, V> observe(S source) {
+		return new BeanObservableMapDecorator<K, V>(delegate.observe(source),
 				propertyDescriptor);
 	}
 
-	public IObservableMap observe(Realm realm, Object source) {
-		return new BeanObservableMapDecorator(delegate.observe(realm, source),
-				propertyDescriptor);
+	public IObservableMap<K, V> observe(Realm realm, S source) {
+		return new BeanObservableMapDecorator<K, V>(delegate.observe(realm,
+				source), propertyDescriptor);
 	}
 
-	public IObservableMap observeDetail(IObservableValue master) {
-		return new BeanObservableMapDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <M extends S> IObservableMap<K, V> observeDetail(
+			IObservableValue<M> master) {
+		return new BeanObservableMapDecorator<K, V>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoSetProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoSetProperty.java
index d0f2fa6..8c2af28 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoSetProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoSetProperty.java
@@ -23,67 +23,95 @@
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.set.SimpleSetProperty;
+import org.eclipse.core.databinding.util.Policy;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class PojoSetProperty extends SimpleSetProperty {
+public class PojoSetProperty<S, E> extends SimpleSetProperty<S, E> {
 	private final PropertyDescriptor propertyDescriptor;
-	private final Class elementType;
+	private final Class<E> elementType;
 
 	/**
 	 * @param propertyDescriptor
 	 * @param elementType
 	 */
 	public PojoSetProperty(PropertyDescriptor propertyDescriptor,
-			Class elementType) {
+			Class<E> elementType) {
+		if (elementType == null) {
+			// elementType cannot be null.
+			// For legacy reasons, we allow this through but log it.
+			// Three cycles after Kepler this should be replaced by the
+			// exception (currently
+			// commented out) because it is not type safe.
+			// throw new IllegalArgumentException("elementType cannot be null."); //$NON-NLS-1$
+			Policy.getLog().log(
+					new Status(IStatus.WARNING, Policy.JFACE_DATABINDING,
+							"elementType cannot be null")); //$NON-NLS-1$
+
+			if (propertyDescriptor.getPropertyType().isArray()) {
+				elementType = (Class<E>) propertyDescriptor.getPropertyType()
+						.getComponentType();
+			} else {
+				elementType = (Class<E>) Object.class;
+			}
+		}
+
+		BeanPropertyHelper.checkCollectionPropertyElementType(
+				propertyDescriptor, elementType);
 		this.propertyDescriptor = propertyDescriptor;
-		this.elementType = elementType == null ? BeanPropertyHelper
-				.getCollectionPropertyElementType(propertyDescriptor)
-				: elementType;
+		this.elementType = elementType;
 	}
 
-	public Object getElementType() {
+	public Class<E> getElementType() {
 		return elementType;
 	}
 
-	protected Set doGetSet(Object source) {
-		return asSet(BeanPropertyHelper
-				.readProperty(source, propertyDescriptor));
+	public Class<E> getElementClass() {
+		return elementType;
 	}
 
-	private Set asSet(Object propertyValue) {
+	protected Set<E> doGetSet(S source) {
+		return (Set<E>) asSet(BeanPropertyHelper.readProperty(source,
+				propertyDescriptor));
+	}
+
+	private Set<?> asSet(Object propertyValue) {
 		if (propertyValue == null)
-			return Collections.EMPTY_SET;
+			return Collections.emptySet();
 		if (propertyDescriptor.getPropertyType().isArray())
-			return new HashSet(Arrays.asList((Object[]) propertyValue));
-		return (Set) propertyValue;
+			return new HashSet<Object>(Arrays.asList((Object[]) propertyValue));
+		return (Set<?>) propertyValue;
 	}
 
-	protected void doSetSet(Object source, Set set, SetDiff diff) {
+	protected void doSetSet(S source, Set<E> set, SetDiff<E> diff) {
 		doSetSet(source, set);
 	}
 
-	protected void doSetSet(Object source, Set set) {
+	protected void doSetSet(S source, Set<E> set) {
 		BeanPropertyHelper.writeProperty(source, propertyDescriptor,
 				convertSetToBeanPropertyType(set));
 	}
 
-	private Object convertSetToBeanPropertyType(Set set) {
+	private Object convertSetToBeanPropertyType(Set<E> set) {
 		Object propertyValue = set;
 		if (propertyDescriptor.getPropertyType().isArray()) {
-			Class componentType = propertyDescriptor.getPropertyType()
+			Class<?> componentType = propertyDescriptor.getPropertyType()
 					.getComponentType();
-			Object[] array = (Object[]) Array.newInstance(componentType, set
-					.size());
+			Object[] array = (Object[]) Array.newInstance(componentType,
+					set.size());
 			propertyValue = set.toArray(array);
 		}
 		return propertyValue;
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<S> adaptListener(
+			ISimplePropertyListener<SetDiff<E>> listener) {
 		return null;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoSetPropertyDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoSetPropertyDecorator.java
index ebe54a9..4b0a9a1 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoSetPropertyDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoSetPropertyDecorator.java
@@ -27,37 +27,46 @@
 import org.eclipse.core.databinding.property.set.SetProperty;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class PojoSetPropertyDecorator extends SetProperty implements
-		IBeanSetProperty {
-	private final ISetProperty delegate;
+public class PojoSetPropertyDecorator<S, E> extends SetProperty<S, E> implements
+		IBeanSetProperty<S, E> {
+	private final ISetProperty<S, E> delegate;
 	private final PropertyDescriptor propertyDescriptor;
 
 	/**
 	 * @param delegate
 	 * @param propertyDescriptor
 	 */
-	public PojoSetPropertyDecorator(ISetProperty delegate,
+	public PojoSetPropertyDecorator(ISetProperty<S, E> delegate,
 			PropertyDescriptor propertyDescriptor) {
 		this.delegate = delegate;
 		this.propertyDescriptor = propertyDescriptor;
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return delegate.getElementType();
 	}
 
-	protected Set doGetSet(Object source) {
+	public Class<E> getElementClass() {
+		return delegate.getElementClass();
+	}
+
+	protected Set<E> doGetSet(S source) {
 		return delegate.getSet(source);
 	}
 
-	protected void doSetSet(Object source, Set set) {
+	protected void doSetSet(S source, Set<E> set) {
 		delegate.setSet(source, set);
 	}
 
-	protected void doUpdateSet(Object source, SetDiff diff) {
+	protected void doUpdateSet(S source, SetDiff<E> diff) {
 		delegate.updateSet(source, diff);
 	}
 
@@ -65,33 +74,36 @@
 		return propertyDescriptor;
 	}
 
-	public IBeanMapProperty values(String propertyName) {
+	public <T> IBeanMapProperty<S, E, T> values(String propertyName) {
 		return values(propertyName, null);
 	}
 
-	public IBeanMapProperty values(String propertyName, Class valueType) {
-		Class beanClass = (Class) delegate.getElementType();
+	public <T> IBeanMapProperty<S, E, T> values(String propertyName,
+			Class<T> valueType) {
+		Class<E> beanClass = delegate.getElementClass();
 		return values(PojoProperties.value(beanClass, propertyName, valueType));
 	}
 
-	public IBeanMapProperty values(IBeanValueProperty property) {
-		return new BeanMapPropertyDecorator(super.values(property),
+	public <T> IBeanMapProperty<S, E, T> values(
+			IBeanValueProperty<E, T> property) {
+		return new BeanMapPropertyDecorator<S, E, T>(super.values(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IObservableSet observe(Object source) {
-		return new BeanObservableSetDecorator(delegate.observe(source),
+	public IObservableSet<E> observe(S source) {
+		return new BeanObservableSetDecorator<E>(delegate.observe(source),
 				propertyDescriptor);
 	}
 
-	public IObservableSet observe(Realm realm, Object source) {
-		return new BeanObservableSetDecorator(delegate.observe(realm, source),
-				propertyDescriptor);
+	public IObservableSet<E> observe(Realm realm, S source) {
+		return new BeanObservableSetDecorator<E>(
+				delegate.observe(realm, source), propertyDescriptor);
 	}
 
-	public IObservableSet observeDetail(IObservableValue master) {
-		return new BeanObservableSetDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <M extends S> IObservableSet<E> observeDetail(
+			IObservableValue<M> master) {
+		return new BeanObservableSetDecorator<E>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoValueProperty.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoValueProperty.java
index f63a8c8..6d2dbec 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoValueProperty.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoValueProperty.java
@@ -14,45 +14,60 @@
 
 import java.beans.PropertyDescriptor;
 
+import org.eclipse.core.databinding.observable.value.ValueDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.value.SimpleValueProperty;
 
 /**
+ * @param <S>
+ * @param <T>
  * @since 3.3
  * 
  */
-public class PojoValueProperty extends SimpleValueProperty {
+public class PojoValueProperty<S, T> extends SimpleValueProperty<S, T> {
 	private final PropertyDescriptor propertyDescriptor;
-	private final Class valueType;
+	private final Class<T> valueType;
 
 	/**
 	 * @param propertyDescriptor
 	 * @param valueType
 	 */
 	public PojoValueProperty(PropertyDescriptor propertyDescriptor,
-			Class valueType) {
+			Class<T> valueType) {
+		if (valueType == null) {
+			// valueType cannot be null. If the caller knows the specific
+			// type of the class then that should be passed. If the caller
+			// does not specifically know the class then pass
+			// propertyDescriptor.getPropertyType() and T will be a wild card.
+			throw new IllegalArgumentException("valueType cannot be null."); //$NON-NLS-1$
+		}
 		this.propertyDescriptor = propertyDescriptor;
-		this.valueType = valueType == null ? propertyDescriptor
-				.getPropertyType() : valueType;
+		this.valueType = valueType;
 	}
 
-	public Object getValueType() {
+	public Class<T> getValueType() {
 		return valueType;
 	}
 
-	protected Object doGetValue(Object source) {
+	public Class<T> getValueClass() {
+		return valueType;
+	}
+
+	protected T doGetValue(S source) {
 		if (source == null)
 			return null;
-		return BeanPropertyHelper.readProperty(source, propertyDescriptor);
+		Object value = BeanPropertyHelper.readProperty(source,
+				propertyDescriptor);
+		return valueType.cast(value);
 	}
 
 	protected void doSetValue(Object source, Object value) {
 		BeanPropertyHelper.writeProperty(source, propertyDescriptor, value);
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<S> adaptListener(
+			ISimplePropertyListener<ValueDiff<T>> listener) {
 		return null;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoValuePropertyDecorator.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoValuePropertyDecorator.java
index af410e7..a542395 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoValuePropertyDecorator.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/PojoValuePropertyDecorator.java
@@ -28,19 +28,21 @@
 import org.eclipse.core.databinding.property.value.ValueProperty;
 
 /**
+ * @param <S>
+ * @param <T>
  * @since 3.3
  * 
  */
-public class PojoValuePropertyDecorator extends ValueProperty implements
-		IBeanValueProperty {
-	private final IValueProperty delegate;
+public class PojoValuePropertyDecorator<S, T> extends ValueProperty<S, T>
+		implements IBeanValueProperty<S, T> {
+	private final IValueProperty<S, T> delegate;
 	private final PropertyDescriptor propertyDescriptor;
 
 	/**
 	 * @param delegate
 	 * @param propertyDescriptor
 	 */
-	public PojoValuePropertyDecorator(IValueProperty delegate,
+	public PojoValuePropertyDecorator(IValueProperty<S, T> delegate,
 			PropertyDescriptor propertyDescriptor) {
 		this.delegate = delegate;
 		this.propertyDescriptor = propertyDescriptor;
@@ -50,104 +52,119 @@
 		return propertyDescriptor;
 	}
 
+	/**
+	 * @deprecated use getValueClass instead
+	 */
 	public Object getValueType() {
 		return delegate.getValueType();
 	}
 
-	protected Object doGetValue(Object source) {
+	public Class<T> getValueClass() {
+		return delegate.getValueClass();
+	}
+
+	protected T doGetValue(S source) {
 		return delegate.getValue(source);
 	}
 
-	protected void doSetValue(Object source, Object value) {
+	protected void doSetValue(S source, T value) {
 		delegate.setValue(source, value);
 	}
 
-	public IBeanValueProperty value(String propertyName) {
+	public <V> IBeanValueProperty<S, V> value(String propertyName) {
 		return value(propertyName, null);
 	}
 
-	public IBeanValueProperty value(String propertyName, Class valueType) {
-		Class beanClass = (Class) delegate.getValueType();
+	public <V> IBeanValueProperty<S, V> value(String propertyName,
+			Class<V> valueType) {
+		Class<T> beanClass = delegate.getValueClass();
 		return value(PojoProperties.value(beanClass, propertyName, valueType));
 	}
 
-	public IBeanValueProperty value(IBeanValueProperty property) {
-		return new PojoValuePropertyDecorator(super.value(property),
+	public <V> IBeanValueProperty<S, V> value(IBeanValueProperty<T, V> property) {
+		return new PojoValuePropertyDecorator<S, V>(super.value(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IBeanListProperty list(String propertyName) {
+	public <E> IBeanListProperty<S, E> list(String propertyName) {
 		return list(propertyName, null);
 	}
 
-	public IBeanListProperty list(String propertyName, Class elementType) {
-		Class beanClass = (Class) delegate.getValueType();
+	public <E> IBeanListProperty<S, E> list(String propertyName,
+			Class<E> elementType) {
+		Class<T> beanClass = delegate.getValueClass();
 		return list(PojoProperties.list(beanClass, propertyName, elementType));
 	}
 
-	public IBeanListProperty list(IBeanListProperty property) {
-		return new BeanListPropertyDecorator(super.list(property),
+	public <E> IBeanListProperty<S, E> list(IBeanListProperty<T, E> property) {
+		return new BeanListPropertyDecorator<S, E>(super.list(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IBeanSetProperty set(String propertyName) {
+	public <E> IBeanSetProperty<S, E> set(String propertyName) {
 		return set(propertyName, null);
 	}
 
-	public IBeanSetProperty set(String propertyName, Class elementType) {
-		Class beanClass = (Class) delegate.getValueType();
+	public <E> IBeanSetProperty<S, E> set(String propertyName,
+			Class<E> elementType) {
+		Class<T> beanClass = delegate.getValueClass();
 		return set(PojoProperties.set(beanClass, propertyName, elementType));
 	}
 
-	public IBeanSetProperty set(IBeanSetProperty property) {
-		return new BeanSetPropertyDecorator(super.set(property),
+	public <E> IBeanSetProperty<S, E> set(IBeanSetProperty<T, E> property) {
+		return new BeanSetPropertyDecorator<S, E>(super.set(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IBeanMapProperty map(String propertyName) {
+	public <K, V> IBeanMapProperty<S, K, V> map(String propertyName) {
 		return map(propertyName, null, null);
 	}
 
-	public IBeanMapProperty map(String propertyName, Class keyType,
-			Class valueType) {
-		Class beanClass = (Class) delegate.getValueType();
+	public <K, V> IBeanMapProperty<S, K, V> map(String propertyName,
+			Class<K> keyType, Class<V> valueType) {
+		Class<T> beanClass = delegate.getValueClass();
 		return map(PojoProperties.map(beanClass, propertyName, keyType,
 				valueType));
 	}
 
-	public IBeanMapProperty map(IBeanMapProperty property) {
-		return new BeanMapPropertyDecorator(super.map(property),
+	public <K, V> IBeanMapProperty<S, K, V> map(
+			IBeanMapProperty<? super T, K, V> property) {
+		return new BeanMapPropertyDecorator<S, K, V>(super.map(property),
 				property.getPropertyDescriptor());
 	}
 
-	public IObservableValue observe(Object source) {
-		return new BeanObservableValueDecorator(delegate.observe(source),
+	public IObservableValue<T> observe(S source) {
+		return new BeanObservableValueDecorator<T>(delegate.observe(source),
 				propertyDescriptor);
 	}
 
-	public IObservableValue observe(Realm realm, Object source) {
-		return new BeanObservableValueDecorator(
-				delegate.observe(realm, source), propertyDescriptor);
+	public IObservableValue<T> observe(Realm realm, S source) {
+		return new BeanObservableValueDecorator<T>(delegate.observe(realm,
+				source), propertyDescriptor);
 	}
 
-	public IObservableValue observeDetail(IObservableValue master) {
-		return new BeanObservableValueDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <M extends S> IObservableValue<T> observeDetail(
+			IObservableValue<M> master) {
+		return new BeanObservableValueDecorator<T>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
-	public IObservableList observeDetail(IObservableList master) {
-		return new BeanObservableListDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <M extends S> IObservableList<T> observeDetail(
+			IObservableList<M> master) {
+		return new BeanObservableListDecorator<T>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
-	public IObservableMap observeDetail(IObservableSet master) {
-		return new BeanObservableMapDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <M extends S> IObservableMap<M, T> observeDetail(
+			IObservableSet<M> master) {
+		return new BeanObservableMapDecorator<M, T>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
-	public IObservableMap observeDetail(IObservableMap master) {
-		return new BeanObservableMapDecorator(delegate.observeDetail(master),
-				propertyDescriptor);
+	public <K, M extends S> IObservableMap<K, T> observeDetail(
+			IObservableMap<K, M> master) {
+		return new BeanObservableMapDecorator<K, T>(
+				delegate.observeDetail(master), propertyDescriptor);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/TypedSet.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/TypedSet.java
new file mode 100644
index 0000000..c5581da
--- /dev/null
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/TypedSet.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.core.internal.databinding.beans;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @param <E>
+ * @since 3.3
+ * 
+ */
+public class TypedSet<E> implements Set<E> {
+
+	final Set<?> wrappedSet;
+
+	final Class<E> elementType;
+
+	TypedSet(Set<?> wrappedSet, Class<E> elementType) {
+		this.wrappedSet = wrappedSet;
+		this.elementType = elementType;
+	}
+
+	public boolean add(Object o) {
+		throw new UnsupportedOperationException();
+	}
+
+	public boolean addAll(Collection<? extends E> c) {
+		throw new UnsupportedOperationException();
+	}
+
+	public void clear() {
+		throw new UnsupportedOperationException();
+	}
+
+	public boolean contains(Object o) {
+		return wrappedSet.contains(o);
+	}
+
+	public boolean containsAll(Collection<?> c) {
+		return wrappedSet.containsAll(c);
+	}
+
+	public boolean isEmpty() {
+		return wrappedSet.isEmpty();
+	}
+
+	public Iterator<E> iterator() {
+		final Iterator<?> wrappedIterator = wrappedSet.iterator();
+		return new Iterator<E>() {
+			public boolean hasNext() {
+				return wrappedIterator.hasNext();
+			}
+
+			public E next() {
+				Object next = wrappedIterator.next();
+				return elementType.cast(next);
+			}
+
+			public void remove() {
+				wrappedIterator.remove();
+			}
+		};
+	}
+
+	public boolean remove(Object o) {
+		throw new UnsupportedOperationException();
+	}
+
+	public boolean removeAll(Collection<?> c) {
+		throw new UnsupportedOperationException();
+	}
+
+	public boolean retainAll(Collection<?> c) {
+		throw new UnsupportedOperationException();
+	}
+
+	public int size() {
+		return wrappedSet.size();
+	}
+
+	public Object[] toArray() {
+		return toArray(new Object[wrappedSet.size()]);
+	}
+
+	public <E2> E2[] toArray(E2[] a) {
+		int size = wrappedSet.size();
+		Class<E2> componentType = Util.getComponentType(a);
+
+		E2[] result = a;
+		if (a.length < size) {
+			result = Util.createArrayInstance(componentType, size);
+		}
+
+		int i = 0;
+		for (Object element : wrappedSet) {
+			result[i] = componentType.cast(element);
+		}
+
+		return result;
+	}
+
+	public boolean equals(Object obj) {
+		if (obj == this)
+			return true;
+		if (obj == null || !(obj instanceof Set))
+			return false;
+		Set<?> that = (Set<?>) obj;
+		return this.size() == that.size() && containsAll(that);
+	}
+
+	public int hashCode() {
+		return wrappedSet.hashCode();
+	}
+}
diff --git a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/Util.java b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/Util.java
index f18e856..5c246f0 100644
--- a/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/Util.java
+++ b/bundles/org.eclipse.core.databinding.beans/src/org/eclipse/core/internal/databinding/beans/Util.java
@@ -11,6 +11,8 @@
 
 package org.eclipse.core.internal.databinding.beans;
 
+import java.lang.reflect.Array;
+
 /**
  * @since 3.3
  * 
@@ -32,4 +34,68 @@
 		return left == null ? right == null : ((right != null) && left
 				.equals(right));
 	}
+
+	/**
+	 * This method carries out an operation that the Java 5 compiler claims is
+	 * an unchecked cast but if fact it should not be. No cast should be
+	 * necessary in the following code because the getComponentType method
+	 * should return a correctly typed result.
+	 * 
+	 * @param a
+	 * @return the class of the elements of the given array
+	 */
+	@SuppressWarnings("unchecked")
+	public static <E> Class<E> getComponentType(E[] a) {
+		return (Class<E>) a.getClass().getComponentType();
+	}
+
+	/**
+	 * This method carries out an operation that the Java 5 compiler claims is
+	 * an unchecked cast but if fact it should not be. No cast should be
+	 * necessary in the following code because the newInstance method should
+	 * return a correctly typed result.
+	 * 
+	 * @param componentType
+	 * @param size
+	 * @return an array of the given element type and size
+	 */
+	@SuppressWarnings("unchecked")
+	public static <E> E[] createArrayInstance(Class<E> componentType, int size) {
+		return (E[]) Array.newInstance(componentType, size);
+	}
+
+	/**
+	 * @param object
+	 * @return the class of the object, correctly typed
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> Class<? extends T> getClass(T object) {
+		return (Class<? extends T>) object.getClass();
+	}
+
+	/**
+	 * @param valueType
+	 * @return a class which will not be a primitive
+	 */
+	public static Class<?> convertToObjectClass(Class<?> valueType) {
+		if (valueType.isPrimitive()) {
+			if (valueType == double.class) {
+				valueType = Double.class;
+			} else if (valueType == long.class) {
+				valueType = Long.class;
+			} else if (valueType == boolean.class) {
+				valueType = Boolean.class;
+			} else if (valueType == float.class) {
+				valueType = Float.class;
+			} else if (valueType == int.class) {
+				valueType = Integer.class;
+			} else if (valueType == char.class) {
+				valueType = Character.class;
+			} else if (valueType == short.class) {
+				valueType = Short.class;
+			}
+		}
+
+		return valueType;
+	}
 }
diff --git a/bundles/org.eclipse.core.databinding.observable/.classpath b/bundles/org.eclipse.core.databinding.observable/.classpath
index 6f3b481..64c5e31 100644
--- a/bundles/org.eclipse.core.databinding.observable/.classpath
+++ b/bundles/org.eclipse.core.databinding.observable/.classpath
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/CDC-1.1%Foundation-1.1"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="output" path="bin"/>
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/DecoratingObservableCollection.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/DecoratingObservableCollection.java
index 4ba9199..009b4d9 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/DecoratingObservableCollection.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/DecoratingObservableCollection.java
@@ -115,10 +115,20 @@
 		return decorated.toArray(a);
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return decorated.getElementType();
 	}
 
+	/**
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
+		return decorated.getElementClass();
+	}
+
 	public boolean equals(Object obj) {
 		getterCalled();
 		if (this == obj) {
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/Diffs.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/Diffs.java
index 77ed5e2..43f3110 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/Diffs.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/Diffs.java
@@ -57,6 +57,48 @@
 	}
 
 	/**
+	 * Returns a {@link ListDiff} describing the change between the specified
+	 * old and new list states.
+	 * <P>
+	 * This method does the same thing as computeListDiff but it accepts untyped
+	 * lists and casts them in a type safe manner returning a typed
+	 * {@link ListDiff}.
+	 * 
+	 * @param <E>
+	 * 
+	 * @param oldList
+	 *            the old list state
+	 * @param newList
+	 *            the new list state
+	 * @param elementType
+	 * @return the differences between oldList and newList
+	 * @since 1.5
+	 */
+	public static <E> ListDiff<E> computeAndCastListDiff(List<?> oldList,
+			List<?> newList, Class<E> elementType) {
+		List<ListDiffEntry<E>> diffEntries = new ArrayList<ListDiffEntry<E>>();
+
+		/*
+		 * We copy both lists into typed lists. createListDiffs will alter the
+		 * oldList (though not newList), so that one has to be copied anyway.
+		 */
+
+		List<E> oldListTyped = new ArrayList<E>();
+		for (Object oldElement : oldList) {
+			oldListTyped.add(elementType.cast(oldElement));
+		}
+
+		List<E> newListTyped = new ArrayList<E>();
+		for (Object newElement : newList) {
+			newListTyped.add(elementType.cast(newElement));
+		}
+
+		createListDiffs(oldListTyped, newListTyped, diffEntries);
+		ListDiff<E> listDiff = createListDiff(diffEntries);
+		return listDiff;
+	}
+
+	/**
 	 * Returns a lazily computed {@link ListDiff} describing the change between
 	 * the specified old and new list states.
 	 * 
@@ -213,6 +255,7 @@
 	 *            the new set state
 	 * @return a {@link SetDiff} describing the change between the specified old
 	 *         and new set states.
+	 * @since 1.5
 	 */
 	public static <E> SetDiff<E> computeSetDiff(Set<E> oldSet, Set<E> newSet) {
 		Set<E> additions = new HashSet<E>(newSet);
@@ -223,6 +266,45 @@
 	}
 
 	/**
+	 * Returns a {@link SetDiff} describing the change between the specified old
+	 * and new set states.
+	 * <P>
+	 * This method does the same thing as computeSetDiff but it accepts untyped
+	 * sets and casts them in a type safe manner returning a typed
+	 * {@link SetDiff}.
+	 * 
+	 * @param <E>
+	 * 
+	 * @param oldSet
+	 *            the old set state
+	 * @param newSet
+	 *            the new set state
+	 * @param elementType
+	 *            the type of the elements in the sets
+	 * @return a {@link SetDiff} describing the change between the specified old
+	 *         and new set states.
+	 * @since 1.5
+	 */
+	public static <E> SetDiff<E> computeAndCastSetDiff(Set<?> oldSet,
+			Set<?> newSet, Class<E> elementType) {
+		Set<E> additions = new HashSet<E>();
+		for (Object newElement : newSet) {
+			if (!oldSet.contains(newElement)) {
+				additions.add(elementType.cast(newElement));
+			}
+		}
+
+		Set<E> removals = new HashSet<E>();
+		for (Object oldElement : oldSet) {
+			if (!newSet.contains(oldElement)) {
+				removals.add(elementType.cast(oldElement));
+			}
+		}
+
+		return createSetDiff(additions, removals);
+	}
+
+	/**
 	 * Returns a lazily computed {@link SetDiff} describing the change between
 	 * the specified old and new set states.
 	 * 
@@ -330,6 +412,85 @@
 	}
 
 	/**
+	 * Returns a {@link MapDiff} describing the change between the specified old
+	 * and new map states.
+	 * <P>
+	 * This version also types the maps. This is useful when the maps have no
+	 * type information (for example they come from reflection) and we require
+	 * the MapDiff to be typed.
+	 * 
+	 * @param <K>
+	 *            the type of keys maintained by this map
+	 * @param <V>
+	 *            the type of mapped values
+	 * @param oldMap
+	 *            the old map state
+	 * @param newMap
+	 *            the new map state
+	 * @param keyType
+	 * @param valueType
+	 * @return a {@link MapDiff} describing the change between the specified old
+	 *         and new map states.
+	 * @since 1.5
+	 */
+	public static <K, V> MapDiff<K, V> computeAndCastMapDiff(Map<?, ?> oldMap,
+			Map<?, ?> newMap, Class<K> keyType, Class<V> valueType) {
+		// starts out with all keys from the new map, we will remove keys from
+		// the old map as we go
+		final Set<K> addedKeys = new HashSet<K>();
+		final Set<K> removedKeys = new HashSet<K>();
+		final Set<K> changedKeys = new HashSet<K>();
+		final Map<K, V> oldValues = new HashMap<K, V>();
+		final Map<K, V> newValues = new HashMap<K, V>();
+
+		for (Object newKey : newMap.keySet()) {
+			addedKeys.add(keyType.cast(newKey));
+		}
+
+		for (Map.Entry<?, ?> oldEntry : oldMap.entrySet()) {
+			K oldKey = keyType.cast(oldEntry.getKey());
+			V oldValue = valueType.cast(oldEntry.getValue());
+			if (addedKeys.remove(oldKey)) {
+				// potentially changed key since it is in oldMap and newMap
+				V newValue = valueType.cast(newMap.get(oldKey));
+				if (!Util.equals(oldValue, newValue)) {
+					changedKeys.add(oldKey);
+					oldValues.put(oldKey, oldValue);
+					newValues.put(oldKey, newValue);
+				}
+			} else {
+				removedKeys.add(oldKey);
+				oldValues.put(oldKey, oldValue);
+			}
+		}
+		for (Iterator<K> it = addedKeys.iterator(); it.hasNext();) {
+			K newKey = it.next();
+			newValues.put(newKey, valueType.cast(newMap.get(newKey)));
+		}
+		return new MapDiff<K, V>() {
+			public Set<K> getAddedKeys() {
+				return addedKeys;
+			}
+
+			public Set<K> getChangedKeys() {
+				return changedKeys;
+			}
+
+			public Set<K> getRemovedKeys() {
+				return removedKeys;
+			}
+
+			public V getNewValue(Object key) {
+				return newValues.get(key);
+			}
+
+			public V getOldValue(Object key) {
+				return oldValues.get(key);
+			}
+		};
+	}
+
+	/**
 	 * Returns a lazily computed {@link MapDiff} describing the change between
 	 * the specified old and new map states.
 	 * 
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/IObservableCollection.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/IObservableCollection.java
index 2aa0867..b2eca28 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/IObservableCollection.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/IObservableCollection.java
@@ -22,7 +22,8 @@
  * changes have to be added using more concrete subtypes such as
  * {@link IObservableList} or {@link IObservableSet}.
  * 
- * @param <T>
+ * @param <E>
+ *            type of the elements in the collection
  * 
  * @noextend This interface is not intended to be extended by clients.
  * @noimplement This interface is not intended to be implemented by clients.
@@ -33,7 +34,7 @@
  * 
  * @since 1.0
  */
-public interface IObservableCollection<T> extends IObservable, Collection<T> {
+public interface IObservableCollection<E> extends IObservable, Collection<E> {
 
 	/**
 	 * Returns the element type of this observable collection, or
@@ -41,7 +42,18 @@
 	 * 
 	 * @return the element type of this observable collection, or
 	 *         <code>null</code> if this observable collection is untyped.
+	 * @deprecated use getElementClass instead
 	 */
 	Object getElementType();
 
+	/**
+	 * Returns the element type of this observable collection, or
+	 * <code>null</code> if this observable collection is untyped.
+	 * 
+	 * @return the element type of this observable collection, or
+	 *         <code>null</code> if this observable collection is untyped.
+	 * @since 1.5
+	 */
+	Class<E> getElementClass();
+
 }
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/Observables.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/Observables.java
index 63f26d3..d881e8b 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/Observables.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/Observables.java
@@ -132,6 +132,7 @@
 	 *            the observable's value type
 	 * @return an immutable observable value with the given constant value
 	 * @since 1.1
+	 * @deprecated use constantObservableValue(Realm, T, Class<T>) instead
 	 */
 	public static <T> IObservableValue<T> constantObservableValue(Realm realm,
 			T value, Object valueType) {
@@ -147,6 +148,25 @@
 	 *            the observable's realm
 	 * @param value
 	 *            the observable's constant value
+	 * @param valueType
+	 *            the observable's value type
+	 * @return an immutable observable value with the given constant value
+	 * @since 1.5
+	 */
+	public static <T> IObservableValue<T> constantObservableValue(Realm realm,
+			T value, Class<T> valueType) {
+		return new ConstantObservableValue<T>(realm, value, valueType);
+	}
+
+	/**
+	 * Returns an observable value with the given constant value.
+	 * 
+	 * @param <T>
+	 * 
+	 * @param realm
+	 *            the observable's realm
+	 * @param value
+	 *            the observable's constant value
 	 * @return an immutable observable value with the given constant value
 	 * @since 1.1
 	 */
@@ -575,7 +595,7 @@
 			}
 
 			public synchronized void addListChangeListener(
-					IListChangeListener<E> listener) {
+					IListChangeListener<? super E> listener) {
 			}
 		};
 	}
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/AbstractObservableList.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/AbstractObservableList.java
index be75267..0d98055 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/AbstractObservableList.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/AbstractObservableList.java
@@ -102,14 +102,14 @@
 	}
 
 	public synchronized void addListChangeListener(
-			IListChangeListener<E> listener) {
+			IListChangeListener<? super E> listener) {
 		if (!disposed) {
 			changeSupport.addListener(ListChangeEvent.TYPE, listener);
 		}
 	}
 
 	public synchronized void removeListChangeListener(
-			IListChangeListener<E> listener) {
+			IListChangeListener<? super E> listener) {
 		if (!disposed) {
 			changeSupport.removeListener(ListChangeEvent.TYPE, listener);
 		}
@@ -380,4 +380,25 @@
 		Assert.isTrue(getRealm().isCurrent(),
 				"This operation must be run within the observable's realm"); //$NON-NLS-1$
 	}
+
+	/**
+	 * This is a default implementation that should ideally be overridden to use
+	 * a properly typed Class field. This implementation checks to see if the
+	 * element type is of type Class and, if it is, it assumes it is the class
+	 * of the elements and makes an unchecked cast.
+	 * <P>
+	 * This method should always be overridden to provide an implementation that
+	 * never returns null.
+	 * 
+	 * @return the class of the elements, if possible, or null if this is not
+	 *         possible
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
+		Object elementType = getElementType();
+		if (elementType instanceof Class) {
+			return (Class<E>) elementType;
+		}
+		return null;
+	}
 }
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ComputedList.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ComputedList.java
index b327717..15acee2 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ComputedList.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ComputedList.java
@@ -311,7 +311,7 @@
 	}
 
 	public synchronized void addListChangeListener(
-			IListChangeListener<E> listener) {
+			IListChangeListener<? super E> listener) {
 		super.addListChangeListener(listener);
 		// If somebody is listening, we need to make sure we attach our own
 		// listeners
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/DecoratingObservableList.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/DecoratingObservableList.java
index a4a6f9e..b0c74a7 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/DecoratingObservableList.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/DecoratingObservableList.java
@@ -47,12 +47,12 @@
 	}
 
 	public synchronized void addListChangeListener(
-			IListChangeListener<E> listener) {
+			IListChangeListener<? super E> listener) {
 		addListener(ListChangeEvent.TYPE, listener);
 	}
 
 	public synchronized void removeListChangeListener(
-			IListChangeListener<E> listener) {
+			IListChangeListener<? super E> listener) {
 		removeListener(ListChangeEvent.TYPE, listener);
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/IObservableList.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/IObservableList.java
index 84c76ad..e6b7483 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/IObservableList.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/IObservableList.java
@@ -43,7 +43,7 @@
 	 * 
 	 * @param listener
 	 */
-	public void addListChangeListener(IListChangeListener<E> listener);
+	public void addListChangeListener(IListChangeListener<? super E> listener);
 
 	/**
 	 * Removes the given list change listener from the list of list change
@@ -52,7 +52,7 @@
 	 * 
 	 * @param listener
 	 */
-	public void removeListChangeListener(IListChangeListener<E> listener);
+	public void removeListChangeListener(IListChangeListener<? super E> listener);
 
 	/**
 	 * @TrackedGetter
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ListChangeEvent.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ListChangeEvent.java
index 1254f89..214d310 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ListChangeEvent.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ListChangeEvent.java
@@ -41,7 +41,7 @@
 	 * Always identical to <code>EventObject.source</code> but the type
 	 * information is maintained.
 	 */
-	private IObservableList<E> typedSource;
+	private IObservableList<? extends E> typedSource;
 
 	/**
 	 * Creates a new list change event.
@@ -62,7 +62,7 @@
 	 * 
 	 * @return the observable list from which this event originated
 	 */
-	public IObservableList<E> getObservableList() {
+	public IObservableList<? extends E> getObservableList() {
 		return typedSource;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/MultiList.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/MultiList.java
index 7a95e0a..7989a8b 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/MultiList.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/MultiList.java
@@ -105,6 +105,7 @@
 	 *            the observable's realm
 	 * @param lists
 	 *            the array of observable lists backing this MultiList
+	 * @deprecated use MultiList(realm, List<IObservableList<E>>) instead
 	 */
 	public MultiList(Realm realm, IObservableList<E>[] lists) {
 		this(realm, lists, null);
@@ -118,6 +119,20 @@
 	 *            the observable's realm
 	 * @param lists
 	 *            the array of observable lists backing this MultiList
+	 * @since 1.5
+	 */
+	public MultiList(Realm realm, List<IObservableList<E>> lists) {
+		this(realm, lists, null);
+	}
+
+	/**
+	 * Constructs a MultiList belonging to the given realm, and backed by the
+	 * given observable lists.
+	 * 
+	 * @param realm
+	 *            the observable's realm
+	 * @param lists
+	 *            the array of observable lists backing this MultiList
 	 * @param elementType
 	 *            element type of the constructed list.
 	 * @deprecated use MultiList(realm, List<IObservableList<E>>, Object)
@@ -224,7 +239,7 @@
 	}
 
 	private void listChanged(ListChangeEvent<E> event) {
-		IObservableList<E> source = event.getObservableList();
+		IObservableList<? extends E> source = event.getObservableList();
 		int offset = 0;
 		for (IObservableList<E> list : lists) {
 			if (source == list) {
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ObservableList.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ObservableList.java
index 655970d..6feb2c5 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ObservableList.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/ObservableList.java
@@ -48,26 +48,72 @@
 	 */
 	private boolean stale = false;
 
-	private Object elementType;
+	private Object elementTypeAsObject;
 
+	private Class<E> elementType;
+
+	/**
+	 * 
+	 * @param wrappedList
+	 * @param elementType
+	 * @deprecated use instead the form of the constructor that takes Class as
+	 *             the parameter type for the element type
+	 */
 	protected ObservableList(List<E> wrappedList, Object elementType) {
 		this(Realm.getDefault(), wrappedList, elementType);
 	}
 
+	/**
+	 * @param wrappedList
+	 * @param elementType
+	 * @since 1.5
+	 */
+	protected ObservableList(List<E> wrappedList, Class<E> elementType) {
+		this(Realm.getDefault(), wrappedList, elementType);
+	}
+
+	/**
+	 * 
+	 * @param realm
+	 * @param wrappedList
+	 * @param elementType
+	 * @deprecated use instead the form of the constructor that takes Class as
+	 *             the parameter type for the element type
+	 */
 	protected ObservableList(Realm realm, List<E> wrappedList,
 			Object elementType) {
 		super(realm);
 		this.wrappedList = wrappedList;
+		this.elementTypeAsObject = elementType;
+		if (elementType instanceof Class) {
+			this.elementType = (Class<E>) elementType;
+		} else {
+			this.elementType = null;
+		}
+	}
+
+	/**
+	 * 
+	 * @param realm
+	 * @param wrappedList
+	 * @param elementType
+	 * @since 1.5
+	 */
+	protected ObservableList(Realm realm, List<E> wrappedList,
+			Class<E> elementType) {
+		super(realm);
+		this.wrappedList = wrappedList;
+		this.elementTypeAsObject = elementType;
 		this.elementType = elementType;
 	}
 
 	public synchronized void addListChangeListener(
-			IListChangeListener<E> listener) {
+			IListChangeListener<? super E> listener) {
 		addListener(ListChangeEvent.TYPE, listener);
 	}
 
 	public synchronized void removeListChangeListener(
-			IListChangeListener<E> listener) {
+			IListChangeListener<? super E> listener) {
 		removeListener(ListChangeEvent.TYPE, listener);
 	}
 
@@ -227,10 +273,17 @@
 		}
 		return new AbstractObservableList<E>(getRealm()) {
 
+			/**
+			 * @deprecated use getElementClass instead
+			 */
 			public Object getElementType() {
 				return ObservableList.this.getElementType();
 			}
 
+			public Class<E> getElementClass() {
+				return ObservableList.this.getElementClass();
+			}
+
 			public E get(int location) {
 				return ObservableList.this.get(fromIndex + location);
 			}
@@ -360,7 +413,17 @@
 		super.dispose();
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
+		return elementTypeAsObject;
+	}
+
+	/**
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
 		return elementType;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/map/AbstractObservableMap.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/map/AbstractObservableMap.java
index 3e8c754..83034da 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/map/AbstractObservableMap.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/map/AbstractObservableMap.java
@@ -251,4 +251,46 @@
 		Assert.isTrue(getRealm().isCurrent(),
 				"This operation must be run within the observable's realm"); //$NON-NLS-1$
 	}
+
+	/**
+	 * This is a default implementation that should ideally be overridden to use
+	 * a properly typed Class field. This implementation checks to see if the
+	 * key type is of type Class and, if it is, it assumes it is the class of
+	 * the keys and makes an unchecked cast.
+	 * <P>
+	 * This method should always be overridden to provide an implementation that
+	 * never returns null.
+	 * 
+	 * @return the class of the keys, if possible, or null if this is not
+	 *         possible
+	 * @since 1.5
+	 */
+	public Class<K> getKeyClass() {
+		Object keyType = getKeyType();
+		if (keyType instanceof Class) {
+			return (Class<K>) keyType;
+		}
+		return null;
+	}
+
+	/**
+	 * This is a default implementation that should ideally be overridden to use
+	 * a properly typed Class field. This implementation checks to see if the
+	 * value type is of type Class and, if it is, it assumes it is the class of
+	 * the values and makes an unchecked cast.
+	 * <P>
+	 * This method should always be overridden to provide an implementation that
+	 * never returns null.
+	 * 
+	 * @return the class of the values, if possible, or null if this is not
+	 *         possible
+	 * @since 1.5
+	 */
+	public Class<V> getValueClass() {
+		Object valueType = getKeyType();
+		if (valueType instanceof Class) {
+			return (Class<V>) valueType;
+		}
+		return null;
+	}
 }
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/set/AbstractObservableSet.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/set/AbstractObservableSet.java
index 7a46c87..13694f4 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/set/AbstractObservableSet.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/set/AbstractObservableSet.java
@@ -195,4 +195,25 @@
 		throw new RuntimeException(
 				"fireChange should not be called, use fireSetChange() instead"); //$NON-NLS-1$
 	}
+
+	/**
+	 * This is a default implementation that should ideally be overridden to use
+	 * a properly typed Class field. This implementation checks to see if the
+	 * element type is of type Class and, if it is, it assumes it is the class
+	 * of the elements and makes an unchecked cast.
+	 * <P>
+	 * This method should always be overridden to provide an implementation that
+	 * never returns null.
+	 * 
+	 * @return the class of the elements, if possible, or null if this is not
+	 *         possible
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
+		Object elementType = getElementType();
+		if (elementType instanceof Class) {
+			return (Class<E>) elementType;
+		}
+		return null;
+	}
 }
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/set/ObservableSet.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/set/ObservableSet.java
index 3b4b49d..746d9ec 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/set/ObservableSet.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/set/ObservableSet.java
@@ -42,16 +42,70 @@
 
 	private boolean stale = false;
 
+	/**
+	 * @deprecated use getElementClass() instead
+	 */
 	protected Object elementType;
 
+	/**
+	 * @since 1.5
+	 */
+	private Class<E> elementClass;
+
+	/**
+	 * 
+	 * @param wrappedSet
+	 * @param elementType
+	 * @deprecated use instead the form of the constructor that takes Class as
+	 *             the parameter type for the element type
+	 */
 	protected ObservableSet(Set<E> wrappedSet, Object elementType) {
 		this(Realm.getDefault(), wrappedSet, elementType);
 	}
 
+	/**
+	 * 
+	 * @param wrappedSet
+	 * @param elementType
+	 * @since 1.5
+	 */
+	protected ObservableSet(Set<E> wrappedSet, Class<E> elementType) {
+		this(Realm.getDefault(), wrappedSet, elementType);
+	}
+
+	/**
+	 * 
+	 * @param realm
+	 * @param wrappedSet
+	 * @param elementType
+	 * @deprecated use instead the form of the constructor that takes Class as
+	 *             the parameter type for the element type
+	 */
 	protected ObservableSet(Realm realm, Set<E> wrappedSet, Object elementType) {
 		super(realm);
 		this.wrappedSet = wrappedSet;
 		this.elementType = elementType;
+		if (elementType instanceof Class) {
+			this.elementClass = (Class<E>) elementType;
+		} else {
+			this.elementClass = null;
+		}
+	}
+
+	/**
+	 * 
+	 * @param realm
+	 * @param wrappedSet
+	 * @param elementType
+	 * @since 1.5
+	 */
+	// We must set deprecated fields in case any one uses them
+	@SuppressWarnings("deprecation")
+	protected ObservableSet(Realm realm, Set<E> wrappedSet, Class<E> elementType) {
+		super(realm);
+		this.wrappedSet = wrappedSet;
+		this.elementType = elementType;
+		this.elementClass = elementType;
 	}
 
 	public synchronized void addSetChangeListener(
@@ -205,7 +259,17 @@
 		super.dispose();
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return elementType;
 	}
+
+	/**
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
+		return elementClass;
+	}
 }
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/AbstractObservableValue.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/AbstractObservableValue.java
index 96766fc..e0e5c0e 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/AbstractObservableValue.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/AbstractObservableValue.java
@@ -46,12 +46,12 @@
 	}
 
 	public synchronized void addValueChangeListener(
-			IValueChangeListener<T> listener) {
+			IValueChangeListener<? super T> listener) {
 		addListener(ValueChangeEvent.TYPE, listener);
 	}
 
 	public synchronized void removeValueChangeListener(
-			IValueChangeListener<T> listener) {
+			IValueChangeListener<? super T> listener) {
 		removeListener(ValueChangeEvent.TYPE, listener);
 	}
 
@@ -90,10 +90,28 @@
 
 	private void getterCalled() {
 		ObservableTracker.getterCalled(this);
+
 	}
 
 	protected void fireChange() {
 		throw new RuntimeException(
 				"fireChange should not be called, use fireValueChange() instead"); //$NON-NLS-1$
 	}
+
+	/**
+	 * This is a default implementation that should ideally be overridden to use
+	 * a properly typed Class field. This implementation checks to see if the
+	 * value type is of type Class and, if it is, it assumes it is the class of
+	 * the values and makes an unchecked cast.
+	 * 
+	 * @return Class to which values of this observable are constrained
+	 * @since 1.5
+	 */
+	public Class<T> getValueClass() {
+		Object valueType = getValueType();
+		if (valueType instanceof Class) {
+			return (Class<T>) valueType;
+		}
+		return null;
+	}
 }
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/ComputedValue.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/ComputedValue.java
index bd405f3..c01ade3 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/ComputedValue.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/ComputedValue.java
@@ -285,7 +285,7 @@
 	}
 
 	public synchronized void addValueChangeListener(
-			IValueChangeListener<T> listener) {
+			IValueChangeListener<? super T> listener) {
 		super.addValueChangeListener(listener);
 		// If somebody is listening, we need to make sure we attach our own
 		// listeners
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/DecoratingObservableValue.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/DecoratingObservableValue.java
index 154d66d..11a4c43 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/DecoratingObservableValue.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/DecoratingObservableValue.java
@@ -42,12 +42,12 @@
 	}
 
 	public synchronized void addValueChangeListener(
-			IValueChangeListener<T> listener) {
+			IValueChangeListener<? super T> listener) {
 		addListener(ValueChangeEvent.TYPE, listener);
 	}
 
 	public synchronized void removeValueChangeListener(
-			IValueChangeListener<T> listener) {
+			IValueChangeListener<? super T> listener) {
 		removeListener(ValueChangeEvent.TYPE, listener);
 	}
 
@@ -109,6 +109,13 @@
 		return decorated.getValueType();
 	}
 
+	/**
+	 * @since 1.5
+	 */
+	public Class<T> getValueClass() {
+		return decorated.getValueClass();
+	}
+
 	public synchronized void dispose() {
 		if (decorated != null && valueChangeListener != null) {
 			decorated.removeValueChangeListener(valueChangeListener);
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/DuplexingObservableValue.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/DuplexingObservableValue.java
index 346051b..093ff18 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/DuplexingObservableValue.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/DuplexingObservableValue.java
@@ -197,7 +197,7 @@
 	}
 
 	public synchronized void addValueChangeListener(
-			IValueChangeListener<T> listener) {
+			IValueChangeListener<? super T> listener) {
 		super.addValueChangeListener(listener);
 		// If somebody is listening, we need to make sure we attach our own
 		// listeners
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/IObservableValue.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/IObservableValue.java
index beafb3d..b3bc49a 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/IObservableValue.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/value/IObservableValue.java
@@ -42,6 +42,15 @@
 	public Object getValueType();
 
 	/**
+	 * The value class of this observable value, or <code>Object.class</code> if
+	 * this observable value is untyped.
+	 * 
+	 * @return the value type, never null
+	 * @since 1.5
+	 */
+	public Class<T> getValueClass();
+
+	/**
 	 * Returns the value. Must be invoked in the {@link Realm} of the
 	 * observable.
 	 * 
@@ -64,10 +73,11 @@
 	 * 
 	 * @param listener
 	 */
-	public void addValueChangeListener(IValueChangeListener<T> listener);
+	public void addValueChangeListener(IValueChangeListener<? super T> listener);
 
 	/**
 	 * @param listener
 	 */
-	public void removeValueChangeListener(IValueChangeListener<T> listener);
+	public void removeValueChangeListener(
+			IValueChangeListener<? super T> listener);
 }
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityObservableSet.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityObservableSet.java
index b09ef4e..394f619 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityObservableSet.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityObservableSet.java
@@ -39,9 +39,40 @@
  */
 public class IdentityObservableSet<E> extends AbstractObservableSet<E> {
 	private Set<E> wrappedSet;
+
+	/**
+	 * @deprecated use getElementClass() instead
+	 */
 	private Object elementType;
 
 	/**
+	 * @since 1.5
+	 */
+	private Class<E> elementClass;
+
+	/**
+	 * Constructs an IdentityObservableSet on the given {@link Realm}.
+	 * 
+	 * @param realm
+	 *            the realm of the constructed set.
+	 * @param elementType
+	 *            the element type of the constructed set.
+	 * @deprecated use instead the form of the constructor that takes Class as
+	 *             the parameter type for the element type
+	 */
+	public IdentityObservableSet(Realm realm, Object elementType) {
+		super(realm);
+
+		this.wrappedSet = new IdentitySet<E>();
+		this.elementType = elementType;
+		if (elementType instanceof Class) {
+			this.elementClass = (Class<E>) elementType;
+		} else {
+			this.elementClass = null;
+		}
+	}
+
+	/**
 	 * Constructs an IdentityObservableSet on the given {@link Realm}.
 	 * 
 	 * @param realm
@@ -49,21 +80,34 @@
 	 * @param elementType
 	 *            the element type of the constructed set.
 	 */
-	public IdentityObservableSet(Realm realm, Object elementType) {
+	// We must set deprecated fields in case any one uses them
+	@SuppressWarnings("deprecation")
+	public IdentityObservableSet(Realm realm, Class<E> elementType) {
 		super(realm);
 
 		this.wrappedSet = new IdentitySet<E>();
 		this.elementType = elementType;
+		this.elementClass = elementType;
 	}
 
 	protected Set<E> getWrappedSet() {
 		return wrappedSet;
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return elementType;
 	}
 
+	/**
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
+		return elementClass;
+	}
+
 	public Iterator<E> iterator() {
 		getterCalled();
 		final Iterator<E> wrappedIterator = wrappedSet.iterator();
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/ConstantObservableValue.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/ConstantObservableValue.java
index d98a524..996bb53 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/ConstantObservableValue.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/ConstantObservableValue.java
@@ -31,7 +31,22 @@
 public class ConstantObservableValue<T> implements IObservableValue<T> {
 	final Realm realm;
 	final T value;
-	final Object type;
+	final Object typeAsObject;
+	final Class<T> type;
+
+	/**
+	 * Construct a constant value of the given type, in the default realm.
+	 * 
+	 * @param value
+	 *            immutable value
+	 * @param type
+	 *            type
+	 * @deprecated use the form of the constructor that takes a Class parameter
+	 *             for the type
+	 */
+	public ConstantObservableValue(T value, Object type) {
+		this(Realm.getDefault(), value, type);
+	}
 
 	/**
 	 * Construct a constant value of the given type, in the default realm.
@@ -41,7 +56,7 @@
 	 * @param type
 	 *            type
 	 */
-	public ConstantObservableValue(T value, Object type) {
+	public ConstantObservableValue(T value, Class<T> type) {
 		this(Realm.getDefault(), value, type);
 	}
 
@@ -54,16 +69,42 @@
 	 *            immutable value
 	 * @param type
 	 *            type
+	 * @deprecated use the form of the constructor that takes a Class parameter
+	 *             for the type
 	 */
 	public ConstantObservableValue(Realm realm, T value, Object type) {
 		Assert.isNotNull(realm, "Realm cannot be null"); //$NON-NLS-1$
 		this.realm = realm;
 		this.value = value;
+		this.typeAsObject = type;
+		this.type = null;
+		ObservableTracker.observableCreated(this);
+	}
+
+	/**
+	 * Construct a constant value of the given type, in the given realm.
+	 * 
+	 * @param realm
+	 *            Realm
+	 * @param value
+	 *            immutable value
+	 * @param type
+	 *            type
+	 */
+	public ConstantObservableValue(Realm realm, T value, Class<T> type) {
+		Assert.isNotNull(realm, "Realm cannot be null"); //$NON-NLS-1$
+		this.realm = realm;
+		this.value = value;
+		this.typeAsObject = type;
 		this.type = type;
 		ObservableTracker.observableCreated(this);
 	}
 
 	public Object getValueType() {
+		return typeAsObject;
+	}
+
+	public Class<T> getValueClass() {
 		return type;
 	}
 
@@ -76,11 +117,12 @@
 		throw new UnsupportedOperationException();
 	}
 
-	public void addValueChangeListener(IValueChangeListener<T> listener) {
+	public void addValueChangeListener(IValueChangeListener<? super T> listener) {
 		// ignore
 	}
 
-	public void removeValueChangeListener(IValueChangeListener<T> listener) {
+	public void removeValueChangeListener(
+			IValueChangeListener<? super T> listener) {
 		// ignore
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/EmptyObservableList.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/EmptyObservableList.java
index 531d2b5..b06b5dd 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/EmptyObservableList.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/EmptyObservableList.java
@@ -37,9 +37,18 @@
 	private final List<E> emptyList = Collections.emptyList();
 
 	private final Realm realm;
+
+	/**
+	 * @deprecated use getElementClass() instead
+	 */
 	private Object elementType;
 
 	/**
+	 * @since 1.5
+	 */
+	private Class<E> elementClass;
+
+	/**
 	 * Creates an empty list. This list may be disposed multiple times without
 	 * any side-effects.
 	 * 
@@ -59,25 +68,61 @@
 	 * @param elementType
 	 *            the element type of the constructed list
 	 * @since 1.1
+	 * @deprecated use instead the form of the constructor that takes Class as
+	 *             the parameter type for the element type
 	 */
 	public EmptyObservableList(Realm realm, Object elementType) {
 		this.realm = realm;
 		this.elementType = elementType;
+		if (elementType instanceof Class) {
+			this.elementClass = (Class<E>) elementType;
+		} else {
+			this.elementClass = null;
+		}
 		ObservableTracker.observableCreated(this);
 	}
 
-	public void addListChangeListener(IListChangeListener<E> listener) {
+	/**
+	 * Creates an empty list. This list may be disposed multiple times without
+	 * any side-effects.
+	 * 
+	 * @param realm
+	 *            the realm of the constructed list
+	 * @param elementType
+	 *            the element type of the constructed list
+	 * @since 1.1
+	 */
+	// We must set deprecated fields in case any one uses them
+	@SuppressWarnings("deprecation")
+	public EmptyObservableList(Realm realm, Class<E> elementType) {
+		this.realm = realm;
+		this.elementType = elementType;
+		this.elementClass = elementType;
+		ObservableTracker.observableCreated(this);
+	}
+
+	public void addListChangeListener(IListChangeListener<? super E> listener) {
 		// ignore
 	}
 
-	public void removeListChangeListener(IListChangeListener<E> listener) {
+	public void removeListChangeListener(IListChangeListener<? super E> listener) {
 		// ignore
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return elementType;
 	}
 
+	/**
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
+		return elementClass;
+	}
+
 	public int size() {
 		checkRealm();
 		return 0;
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/EmptyObservableSet.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/EmptyObservableSet.java
index bc3aea9..506f179 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/EmptyObservableSet.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/observable/EmptyObservableSet.java
@@ -36,9 +36,18 @@
 	private final Set<E> emptySet = Collections.emptySet();
 
 	private final Realm realm;
+
+	/**
+	 * @deprecated use getElementClass() instead
+	 */
 	private Object elementType;
 
 	/**
+	 * @since 1.5
+	 */
+	private Class<E> elementClass;
+
+	/**
 	 * Creates a singleton empty set. This set may be disposed multiple times
 	 * without any side-effects.
 	 * 
@@ -58,10 +67,36 @@
 	 * @param elementType
 	 *            the element type of the constructed set
 	 * @since 1.1
+	 * @deprecated use instead the form of the constructor that takes Class as
+	 *             the parameter type for the element type
 	 */
 	public EmptyObservableSet(Realm realm, Object elementType) {
 		this.realm = realm;
 		this.elementType = elementType;
+		if (elementType instanceof Class) {
+			this.elementClass = (Class<E>) elementType;
+		} else {
+			this.elementClass = null;
+		}
+		ObservableTracker.observableCreated(this);
+	}
+
+	/**
+	 * Creates a singleton empty set. This set may be disposed multiple times
+	 * without any side-effects.
+	 * 
+	 * @param realm
+	 *            the realm of the constructed set
+	 * @param elementType
+	 *            the element type of the constructed set
+	 * @since 1.1
+	 */
+	// We must set deprecated fields in case any one uses them
+	@SuppressWarnings("deprecation")
+	public EmptyObservableSet(Realm realm, Class<E> elementType) {
+		this.realm = realm;
+		this.elementType = elementType;
+		this.elementClass = elementType;
 		ObservableTracker.observableCreated(this);
 	}
 
@@ -71,10 +106,20 @@
 	public void removeSetChangeListener(ISetChangeListener<? super E> listener) {
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return elementType;
 	}
 
+	/**
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
+		return elementClass;
+	}
+
 	public int size() {
 		checkRealm();
 		return 0;
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/Properties.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/Properties.java
index 28b0e43..4047d48 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/Properties.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/Properties.java
@@ -143,8 +143,24 @@
 	 *            the value type of the property
 	 * @return a value property which takes the source object itself as the
 	 *         property value.
+	 * @deprecated use the form that takes a Class instead
 	 */
-	public static <T> IValueProperty<T, T> selfValue(T valueType) {
+	public static <T> IValueProperty<T, T> selfValue(Object valueType) {
+		return new SelfValueProperty<T>(valueType);
+	}
+
+	/**
+	 * Returns a value property which takes the source object itself as the
+	 * property value. This property may be used to wrap an object in an
+	 * unmodifiable {@link IObservableValue}.
+	 * 
+	 * @param valueType
+	 *            the value type of the property
+	 * @return a value property which takes the source object itself as the
+	 *         property value.
+	 * @since 1.5
+	 */
+	public static <T> IValueProperty<T, T> selfValue(Class<T> valueType) {
 		return new SelfValueProperty<T>(valueType);
 	}
 
@@ -157,12 +173,28 @@
 	 *            the element type of the property
 	 * @return a list property which takes the source object (a {@link List}) as
 	 *         the property list.
+	 * @deprecated use the form that takes a Class instead
 	 */
 	public static <E> IListProperty<List<E>, E> selfList(Object elementType) {
 		return new SelfListProperty<E>(elementType);
 	}
 
 	/**
+	 * Returns a list property which takes the source object (a {@link List}) as
+	 * the property list. This property may be used to wrap an arbitrary List
+	 * instance in an {@link IObservableList}.
+	 * 
+	 * @param elementType
+	 *            the element type of the property
+	 * @return a list property which takes the source object (a {@link List}) as
+	 *         the property list.
+	 * @since 1.5
+	 */
+	public static <E> IListProperty<List<E>, E> selfList(Class<E> elementType) {
+		return new SelfListProperty<E>(elementType);
+	}
+
+	/**
 	 * Returns a set property which takes the source object (a {@link Set}) as
 	 * the property set. This property may be used to wrap an arbitrary Set
 	 * instance in an {@link IObservableSet}.
@@ -171,12 +203,29 @@
 	 *            the element type of the property
 	 * @return a set property which takes the source object (a {@link Set}) as
 	 *         the property set.
+	 * @since 1.5
+	 * @deprecated use the form that takes a Class instead
 	 */
 	public static <E> ISetProperty<Set<E>, E> selfSet(Object elementType) {
 		return new SelfSetProperty<E>(elementType);
 	}
 
 	/**
+	 * Returns a set property which takes the source object (a {@link Set}) as
+	 * the property set. This property may be used to wrap an arbitrary Set
+	 * instance in an {@link IObservableSet}.
+	 * 
+	 * @param elementType
+	 *            the element type of the property
+	 * @return a set property which takes the source object (a {@link Set}) as
+	 *         the property set.
+	 * @since 1.5
+	 */
+	public static <E> ISetProperty<Set<E>, E> selfSet(Class<E> elementType) {
+		return new SelfSetProperty<E>(elementType);
+	}
+
+	/**
 	 * Returns a map property which takes the source object (a {@link Map}) as
 	 * the property map. This property may be used to wrap an arbitrary Map
 	 * instance in an {@link IObservableMap}.
@@ -207,6 +256,27 @@
 	 *            the value type of the property
 	 * @return a value property which observes the value of an
 	 *         {@link IObservableValue}.
+	 * @deprecated use the form that takes a Class instead
+	 */
+	public static <T> IValueProperty<IObservableValue<T>, T> observableValue(
+			Object valueType) {
+		return new ObservableValueProperty<T>(valueType);
+	}
+
+	/**
+	 * Returns a value property which observes the value of an
+	 * {@link IObservableValue}. This property may be used e.g. for observing
+	 * the respective values of an {@link IObservableList} &lt;
+	 * {@link IObservableValue} &gt;.
+	 * <p>
+	 * Calls to {@link IValueProperty#observe(Object)} or
+	 * {@link IValueProperty#observe(Realm, Object)} just cast the argument to
+	 * {@link IObservableValue} and return it (the realm argument is ignored).
+	 * 
+	 * @param valueType
+	 *            the value type of the property
+	 * @return a value property which observes the value of an
+	 *         {@link IObservableValue}.
 	 * @since 1.5
 	 */
 	public static <T> IValueProperty<IObservableValue<T>, T> observableValue(
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/DelegatingListProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/DelegatingListProperty.java
index eca14a1..c00a166 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/DelegatingListProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/DelegatingListProperty.java
@@ -31,14 +31,35 @@
  */
 public abstract class DelegatingListProperty<S, E> extends ListProperty<S, E> {
 	private final IListProperty<S, E> nullProperty;
-	private final Object elementType;
+	private final Class<E> elementType;
+	private final Object elementTypeAsObject;
 
 	protected DelegatingListProperty() {
 		this(null);
 	}
 
+	/**
+	 * 
+	 * @param elementType
+	 * @deprecated use the constructor which takes Class as a parameter. This is
+	 *             safer because code in this plug-in fails anyway if a Class is
+	 *             not passed.
+	 * 
+	 */
 	protected DelegatingListProperty(Object elementType) {
+		//		throw new IllegalArgumentException("elementType must be a Class object"); //$NON-NLS-1$
+		this.elementType = null;
+		this.elementTypeAsObject = elementType;
+		this.nullProperty = new NullListProperty();
+	}
+
+	/**
+	 * @param elementType
+	 * @since 1.5
+	 */
+	protected DelegatingListProperty(Class<E> elementType) {
 		this.elementType = elementType;
+		this.elementTypeAsObject = elementType;
 		this.nullProperty = new NullListProperty();
 	}
 
@@ -69,9 +90,20 @@
 	 *            the property source
 	 * @return the property to delegate to for the specified source object.
 	 */
-	protected abstract IListProperty<S, E> doGetDelegate(Object source);
+	protected abstract IListProperty<S, E> doGetDelegate(S source);
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
+		return elementTypeAsObject;
+	}
+
+	/**
+	 * @return the class of the elements in the list
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
 		return elementType;
 	}
 
@@ -97,6 +129,10 @@
 
 	private class NullListProperty extends SimpleListProperty<S, E> {
 		public Object getElementType() {
+			return elementTypeAsObject;
+		}
+
+		public Class<E> getElementClass() {
 			return elementType;
 		}
 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/IListProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/IListProperty.java
index cb19347..97c9631 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/IListProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/IListProperty.java
@@ -40,15 +40,25 @@
  */
 public interface IListProperty<S, E> extends IProperty {
 	/**
-	 * Returns the type of the elements in the collection or <code>null</code>
-	 * if untyped
+	 * Returns the type of the elements in the list or <code>null</code> if
+	 * untyped
 	 * 
-	 * @return the type of the elements in the collection or <code>null</code>
-	 *         if untyped
+	 * @return the type of the elements in the list or <code>null</code> if
+	 *         untyped
+	 * @deprecated use getElementClass instead
 	 */
 	public Object getElementType();
 
 	/**
+	 * Returns the type of the elements in the list or <code>Object.class</code>
+	 * if untyped
+	 * 
+	 * @return the type of the elements in the list
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass();
+
+	/**
 	 * Returns an unmodifiable List with the current contents of the source's
 	 * list property
 	 * 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/ListProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/ListProperty.java
index 6a63ca2..5cab869 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/ListProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/ListProperty.java
@@ -151,11 +151,32 @@
 	public <U extends S> IObservableList<E> observeDetail(
 			IObservableValue<U> master) {
 		return MasterDetailObservables.detailList(master,
-				listFactory(master.getRealm()), getElementType());
+				listFactory(master.getRealm()), getElementClass());
 	}
 
 	public final <T> IListProperty<S, T> values(
 			IValueProperty<? super E, T> detailValue) {
 		return new ListPropertyDetailValuesList<S, E, T>(this, detailValue);
 	}
+
+	/**
+	 * This is a default implementation that should ideally be overridden to use
+	 * a properly typed Class field. This implementation checks to see if the
+	 * element type is of type Class and, if it is, it assumes it is the class
+	 * of the elements and makes an unchecked cast.
+	 * <P>
+	 * This method should always be overridden to provide an implementation that
+	 * never returns null.
+	 * 
+	 * @return the class of the elements, if possible, or null if this is not
+	 *         possible
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
+		Object elementType = getElementType();
+		if (elementType instanceof Class) {
+			return (Class<E>) elementType;
+		}
+		return null;
+	}
 }
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/MultiListProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/MultiListProperty.java
index b1069fb..cd0150b 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/MultiListProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/MultiListProperty.java
@@ -35,7 +35,8 @@
  */
 public class MultiListProperty<S, E> extends ListProperty<S, E> {
 	private IListProperty<S, E>[] properties;
-	private Object elementType;
+	private Object elementTypeAsObject;
+	private Class<E> elementType;
 
 	/**
 	 * Constructs a MultiListProperty for observing the specified list
@@ -60,10 +61,30 @@
 	public MultiListProperty(IListProperty<S, E>[] properties,
 			Object elementType) {
 		this.properties = properties;
+		this.elementTypeAsObject = elementType;
+		this.elementType = null;
+	}
+
+	/**
+	 * @param properties
+	 * @param elementType
+	 * @since 1.5
+	 */
+	public MultiListProperty(IListProperty<S, E>[] properties,
+			Class<E> elementType) {
+		this.properties = properties;
+		this.elementTypeAsObject = elementType;
 		this.elementType = elementType;
 	}
 
 	public Object getElementType() {
+		return elementTypeAsObject;
+	}
+
+	/**
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
 		return elementType;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/SimpleListProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/SimpleListProperty.java
index 9e58d61..1c1f384 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/SimpleListProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/list/SimpleListProperty.java
@@ -31,7 +31,7 @@
  * <p>
  * Subclasses must implement these methods:
  * <ul>
- * <li> {@link #getElementType()}
+ * <li> {@link #getElementClass()}
  * <li> {@link #doGetList(Object)}
  * <li> {@link #doSetList(Object, List, ListDiff)}
  * <li> {@link #adaptListener(ISimplePropertyListener)}
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/DelegatingMapProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/DelegatingMapProperty.java
index d2fef6f..d6195c3 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/DelegatingMapProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/DelegatingMapProperty.java
@@ -33,17 +33,45 @@
  */
 public abstract class DelegatingMapProperty<S, K, V> extends
 		MapProperty<S, K, V> {
-	private final Object keyType;
-	private final Object valueType;
+	private final Object keyTypeAsObject;
+	private final Object valueTypeAsObject;
+	private final Class<K> keyType;
+	private final Class<V> valueType;
 	private final IMapProperty<S, K, V> nullProperty = new NullMapProperty();
 
 	protected DelegatingMapProperty() {
-		this(null, null);
+		this.keyType = null;
+		this.valueType = null;
+		this.keyTypeAsObject = null;
+		this.valueTypeAsObject = null;
 	}
 
+	/**
+	 * 
+	 * @param keyType
+	 * @param valueType
+	 * @deprecated use the constructor which takes Class as parameters. This is
+	 *             safer because code in this plug-in fails anyway if a Class is
+	 *             not passed.
+	 */
 	protected DelegatingMapProperty(Object keyType, Object valueType) {
+		this.keyType = null;
+		this.valueType = null;
+		this.keyTypeAsObject = keyType;
+		this.valueTypeAsObject = valueType;
+	}
+
+	/**
+	 * 
+	 * @param keyType
+	 * @param valueType
+	 * @since 1.5
+	 */
+	protected DelegatingMapProperty(Class<K> keyType, Class<V> valueType) {
 		this.keyType = keyType;
 		this.valueType = valueType;
+		this.keyTypeAsObject = keyType;
+		this.valueTypeAsObject = valueType;
 	}
 
 	/**
@@ -73,13 +101,33 @@
 	 *            the property source
 	 * @return the property to delegate to for the specified source object.
 	 */
-	protected abstract IMapProperty<S, K, V> doGetDelegate(Object source);
+	protected abstract IMapProperty<S, K, V> doGetDelegate(S source);
 
+	/**
+	 * @deprecated use getKeyClass instead
+	 */
 	public Object getKeyType() {
+		return keyTypeAsObject;
+	}
+
+	/**
+	 * @since 1.5
+	 */
+	public Class<K> getKeyClass() {
 		return keyType;
 	}
 
+	/**
+	 * @deprecated use getValueClass instead
+	 */
 	public Object getValueType() {
+		return valueTypeAsObject;
+	}
+
+	/**
+	 * @since 1.5
+	 */
+	public Class<V> getValueClass() {
 		return valueType;
 	}
 
@@ -123,10 +171,18 @@
 		}
 
 		public Object getKeyType() {
-			return keyType;
+			return keyTypeAsObject;
 		}
 
 		public Object getValueType() {
+			return valueTypeAsObject;
+		}
+
+		public Class<K> getKeyClass() {
+			return keyType;
+		}
+
+		public Class<V> getValueClass() {
 			return valueType;
 		}
 	}
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/IMapProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/IMapProperty.java
index 4ae9d40..379d3a8 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/IMapProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/IMapProperty.java
@@ -47,19 +47,41 @@
 	 * 
 	 * @return the element type of the map's key set or <code>null</code> if the
 	 *         key set is untyped.
+	 * @deprecated use getKeyClass instead
 	 */
 	public Object getKeyType();
 
 	/**
+	 * Returns the element type of the map's key set or <code>null</code> if the
+	 * key set is untyped.
+	 * 
+	 * @return the element type of the map's key set or <code>null</code> if the
+	 *         key set is untyped.
+	 * @since 1.5
+	 */
+	public Class<K> getKeyClass();
+
+	/**
 	 * Returns the element type of the map's values collection or
 	 * <code>null</code> if the collection is untyped.
 	 * 
 	 * @return the element type of the map's values collection or
 	 *         <code>null</code> if the collection is untyped.
+	 * @deprecated use getValueClass instead
 	 */
 	public Object getValueType();
 
 	/**
+	 * Returns the element type of the map's values collection or
+	 * <code>null</code> if the collection is untyped.
+	 * 
+	 * @return the element type of the map's values collection or
+	 *         <code>null</code> if the collection is untyped.
+	 * @since 1.5
+	 */
+	public Class<V> getValueClass();
+
+	/**
 	 * Returns an unmodifiable Map with the current contents of the source's map
 	 * property.
 	 * 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/MapProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/MapProperty.java
index a406a4d..c65eb3b 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/MapProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/MapProperty.java
@@ -155,11 +155,22 @@
 	public <U extends S> IObservableMap<K, V> observeDetail(
 			IObservableValue<U> master) {
 		return MasterDetailObservables.detailMap(master,
-				mapFactory(master.getRealm()), getKeyType(), getValueType());
+				mapFactory(master.getRealm()), getKeyClass(), getValueClass());
 	}
 
 	public final <T> IMapProperty<S, K, T> values(
 			IValueProperty<? super V, T> detailValues) {
 		return new MapPropertyDetailValuesMap<S, K, V, T>(this, detailValues);
 	}
+
+	// public Class<K> getKeyClass() {
+	// if (getKeyType() instanceof Class) {
+	// return (Class)getKeyType();
+	// }
+	// return null;
+	// }
+	//
+	// public Class<V> getValueClass() {
+	// return null;
+	// }
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/SimpleMapProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/SimpleMapProperty.java
index eb6f658..c916836 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/SimpleMapProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/map/SimpleMapProperty.java
@@ -31,8 +31,8 @@
  * <p>
  * Subclasses must implement these methods:
  * <ul>
- * <li> {@link #getKeyType()}
- * <li> {@link #getValueType()}
+ * <li> {@link #getKeyClass()}
+ * <li> {@link #getValueClass()}
  * <li> {@link #doGetMap(Object)}
  * <li> {@link #doSetMap(Object, Map, MapDiff)}
  * <li> {@link #adaptListener(ISimplePropertyListener)}
@@ -118,7 +118,6 @@
 	 *         specified listener, or null if the source object has no listener
 	 *         APIs for this property.
 	 * @noreference This method is not intended to be referenced by clients.
-	 * @since 1.5
 	 */
 	public abstract INativePropertyListener<S> adaptListener(
 			ISimplePropertyListener<MapDiff<K, V>> listener);
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/DelegatingSetProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/DelegatingSetProperty.java
index 19689ec..9a7de44 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/DelegatingSetProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/DelegatingSetProperty.java
@@ -30,15 +30,34 @@
  * 
  */
 public abstract class DelegatingSetProperty<S, E> extends SetProperty<S, E> {
-	private final Object elementType;
+	private final Class<E> elementType;
+	private final Object elementTypeAsObject;
 	private final ISetProperty<S, E> nullProperty = new NullSetProperty();
 
 	protected DelegatingSetProperty() {
 		this(null);
 	}
 
+	/**
+	 * 
+	 * @param elementType
+	 * @deprecated use the constructor which takes Class as a parameter. This is
+	 *             safer because code in this plug-in fails anyway if a Class is
+	 *             not passed.
+	 * 
+	 */
 	protected DelegatingSetProperty(Object elementType) {
+		this.elementType = null;
+		this.elementTypeAsObject = elementType;
+	}
+
+	/**
+	 * @param elementType
+	 * @since 1.5
+	 */
+	protected DelegatingSetProperty(Class<E> elementType) {
 		this.elementType = elementType;
+		this.elementTypeAsObject = elementType;
 	}
 
 	/**
@@ -50,7 +69,7 @@
 	 *            the property source (may be null)
 	 * @return the property to delegate to for the specified source object.
 	 */
-	protected final ISetProperty<S, E> getDelegate(Object source) {
+	protected final ISetProperty<S, E> getDelegate(S source) {
 		if (source == null)
 			return nullProperty;
 		ISetProperty<S, E> delegate = doGetDelegate(source);
@@ -68,9 +87,20 @@
 	 *            the property source
 	 * @return the property to delegate to for the specified source object.
 	 */
-	protected abstract ISetProperty<S, E> doGetDelegate(Object source);
+	protected abstract ISetProperty<S, E> doGetDelegate(S source);
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
+		return elementTypeAsObject;
+	}
+
+	/**
+	 * @return the class of the elements in the set
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
 		return elementType;
 	}
 
@@ -96,6 +126,10 @@
 
 	private class NullSetProperty extends SimpleSetProperty<S, E> {
 		public Object getElementType() {
+			return elementTypeAsObject;
+		}
+
+		public Class<E> getElementClass() {
 			return elementType;
 		}
 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/ISetProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/ISetProperty.java
index 40a8b63..5312f63 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/ISetProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/ISetProperty.java
@@ -42,15 +42,25 @@
  */
 public interface ISetProperty<S, E> extends IProperty {
 	/**
-	 * Returns the type of the elements in the collection or <code>null</code>
-	 * if untyped
+	 * Returns the type of the elements in the set or <code>null</code> if
+	 * untyped
 	 * 
-	 * @return the type of the elements in the collection or <code>null</code>
-	 *         if untyped
+	 * @return the type of the elements in the set or <code>null</code> if
+	 *         untyped
+	 * @deprecated use getElementClass instead
 	 */
 	public Object getElementType();
 
 	/**
+	 * Returns the type of the elements in the set or <code>Object.class</code>
+	 * if untyped
+	 * 
+	 * @return the type of the elements in the set
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass();
+
+	/**
 	 * Returns an unmodifiable Set with the current contents of the source's set
 	 * property
 	 * 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/SetProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/SetProperty.java
index b52a40e..2bf113d 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/SetProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/SetProperty.java
@@ -53,7 +53,7 @@
 	 * 
 	 * @since 1.3
 	 */
-	public final Set<E> getSet(S source) {
+	public Set<E> getSet(S source) {
 		if (source == null) {
 			return Collections.emptySet();
 		}
@@ -152,11 +152,32 @@
 	public <U extends S> IObservableSet<E> observeDetail(
 			IObservableValue<U> master) {
 		return MasterDetailObservables.detailSet(master,
-				setFactory(master.getRealm()), getElementType());
+				setFactory(master.getRealm()), getElementClass());
 	}
 
 	public final <T> IMapProperty<S, E, T> values(
 			IValueProperty<? super E, T> detailValues) {
 		return new SetPropertyDetailValuesMap<S, E, T>(this, detailValues);
 	}
+
+	/**
+	 * This is a default implementation that should ideally be overridden to use
+	 * a properly typed Class field. This implementation checks to see if the
+	 * element type is of type Class and, if it is, it assumes it is the class
+	 * of the elements and makes an unchecked cast.
+	 * <P>
+	 * This method should always be overridden to provide an implementation that
+	 * never returns null.
+	 * 
+	 * @return the class of the elements, if possible, or null if this is not
+	 *         possible
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
+		Object elementType = getElementType();
+		if (elementType instanceof Class) {
+			return (Class<E>) elementType;
+		}
+		return null;
+	}
 }
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/SimpleSetProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/SimpleSetProperty.java
index 85ae508..1793db6 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/SimpleSetProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/SimpleSetProperty.java
@@ -31,7 +31,7 @@
  * <p>
  * Subclasses must implement these methods:
  * <ul>
- * <li> {@link #getElementType()}
+ * <li> {@link #getElementClass()}
  * <li> {@link #doGetSet(Object)}
  * <li> {@link #doSetSet(Object, Set, SetDiff)}
  * <li> {@link #adaptListener(ISimplePropertyListener)}
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/UnionSetProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/UnionSetProperty.java
index 7b7a081..0a47fbb 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/UnionSetProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/set/UnionSetProperty.java
@@ -32,7 +32,8 @@
  */
 public class UnionSetProperty<S, E> extends SetProperty<S, E> {
 	private final ISetProperty<S, E>[] properties;
-	private final Object elementType;
+	private final Object elementTypeAsObject;
+	private final Class<E> elementType;
 
 	/**
 	 * @param properties
@@ -44,13 +45,34 @@
 	/**
 	 * @param properties
 	 * @param elementType
+	 * @deprecated use the constuctor that takes a Class instead
 	 */
 	public UnionSetProperty(ISetProperty<S, E>[] properties, Object elementType) {
 		this.properties = properties;
+		this.elementTypeAsObject = elementType;
+		this.elementType = null;
+	}
+
+	/**
+	 * @param properties
+	 * @param elementType
+	 * @since 1.5
+	 */
+	public UnionSetProperty(ISetProperty<S, E>[] properties,
+			Class<E> elementType) {
+		this.properties = properties;
+		this.elementTypeAsObject = elementType;
 		this.elementType = elementType;
 	}
 
 	public Object getElementType() {
+		return elementTypeAsObject;
+	}
+
+	/**
+	 * @since 1.5
+	 */
+	public Class<E> getElementClass() {
 		return elementType;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/DelegatingValueProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/DelegatingValueProperty.java
index 1b6d616..46ce915 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/DelegatingValueProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/DelegatingValueProperty.java
@@ -33,15 +33,31 @@
  * 
  */
 public abstract class DelegatingValueProperty<S, T> extends ValueProperty<S, T> {
-	private final Object valueType;
+	private final Object valueTypeAsObject;
+	private final Class<T> valueType;
 	private final IValueProperty<S, T> nullProperty = new NullValueProperty();
 
 	protected DelegatingValueProperty() {
 		this(null);
 	}
 
+	/**
+	 * 
+	 * @param valueType
+	 * @deprecated use the constructor that takes a Class object instead
+	 */
 	protected DelegatingValueProperty(Object valueType) {
+		this.valueType = null;
+		this.valueTypeAsObject = valueType;
+	}
+
+	/**
+	 * @param valueType
+	 * @since 1.5
+	 */
+	protected DelegatingValueProperty(Class<T> valueType) {
 		this.valueType = valueType;
+		this.valueTypeAsObject = valueType;
 	}
 
 	/**
@@ -82,6 +98,13 @@
 	}
 
 	public Object getValueType() {
+		return valueTypeAsObject;
+	}
+
+	/**
+	 * @since 1.5
+	 */
+	public Class<T> getValueClass() {
 		return valueType;
 	}
 
@@ -113,6 +136,10 @@
 			return valueType;
 		}
 
+		public Class<T> getValueClass() {
+			return valueType;
+		}
+
 		protected T doGetValue(S source) {
 			return null;
 		}
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/IValueProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/IValueProperty.java
index f811ea1..f2523c1 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/IValueProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/IValueProperty.java
@@ -45,10 +45,21 @@
 	 * Returns the value type of the property, or <code>null</code> if untyped.
 	 * 
 	 * @return the value type of the property, or <code>null</code> if untyped.
+	 * @deprecated use getValueClass instead
 	 */
 	public Object getValueType();
 
 	/**
+	 * Returns the value type of the property, or <code>Object.class</code> if
+	 * untyped.
+	 * 
+	 * @return the value type of the property, or <code>Object.class</code> if
+	 *         untyped.
+	 * @since 1.5
+	 */
+	public Class<T> getValueClass();
+
+	/**
 	 * Returns the current value of this property on the specified property
 	 * source.
 	 * 
@@ -172,8 +183,8 @@
 	 *         the current value of this property for the elements in the given
 	 *         map's values collection
 	 */
-	public <K, V extends S> IObservableMap<K, T> observeDetail(
-			IObservableMap<K, V> master);
+	public <K, M extends S> IObservableMap<K, T> observeDetail(
+			IObservableMap<K, M> master);
 
 	/**
 	 * Returns the nested combination of this property and the specified detail
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/SimpleValueProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/SimpleValueProperty.java
index dc19526..2adc71d 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/SimpleValueProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/SimpleValueProperty.java
@@ -32,7 +32,7 @@
  * <p>
  * Subclasses must implement these methods:
  * <ul>
- * <li> {@link #getValueType()}
+ * <li> {@link #getValueClass()}
  * <li> {@link #doGetValue(Object)}
  * <li> {@link #doSetValue(Object, Object)}
  * <li> {@link #adaptListener(ISimplePropertyListener)}
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/ValueProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/ValueProperty.java
index 9ff7220..e99ca7e 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/ValueProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/databinding/property/value/ValueProperty.java
@@ -178,4 +178,23 @@
 			IMapProperty<? super T, K, V> detailMap) {
 		return new ValuePropertyDetailMap<S, T, K, V>(this, detailMap);
 	}
+
+	/**
+	 * This is a default implementation that should ideally be overridden to use
+	 * a properly typed Class field. This implementation checks to see if the
+	 * value type is of type Class and, if it is, it assumes it is the class of
+	 * the values and makes an unchecked cast.
+	 * <P>
+	 * This method should always be overridden to provide an implementation that
+	 * never returns null.
+	 * 
+	 * @since 1.5
+	 */
+	public Class<T> getValueClass() {
+		Object valueType = getValueType();
+		if (valueType instanceof Class) {
+			return (Class<T>) valueType;
+		}
+		return null;
+	}
 }
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ListPropertyDetailValuesList.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ListPropertyDetailValuesList.java
index d864bfe..57b9b3a 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ListPropertyDetailValuesList.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ListPropertyDetailValuesList.java
@@ -54,6 +54,10 @@
 		return detailProperty.getValueType();
 	}
 
+	public Class<E> getElementClass() {
+		return detailProperty.getValueClass();
+	}
+
 	protected List<E> doGetList(S source) {
 		List<T> masterList = masterProperty.getList(source);
 		List<E> detailList = new ArrayList<E>(masterList.size());
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/MapPropertyDetailValuesMap.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/MapPropertyDetailValuesMap.java
index 69e1a29..62a836c 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/MapPropertyDetailValuesMap.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/MapPropertyDetailValuesMap.java
@@ -53,12 +53,26 @@
 		this.detailProperty = detailProperty;
 	}
 
+	/**
+	 * @deprecated use getValueClass instead
+	 */
+	public Object getValueType() {
+		return detailProperty.getValueType();
+	}
+
+	/**
+	 * @deprecated use getKeyClass instead
+	 */
 	public Object getKeyType() {
 		return masterProperty.getKeyType();
 	}
 
-	public Object getValueType() {
-		return detailProperty.getValueType();
+	public Class<K> getKeyClass() {
+		return masterProperty.getKeyClass();
+	}
+
+	public Class<T> getValueClass() {
+		return detailProperty.getValueClass();
 	}
 
 	protected Map<K, T> doGetMap(S source) {
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/SetPropertyDetailValuesMap.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/SetPropertyDetailValuesMap.java
index 4b336c6..b3791a7 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/SetPropertyDetailValuesMap.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/SetPropertyDetailValuesMap.java
@@ -52,14 +52,28 @@
 		this.detailProperty = detailProperty;
 	}
 
+	/**
+	 * @deprecated use getKeyClass instead
+	 */
 	public Object getKeyType() {
 		return masterProperty.getElementType();
 	}
 
+	/**
+	 * @deprecated use getValueClass instead
+	 */
 	public Object getValueType() {
 		return detailProperty.getValueType();
 	}
 
+	public Class<M> getKeyClass() {
+		return masterProperty.getElementClass();
+	}
+
+	public Class<T> getValueClass() {
+		return detailProperty.getValueClass();
+	}
+
 	protected Map<M, T> doGetMap(S source) {
 		Set<M> set = masterProperty.getSet(source);
 		Map<M, T> map = new IdentityMap<M, T>();
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailList.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailList.java
index 6658b05..f2e0655 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailList.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailList.java
@@ -48,10 +48,17 @@
 		this.detailProperty = detailProperty;
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return detailProperty.getElementType();
 	}
 
+	public Class<T> getElementClass() {
+		return detailProperty.getElementClass();
+	}
+
 	protected List<T> doGetList(S source) {
 		M masterValue = masterProperty.getValue(source);
 		return detailProperty.getList(masterValue);
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailMap.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailMap.java
index 993bc55..63f7d52 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailMap.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailMap.java
@@ -50,14 +50,28 @@
 		this.detailProperty = detailProperty;
 	}
 
+	/**
+	 * @deprecated use getKeyClass instead
+	 */
 	public Object getKeyType() {
 		return detailProperty.getKeyType();
 	}
 
+	/**
+	 * @deprecated use getValueClass instead
+	 */
 	public Object getValueType() {
 		return detailProperty.getValueType();
 	}
 
+	public Class<K> getKeyClass() {
+		return detailProperty.getKeyClass();
+	}
+
+	public Class<V> getValueClass() {
+		return detailProperty.getValueClass();
+	}
+
 	protected Map<K, V> doGetMap(S source) {
 		M masterValue = masterProperty.getValue(source);
 		return detailProperty.getMap(masterValue);
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailSet.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailSet.java
index 55e3e2d..7c11c0f 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailSet.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailSet.java
@@ -49,10 +49,17 @@
 		this.detailProperty = detailProperty;
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return detailProperty.getElementType();
 	}
 
+	public Class<T> getElementClass() {
+		return detailProperty.getElementClass();
+	}
+
 	protected Set<T> doGetSet(S source) {
 		M masterValue = masterProperty.getValue(source);
 		return detailProperty.getSet(masterValue);
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailValue.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailValue.java
index c81ad87..df8a4e0 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailValue.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/ValuePropertyDetailValue.java
@@ -52,6 +52,10 @@
 		return detailProperty.getValueType();
 	}
 
+	public Class<T> getValueClass() {
+		return detailProperty.getValueClass();
+	}
+
 	protected T doGetValue(S source) {
 		M masterValue = masterProperty.getValue(source);
 		return detailProperty.getValue(masterValue);
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/list/SelfListProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/list/SelfListProperty.java
index 1d0e444..c65fe17 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/list/SelfListProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/list/SelfListProperty.java
@@ -26,16 +26,31 @@
  * 
  */
 public class SelfListProperty<E> extends SimpleListProperty<List<E>, E> {
-	private final Object elementType;
+	private final Object elementTypeAsObject;
+	private final Class<E> elementType;
+
+	/**
+	 * @param elementType
+	 * @deprecated use the constructor that takes a Class instead
+	 */
+	public SelfListProperty(Object elementType) {
+		this.elementTypeAsObject = elementType;
+		this.elementType = null;
+	}
 
 	/**
 	 * @param elementType
 	 */
-	public SelfListProperty(Object elementType) {
+	public SelfListProperty(Class<E> elementType) {
+		this.elementTypeAsObject = elementType;
 		this.elementType = elementType;
 	}
 
 	public Object getElementType() {
+		return elementTypeAsObject;
+	}
+
+	public Class<E> getElementClass() {
 		return elementType;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/list/SimplePropertyObservableList.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/list/SimplePropertyObservableList.java
index 409c314..5bc4c10 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/list/SimplePropertyObservableList.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/list/SimplePropertyObservableList.java
@@ -116,10 +116,20 @@
 		ObservableTracker.getterCalled(this);
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return property.getElementType();
 	}
 
+	/**
+	 * @return the type of the elements
+	 */
+	public Class<E> getElementClass() {
+		return property.getElementClass();
+	}
+
 	// Queries
 
 	private List<E> getList() {
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SelfMapProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SelfMapProperty.java
index 5bb5005..438e075 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SelfMapProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SelfMapProperty.java
@@ -29,23 +29,47 @@
  */
 public final class SelfMapProperty<K, V> extends
 		SimpleMapProperty<Map<K, V>, K, V> {
-	private final Object keyType;
-	private final Object valueType;
+	private final Object keyTypeAsObject;
+	private final Object valueTypeAsObject;
+	private final Class<K> keyType;
+	private final Class<V> valueType;
+
+	/**
+	 * @param keyType
+	 * @param valueType
+	 * @deprecated use the constructor that takes Class parameters instead
+	 */
+	public SelfMapProperty(Object keyType, Object valueType) {
+		this.keyTypeAsObject = keyType;
+		this.valueTypeAsObject = valueType;
+		this.keyType = null;
+		this.valueType = null;
+	}
 
 	/**
 	 * @param keyType
 	 * @param valueType
 	 */
-	public SelfMapProperty(Object keyType, Object valueType) {
+	public SelfMapProperty(Class<K> keyType, Class<V> valueType) {
+		this.keyTypeAsObject = keyType;
+		this.valueTypeAsObject = valueType;
 		this.keyType = keyType;
 		this.valueType = valueType;
 	}
 
 	public Object getKeyType() {
-		return keyType;
+		return keyTypeAsObject;
 	}
 
 	public Object getValueType() {
+		return valueTypeAsObject;
+	}
+
+	public Class<K> getKeyClass() {
+		return keyType;
+	}
+
+	public Class<V> getValueClass() {
 		return valueType;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/set/SelfSetProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/set/SelfSetProperty.java
index 839dde1..38655d8 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/set/SelfSetProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/set/SelfSetProperty.java
@@ -26,16 +26,31 @@
  * 
  */
 public final class SelfSetProperty<E> extends SimpleSetProperty<Set<E>, E> {
-	private final Object elementType;
+	private final Object elementTypeAsObject;
+	private final Class<E> elementType;
+
+	/**
+	 * @param elementType
+	 * @deprecated use the constructor that takes a Class instead
+	 */
+	public SelfSetProperty(Object elementType) {
+		this.elementTypeAsObject = elementType;
+		this.elementType = null;
+	}
 
 	/**
 	 * @param elementType
 	 */
-	public SelfSetProperty(Object elementType) {
+	public SelfSetProperty(Class<E> elementType) {
+		this.elementTypeAsObject = elementType;
 		this.elementType = elementType;
 	}
 
 	public Object getElementType() {
+		return elementTypeAsObject;
+	}
+
+	public Class<E> getElementClass() {
 		return elementType;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/set/SimplePropertyObservableSet.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/set/SimplePropertyObservableSet.java
index b989f65..4b81121 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/set/SimplePropertyObservableSet.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/set/SimplePropertyObservableSet.java
@@ -113,10 +113,20 @@
 		return getSet();
 	}
 
+	/**
+	 * @deprecated use getElementClass instead
+	 */
 	public Object getElementType() {
 		return property.getElementType();
 	}
 
+	/**
+	 * @return the type of the elements
+	 */
+	public Class<E> getElementClass() {
+		return property.getElementClass();
+	}
+
 	// Queries
 
 	private Set<E> getSet() {
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/ObservableValueProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/ObservableValueProperty.java
index eb203e1..185cef0 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/ObservableValueProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/ObservableValueProperty.java
@@ -40,16 +40,33 @@
  */
 public class ObservableValueProperty<T> extends
 		SimpleValueProperty<IObservableValue<T>, T> {
-	private final Object valueType;
+	private final Object valueTypeAsObject;
+	private final Class<T> valueType;
+
+	/**
+	 * 
+	 * @param valueType
+	 * @deprecated use the constructor that takes a Class object instead
+	 */
+	public ObservableValueProperty(Object valueType) {
+		this.valueType = null;
+		this.valueTypeAsObject = valueType;
+	}
 
 	/**
 	 * @param valueType
+	 * @since 1.5
 	 */
-	public ObservableValueProperty(Object valueType) {
+	public ObservableValueProperty(Class<T> valueType) {
 		this.valueType = valueType;
+		this.valueTypeAsObject = valueType;
 	}
 
 	public Object getValueType() {
+		return valueTypeAsObject;
+	}
+
+	public Class<T> getValueClass() {
 		return valueType;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/SelfValueProperty.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/SelfValueProperty.java
index dc92b99..bac3820 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/SelfValueProperty.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/SelfValueProperty.java
@@ -23,16 +23,31 @@
  * 
  */
 public final class SelfValueProperty<T> extends SimpleValueProperty<T, T> {
-	private final Object valueType;
+	private final Object valueTypeAsObject;
+	private final Class<T> valueType;
+
+	/**
+	 * @param valueType
+	 * @deprecated use the constructor that takes a Class instead
+	 */
+	public SelfValueProperty(Object valueType) {
+		this.valueTypeAsObject = valueType;
+		this.valueType = null;
+	}
 
 	/**
 	 * @param valueType
 	 */
-	public SelfValueProperty(Object valueType) {
+	public SelfValueProperty(Class<T> valueType) {
+		this.valueTypeAsObject = valueType;
 		this.valueType = valueType;
 	}
 
 	public Object getValueType() {
+		return valueTypeAsObject;
+	}
+
+	public Class<T> getValueClass() {
 		return valueType;
 	}
 
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/SimplePropertyObservableValue.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/SimplePropertyObservableValue.java
index e4c34b0..e83b5c4 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/SimplePropertyObservableValue.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/SimplePropertyObservableValue.java
@@ -126,10 +126,17 @@
 		}
 	}
 
+	/**
+	 * @deprecated use getValueClass instead
+	 */
 	public Object getValueType() {
 		return property.getValueType();
 	}
 
+	public Class<T> getValueClass() {
+		return property.getValueClass();
+	}
+
 	public Object getObserved() {
 		return source;
 	}
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/BindingProperties.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/BindingProperties.java
index 940bf10..7e5083f 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/BindingProperties.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/BindingProperties.java
@@ -118,9 +118,10 @@
 	/**
 	 * Returns an {@link IValueProperty} whose value results from applying the
 	 * given {@link IConverter} on the source object of the value property.
-	 * Consequently, the {@link IValueProperty#getValueType() value type} of the
-	 * returned property is the same as the {@link IConverter#getToType() target
-	 * type} of the converter. Setting a value on the property is not supported.
+	 * Consequently, the {@link IValueProperty#getValueClass() value type} of
+	 * the returned property is the same as the {@link IConverter#getToType()
+	 * target type} of the converter. Setting a value on the property is not
+	 * supported.
 	 * 
 	 * @param converter
 	 *            The converter to apply to the source object of the value
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/DataBindingContext.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/DataBindingContext.java
index 58fad1c..4ea796c 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/DataBindingContext.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/databinding/DataBindingContext.java
@@ -127,8 +127,14 @@
 	 * @since 1.2
 	 */
 	public final <T> Binding<?, ?> bindValue(
-			IObservableValue<T> targetObservableValue,
-			IObservableValue<T> modelObservableValue) {
+			IObservableValue<?> targetObservableValue,
+			IObservableValue<?> modelObservableValue) {
+		/*
+		 * The observable values should be parameterized with T. However that
+		 * would require a little work as consumer code would have to be updated
+		 * to make the types match, and it does not cope with the default
+		 * conversions correctly.
+		 */
 		return bindValue(targetObservableValue, modelObservableValue, null,
 				null);
 	}
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/BindingModelProperty.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/BindingModelProperty.java
index 63cc3de..81c9b0d 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/BindingModelProperty.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/BindingModelProperty.java
@@ -28,6 +28,10 @@
 		return IObservable.class;
 	}
 
+	public Class<IObservable> getValueClass() {
+		return IObservable.class;
+	}
+
 	protected IObservable doGetValue(Binding<?, ?> source) {
 		return source.getModel();
 	}
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/BindingTargetProperty.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/BindingTargetProperty.java
index 3c5d66e..ff924a1 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/BindingTargetProperty.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/BindingTargetProperty.java
@@ -28,6 +28,10 @@
 		return IObservable.class;
 	}
 
+	public Class<IObservable> getValueClass() {
+		return IObservable.class;
+	}
+
 	protected IObservable doGetValue(Binding<?, ?> source) {
 		return source.getTarget();
 	}
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ConverterValueProperty.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ConverterValueProperty.java
index dcf693c..c11a15b 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ConverterValueProperty.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ConverterValueProperty.java
@@ -46,6 +46,10 @@
 		return converter.getToType();
 	}
 
+	public Class<T> getValueClass() {
+		return (Class<T>) converter.getToType();
+	}
+
 	public T getValue(S source) {
 		// We do also pass null values to the converter.
 		return doGetValue(source);
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/DataBindingContextBindingsProperty.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/DataBindingContextBindingsProperty.java
index 355f972..6b0ac74 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/DataBindingContextBindingsProperty.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/DataBindingContextBindingsProperty.java
@@ -30,6 +30,10 @@
 		return Binding.class;
 	}
 
+	public Class<Binding<?, ?>> getElementClass() {
+		return (Class<Binding<?, ?>>) getElementType();
+	}
+
 	protected List<Binding<?, ?>> doGetList(DataBindingContext source) {
 		return source.getBindings();
 	}
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/DataBindingContextValidationStatusProvidersProperty.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/DataBindingContextValidationStatusProvidersProperty.java
index b9e6f08..d078ffb 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/DataBindingContextValidationStatusProvidersProperty.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/DataBindingContextValidationStatusProvidersProperty.java
@@ -30,6 +30,10 @@
 		return ValidationStatusProvider.class;
 	}
 
+	public Class<ValidationStatusProvider> getElementClass() {
+		return ValidationStatusProvider.class;
+	}
+
 	protected List<ValidationStatusProvider> doGetList(DataBindingContext source) {
 		return source.getValidationStatusProviders();
 	}
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderModelsProperty.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderModelsProperty.java
index d72228b..4e186d8 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderModelsProperty.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderModelsProperty.java
@@ -31,6 +31,10 @@
 		return IObservable.class;
 	}
 
+	public Class<IObservable> getElementClass() {
+		return IObservable.class;
+	}
+
 	protected List<IObservable> doGetList(ValidationStatusProvider source) {
 		return Collections.unmodifiableList(source.getModels());
 	}
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderTargetsProperty.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderTargetsProperty.java
index 22f2e15..bbd29db 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderTargetsProperty.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderTargetsProperty.java
@@ -31,6 +31,10 @@
 		return IObservable.class;
 	}
 
+	public Class<IObservable> getElementClass() {
+		return IObservable.class;
+	}
+
 	protected List<IObservable> doGetList(ValidationStatusProvider source) {
 		return Collections.unmodifiableList(source.getTargets());
 	}
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderValidationStatusProperty.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderValidationStatusProperty.java
index 2a380c2..8f1aa80 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderValidationStatusProperty.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/ValidationStatusProviderValidationStatusProperty.java
@@ -30,6 +30,10 @@
 		return IObservableValue.class;
 	}
 
+	public Class<IObservableValue<IStatus>> getValueClass() {
+		return (Class<IObservableValue<IStatus>>) getValueType();
+	}
+
 	protected IObservableValue<IStatus> doGetValue(
 			ValidationStatusProvider source) {
 		return source.getValidationStatus();
diff --git a/bundles/org.eclipse.jface.databinding/.classpath b/bundles/org.eclipse.jface.databinding/.classpath
index c2ce266..64c5e31 100644
--- a/bundles/org.eclipse.jface.databinding/.classpath
+++ b/bundles/org.eclipse.jface.databinding/.classpath
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/CDC-1.0%Foundation-1.0"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="output" path="bin"/>
diff --git a/bundles/org.eclipse.jface.databinding/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.jface.databinding/.settings/org.eclipse.jdt.core.prefs
index c42c217..8df57c2 100644
--- a/bundles/org.eclipse.jface.databinding/.settings/org.eclipse.jdt.core.prefs
+++ b/bundles/org.eclipse.jface.databinding/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,3 @@
-#Thu Feb 05 11:36:06 MST 2009
 eclipse.preferences.version=1
 org.eclipse.jdt.core.builder.cleanOutputFolder=clean
 org.eclipse.jdt.core.builder.duplicateResourceTask=warning
@@ -16,9 +15,9 @@
 org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
 org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.3
+org.eclipse.jdt.core.compiler.compliance=1.5
 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
 org.eclipse.jdt.core.compiler.debug.localVariable=generate
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -51,11 +50,12 @@
 org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
 org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
 org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
 org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
@@ -95,7 +95,7 @@
 org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
 org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
 org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.3
+org.eclipse.jdt.core.compiler.source=1.5
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
diff --git a/bundles/org.eclipse.jface.databinding/META-INF/MANIFEST.MF b/bundles/org.eclipse.jface.databinding/META-INF/MANIFEST.MF
index 31cceb7..429a65d 100644
--- a/bundles/org.eclipse.jface.databinding/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.jface.databinding/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jface.databinding
-Bundle-Version: 1.6.200.qualifier
+Bundle-Version: 1.7.0.qualifier
 Bundle-ClassPath: .
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
@@ -24,5 +24,4 @@
  org.eclipse.core.databinding.observable;bundle-version="[1.3.0,2.0.0)",
  org.eclipse.core.databinding.property;bundle-version="[1.3.0,2.0.0)",
  org.eclipse.core.databinding;bundle-version="[1.2.0,2.0.0)"
-Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0,
- J2SE-1.3
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/bundles/org.eclipse.jface.databinding/pom.xml b/bundles/org.eclipse.jface.databinding/pom.xml
index cad6913..2d67290 100644
--- a/bundles/org.eclipse.jface.databinding/pom.xml
+++ b/bundles/org.eclipse.jface.databinding/pom.xml
@@ -18,6 +18,6 @@
   </parent>
   <groupId>org.eclipse.jface</groupId>
   <artifactId>org.eclipse.jface.databinding</artifactId>
-  <version>1.6.200-SNAPSHOT</version>
+  <version>1.7.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java
index aa9eca7..4383843 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java
@@ -16,6 +16,7 @@
 package org.eclipse.jface.databinding.dialog;
 
 import java.util.Iterator;
+import java.util.List;
 
 import org.eclipse.core.databinding.DataBindingContext;
 import org.eclipse.core.databinding.ValidationStatusProvider;
@@ -69,47 +70,47 @@
 	private DialogPage dialogPage;
 	private DataBindingContext dbc;
 	private IValidationMessageProvider messageProvider = new ValidationMessageProvider();
-	private IObservableValue aggregateStatusProvider;
+	private IObservableValue<ValidationStatusProvider> aggregateStatusProvider;
 	private boolean uiChanged = false;
 	private IChangeListener uiChangeListener = new IChangeListener() {
 		public void handleChange(ChangeEvent event) {
 			handleUIChanged();
 		}
 	};
-	private IListChangeListener validationStatusProvidersListener = new IListChangeListener() {
-		public void handleListChange(ListChangeEvent event) {
-			ListDiff diff = event.diff;
-			ListDiffEntry[] differences = diff.getDifferences();
-			for (int i = 0; i < differences.length; i++) {
-				ListDiffEntry listDiffEntry = differences[i];
-				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) listDiffEntry
+	private IListChangeListener<ValidationStatusProvider> validationStatusProvidersListener = new IListChangeListener<ValidationStatusProvider>() {
+		public void handleListChange(
+				ListChangeEvent<ValidationStatusProvider> event) {
+			ListDiff<ValidationStatusProvider> diff = event.diff;
+			List<ListDiffEntry<ValidationStatusProvider>> differences = diff
+					.getDifferencesAsList();
+			for (ListDiffEntry<ValidationStatusProvider> listDiffEntry : differences) {
+				ValidationStatusProvider validationStatusProvider = listDiffEntry
 						.getElement();
-				IObservableList targets = validationStatusProvider.getTargets();
+				IObservableList<IObservable> targets = validationStatusProvider
+						.getTargets();
 				if (listDiffEntry.isAddition()) {
-					targets
-							.addListChangeListener(validationStatusProviderTargetsListener);
-					for (Iterator it = targets.iterator(); it.hasNext();) {
-						((IObservable) it.next())
-								.addChangeListener(uiChangeListener);
+					targets.addListChangeListener(validationStatusProviderTargetsListener);
+					for (Iterator<IObservable> it = targets.iterator(); it
+							.hasNext();) {
+						it.next().addChangeListener(uiChangeListener);
 					}
 				} else {
-					targets
-							.removeListChangeListener(validationStatusProviderTargetsListener);
-					for (Iterator it = targets.iterator(); it.hasNext();) {
-						((IObservable) it.next())
-								.removeChangeListener(uiChangeListener);
+					targets.removeListChangeListener(validationStatusProviderTargetsListener);
+					for (Iterator<IObservable> it = targets.iterator(); it
+							.hasNext();) {
+						(it.next()).removeChangeListener(uiChangeListener);
 					}
 				}
 			}
 		}
 	};
-	private IListChangeListener validationStatusProviderTargetsListener = new IListChangeListener() {
-		public void handleListChange(ListChangeEvent event) {
-			ListDiff diff = event.diff;
-			ListDiffEntry[] differences = diff.getDifferences();
-			for (int i = 0; i < differences.length; i++) {
-				ListDiffEntry listDiffEntry = differences[i];
-				IObservable target = (IObservable) listDiffEntry.getElement();
+	private IListChangeListener<IObservable> validationStatusProviderTargetsListener = new IListChangeListener<IObservable>() {
+		public void handleListChange(ListChangeEvent<IObservable> event) {
+			ListDiff<IObservable> diff = event.diff;
+			List<ListDiffEntry<IObservable>> differences = diff
+					.getDifferencesAsList();
+			for (ListDiffEntry<IObservable> listDiffEntry : differences) {
+				IObservable target = listDiffEntry.getElement();
 				if (listDiffEntry.isAddition()) {
 					target.addChangeListener(uiChangeListener);
 				} else {
@@ -172,8 +173,9 @@
 		}
 
 		aggregateStatusProvider
-				.addValueChangeListener(new IValueChangeListener() {
-					public void handleValueChange(ValueChangeEvent event) {
+				.addValueChangeListener(new IValueChangeListener<ValidationStatusProvider>() {
+					public void handleValueChange(
+							ValueChangeEvent<ValidationStatusProvider> event) {
 						statusProviderChanged();
 					}
 				});
@@ -191,25 +193,24 @@
 		statusProviderChanged();
 		dbc.getValidationStatusProviders().addListChangeListener(
 				validationStatusProvidersListener);
-		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
-				.hasNext();) {
-			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
-					.next();
-			IObservableList targets = validationStatusProvider.getTargets();
-			targets
-					.addListChangeListener(validationStatusProviderTargetsListener);
-			for (Iterator iter = targets.iterator(); iter.hasNext();) {
-				((IObservable) iter.next()).addChangeListener(uiChangeListener);
+		for (Iterator<ValidationStatusProvider> it = dbc
+				.getValidationStatusProviders().iterator(); it.hasNext();) {
+			ValidationStatusProvider validationStatusProvider = it.next();
+			IObservableList<IObservable> targets = validationStatusProvider
+					.getTargets();
+			targets.addListChangeListener(validationStatusProviderTargetsListener);
+			for (Iterator<IObservable> iter = targets.iterator(); iter
+					.hasNext();) {
+				iter.next().addChangeListener(uiChangeListener);
 			}
 		}
 	}
 
 	private void statusProviderChanged() {
-		currentStatusProvider = (ValidationStatusProvider) aggregateStatusProvider
-				.getValue();
+		currentStatusProvider = aggregateStatusProvider.getValue();
 		if (currentStatusProvider != null) {
-			currentStatus = (IStatus) currentStatusProvider
-					.getValidationStatus().getValue();
+			currentStatus = currentStatusProvider.getValidationStatus()
+					.getValue();
 		} else {
 			currentStatus = null;
 		}
@@ -227,16 +228,15 @@
 		}
 		dbc.getValidationStatusProviders().removeListChangeListener(
 				validationStatusProvidersListener);
-		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
-				.hasNext();) {
-			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
-					.next();
-			IObservableList targets = validationStatusProvider.getTargets();
-			targets
-					.removeListChangeListener(validationStatusProviderTargetsListener);
-			for (Iterator iter = targets.iterator(); iter.hasNext();) {
-				((IObservable) iter.next())
-						.removeChangeListener(uiChangeListener);
+		for (Iterator<ValidationStatusProvider> it = dbc
+				.getValidationStatusProviders().iterator(); it.hasNext();) {
+			ValidationStatusProvider validationStatusProvider = it.next();
+			IObservableList<IObservable> targets = validationStatusProvider
+					.getTargets();
+			targets.removeListChangeListener(validationStatusProviderTargetsListener);
+			for (Iterator<IObservable> iter = targets.iterator(); iter
+					.hasNext();) {
+				iter.next().removeChangeListener(uiChangeListener);
 			}
 		}
 	}
@@ -296,14 +296,12 @@
 	}
 
 	private void logThrowable(Throwable throwable) {
-		Policy
-				.getLog()
-				.log(
-						new Status(
-								IStatus.ERROR,
-								Policy.JFACE_DATABINDING,
-								IStatus.OK,
-								"Unhandled exception: " + throwable.getMessage(), throwable)); //$NON-NLS-1$
+		Policy.getLog()
+				.log(new Status(
+						IStatus.ERROR,
+						Policy.JFACE_DATABINDING,
+						IStatus.OK,
+						"Unhandled exception: " + throwable.getMessage(), throwable)); //$NON-NLS-1$
 	}
 
 	/**
@@ -314,16 +312,15 @@
 		if (aggregateStatusProvider != null)
 			aggregateStatusProvider.dispose();
 		if (dbc != null && !uiChanged) {
-			for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
-					.hasNext();) {
-				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
-						.next();
-				IObservableList targets = validationStatusProvider.getTargets();
-				targets
-						.removeListChangeListener(validationStatusProviderTargetsListener);
-				for (Iterator iter = targets.iterator(); iter.hasNext();) {
-					((IObservable) iter.next())
-							.removeChangeListener(uiChangeListener);
+			for (Iterator<ValidationStatusProvider> it = dbc
+					.getValidationStatusProviders().iterator(); it.hasNext();) {
+				ValidationStatusProvider validationStatusProvider = it.next();
+				IObservableList<IObservable> targets = validationStatusProvider
+						.getTargets();
+				targets.removeListChangeListener(validationStatusProviderTargetsListener);
+				for (Iterator<IObservable> iter = targets.iterator(); iter
+						.hasNext();) {
+					iter.next().removeChangeListener(uiChangeListener);
 				}
 			}
 			dbc.getValidationStatusProviders().removeListChangeListener(
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/MaxSeverityValidationStatusProvider.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/MaxSeverityValidationStatusProvider.java
index 50fea47..fa75410 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/MaxSeverityValidationStatusProvider.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/MaxSeverityValidationStatusProvider.java
@@ -19,23 +19,23 @@
 import org.eclipse.core.databinding.observable.value.ComputedValue;
 import org.eclipse.core.runtime.IStatus;
 
-/*package*/ class MaxSeverityValidationStatusProvider extends ComputedValue {
+/*package*/class MaxSeverityValidationStatusProvider extends
+		ComputedValue<ValidationStatusProvider> {
 
-	private Collection validationStatusProviders;
+	private Collection<ValidationStatusProvider> validationStatusProviders;
 
 	public MaxSeverityValidationStatusProvider(DataBindingContext dbc) {
 		super(ValidationStatusProvider.class);
 		this.validationStatusProviders = dbc.getValidationStatusProviders();
 	}
 
-	protected Object calculate() {
+	protected ValidationStatusProvider calculate() {
 		int maxSeverity = IStatus.OK;
 		ValidationStatusProvider maxSeverityProvider = null;
-		for (Iterator it = validationStatusProviders.iterator(); it.hasNext();) {
-			ValidationStatusProvider provider = (ValidationStatusProvider) it
-					.next();
-			IStatus status = (IStatus) provider.getValidationStatus()
-					.getValue();
+		for (Iterator<ValidationStatusProvider> it = validationStatusProviders
+				.iterator(); it.hasNext();) {
+			ValidationStatusProvider provider = it.next();
+			IStatus status = provider.getValidationStatus().getValue();
 			if (status.getSeverity() > maxSeverity) {
 				maxSeverity = status.getSeverity();
 				maxSeverityProvider = provider;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/TitleAreaDialogSupport.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/TitleAreaDialogSupport.java
index eafba89..deeb654 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/TitleAreaDialogSupport.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/TitleAreaDialogSupport.java
@@ -18,6 +18,7 @@
 package org.eclipse.jface.databinding.dialog;
 
 import java.util.Iterator;
+import java.util.List;
 
 import org.eclipse.core.databinding.DataBindingContext;
 import org.eclipse.core.databinding.ValidationStatusProvider;
@@ -70,47 +71,47 @@
 	private TitleAreaDialog dialog;
 	private DataBindingContext dbc;
 	private IValidationMessageProvider messageProvider = new ValidationMessageProvider();
-	private IObservableValue aggregateStatusProvider;
+	private IObservableValue<ValidationStatusProvider> aggregateStatusProvider;
 	private boolean uiChanged = false;
 	private IChangeListener uiChangeListener = new IChangeListener() {
 		public void handleChange(ChangeEvent event) {
 			handleUIChanged();
 		}
 	};
-	private IListChangeListener validationStatusProvidersListener = new IListChangeListener() {
-		public void handleListChange(ListChangeEvent event) {
-			ListDiff diff = event.diff;
-			ListDiffEntry[] differences = diff.getDifferences();
-			for (int i = 0; i < differences.length; i++) {
-				ListDiffEntry listDiffEntry = differences[i];
-				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) listDiffEntry
+	private IListChangeListener<ValidationStatusProvider> validationStatusProvidersListener = new IListChangeListener<ValidationStatusProvider>() {
+		public void handleListChange(
+				ListChangeEvent<ValidationStatusProvider> event) {
+			ListDiff<ValidationStatusProvider> diff = event.diff;
+			List<ListDiffEntry<ValidationStatusProvider>> differences = diff
+					.getDifferencesAsList();
+			for (ListDiffEntry<ValidationStatusProvider> listDiffEntry : differences) {
+				ValidationStatusProvider validationStatusProvider = listDiffEntry
 						.getElement();
-				IObservableList targets = validationStatusProvider.getTargets();
+				IObservableList<IObservable> targets = validationStatusProvider
+						.getTargets();
 				if (listDiffEntry.isAddition()) {
-					targets
-							.addListChangeListener(validationStatusProviderTargetsListener);
-					for (Iterator it = targets.iterator(); it.hasNext();) {
-						((IObservable) it.next())
-								.addChangeListener(uiChangeListener);
+					targets.addListChangeListener(validationStatusProviderTargetsListener);
+					for (Iterator<IObservable> it = targets.iterator(); it
+							.hasNext();) {
+						it.next().addChangeListener(uiChangeListener);
 					}
 				} else {
-					targets
-							.removeListChangeListener(validationStatusProviderTargetsListener);
-					for (Iterator it = targets.iterator(); it.hasNext();) {
-						((IObservable) it.next())
-								.removeChangeListener(uiChangeListener);
+					targets.removeListChangeListener(validationStatusProviderTargetsListener);
+					for (Iterator<IObservable> it = targets.iterator(); it
+							.hasNext();) {
+						it.next().removeChangeListener(uiChangeListener);
 					}
 				}
 			}
 		}
 	};
-	private IListChangeListener validationStatusProviderTargetsListener = new IListChangeListener() {
-		public void handleListChange(ListChangeEvent event) {
-			ListDiff diff = event.diff;
-			ListDiffEntry[] differences = diff.getDifferences();
-			for (int i = 0; i < differences.length; i++) {
-				ListDiffEntry listDiffEntry = differences[i];
-				IObservable target = (IObservable) listDiffEntry.getElement();
+	private IListChangeListener<IObservable> validationStatusProviderTargetsListener = new IListChangeListener<IObservable>() {
+		public void handleListChange(ListChangeEvent<IObservable> event) {
+			ListDiff<IObservable> diff = event.diff;
+			List<ListDiffEntry<IObservable>> differences = diff
+					.getDifferencesAsList();
+			for (ListDiffEntry<IObservable> listDiffEntry : differences) {
+				IObservable target = listDiffEntry.getElement();
 				if (listDiffEntry.isAddition()) {
 					target.addChangeListener(uiChangeListener);
 				} else {
@@ -156,8 +157,9 @@
 		}
 
 		aggregateStatusProvider
-				.addValueChangeListener(new IValueChangeListener() {
-					public void handleValueChange(ValueChangeEvent event) {
+				.addValueChangeListener(new IValueChangeListener<ValidationStatusProvider>() {
+					public void handleValueChange(
+							ValueChangeEvent<ValidationStatusProvider> event) {
 						statusProviderChanged();
 					}
 				});
@@ -169,25 +171,24 @@
 		statusProviderChanged();
 		dbc.getValidationStatusProviders().addListChangeListener(
 				validationStatusProvidersListener);
-		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
-				.hasNext();) {
-			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
-					.next();
-			IObservableList targets = validationStatusProvider.getTargets();
-			targets
-					.addListChangeListener(validationStatusProviderTargetsListener);
-			for (Iterator iter = targets.iterator(); iter.hasNext();) {
-				((IObservable) iter.next()).addChangeListener(uiChangeListener);
+		for (Iterator<ValidationStatusProvider> it = dbc
+				.getValidationStatusProviders().iterator(); it.hasNext();) {
+			ValidationStatusProvider validationStatusProvider = it.next();
+			IObservableList<IObservable> targets = validationStatusProvider
+					.getTargets();
+			targets.addListChangeListener(validationStatusProviderTargetsListener);
+			for (Iterator<IObservable> iter = targets.iterator(); iter
+					.hasNext();) {
+				iter.next().addChangeListener(uiChangeListener);
 			}
 		}
 	}
 
 	private void statusProviderChanged() {
-		currentStatusProvider = (ValidationStatusProvider) aggregateStatusProvider
-				.getValue();
+		currentStatusProvider = aggregateStatusProvider.getValue();
 		if (currentStatusProvider != null) {
-			currentStatus = (IStatus) currentStatusProvider
-					.getValidationStatus().getValue();
+			currentStatus = currentStatusProvider.getValidationStatus()
+					.getValue();
 		} else {
 			currentStatus = null;
 		}
@@ -201,16 +202,15 @@
 		}
 		dbc.getValidationStatusProviders().removeListChangeListener(
 				validationStatusProvidersListener);
-		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
-				.hasNext();) {
-			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
-					.next();
-			IObservableList targets = validationStatusProvider.getTargets();
-			targets
-					.removeListChangeListener(validationStatusProviderTargetsListener);
-			for (Iterator iter = targets.iterator(); iter.hasNext();) {
-				((IObservable) iter.next())
-						.removeChangeListener(uiChangeListener);
+		for (Iterator<ValidationStatusProvider> it = dbc
+				.getValidationStatusProviders().iterator(); it.hasNext();) {
+			ValidationStatusProvider validationStatusProvider = it.next();
+			IObservableList<IObservable> targets = validationStatusProvider
+					.getTargets();
+			targets.removeListChangeListener(validationStatusProviderTargetsListener);
+			for (Iterator<IObservable> iter = targets.iterator(); iter
+					.hasNext();) {
+				iter.next().removeChangeListener(uiChangeListener);
 			}
 		}
 	}
@@ -270,14 +270,12 @@
 	}
 
 	private void logThrowable(Throwable throwable) {
-		Policy
-				.getLog()
-				.log(
-						new Status(
-								IStatus.ERROR,
-								Policy.JFACE_DATABINDING,
-								IStatus.OK,
-								"Unhandled exception: " + throwable.getMessage(), throwable)); //$NON-NLS-1$
+		Policy.getLog()
+				.log(new Status(
+						IStatus.ERROR,
+						Policy.JFACE_DATABINDING,
+						IStatus.OK,
+						"Unhandled exception: " + throwable.getMessage(), throwable)); //$NON-NLS-1$
 	}
 
 	/**
@@ -288,16 +286,15 @@
 		if (aggregateStatusProvider != null)
 			aggregateStatusProvider.dispose();
 		if (dbc != null && !uiChanged) {
-			for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
-					.hasNext();) {
-				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
-						.next();
-				IObservableList targets = validationStatusProvider.getTargets();
-				targets
-						.removeListChangeListener(validationStatusProviderTargetsListener);
-				for (Iterator iter = targets.iterator(); iter.hasNext();) {
-					((IObservable) iter.next())
-							.removeChangeListener(uiChangeListener);
+			for (Iterator<ValidationStatusProvider> it = dbc
+					.getValidationStatusProviders().iterator(); it.hasNext();) {
+				ValidationStatusProvider validationStatusProvider = it.next();
+				IObservableList<IObservable> targets = validationStatusProvider
+						.getTargets();
+				targets.removeListChangeListener(validationStatusProviderTargetsListener);
+				for (Iterator<IObservable> iter = targets.iterator(); iter
+						.hasNext();) {
+					iter.next().removeChangeListener(uiChangeListener);
 				}
 			}
 			dbc.getValidationStatusProviders().removeListChangeListener(
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/fieldassist/ControlDecorationSupport.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/fieldassist/ControlDecorationSupport.java
index 2541527..935fdc6 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/fieldassist/ControlDecorationSupport.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/fieldassist/ControlDecorationSupport.java
@@ -135,8 +135,8 @@
 	private final Composite composite;
 	private final ControlDecorationUpdater updater;
 
-	private IObservableValue validationStatus;
-	private IObservableList targets;
+	private IObservableValue<IStatus> validationStatus;
+	private IObservableList<IObservable> targets;
 
 	private IDisposeListener disposeListener = new IDisposeListener() {
 		public void handleDispose(DisposeEvent staleEvent) {
@@ -144,24 +144,24 @@
 		}
 	};
 
-	private IValueChangeListener statusChangeListener = new IValueChangeListener() {
-		public void handleValueChange(ValueChangeEvent event) {
-			statusChanged((IStatus) validationStatus.getValue());
+	private IValueChangeListener<IStatus> statusChangeListener = new IValueChangeListener<IStatus>() {
+		public void handleValueChange(ValueChangeEvent<IStatus> event) {
+			statusChanged(validationStatus.getValue());
 		}
 	};
 
-	private IListChangeListener targetsChangeListener = new IListChangeListener() {
-		public void handleListChange(ListChangeEvent event) {
-			event.diff.accept(new ListDiffVisitor() {
-				public void handleAdd(int index, Object element) {
-					targetAdded((IObservable) element);
+	private IListChangeListener<IObservable> targetsChangeListener = new IListChangeListener<IObservable>() {
+		public void handleListChange(ListChangeEvent<IObservable> event) {
+			event.diff.accept(new ListDiffVisitor<IObservable>() {
+				public void handleAdd(int index, IObservable element) {
+					targetAdded(element);
 				}
 
-				public void handleRemove(int index, Object element) {
-					targetRemoved((IObservable) element);
+				public void handleRemove(int index, IObservable element) {
+					targetRemoved(element);
 				}
 			});
-			statusChanged((IStatus) validationStatus.getValue());
+			statusChanged(validationStatus.getValue());
 		}
 	};
 
@@ -175,7 +175,7 @@
 		}
 	}
 
-	private List targetDecorations;
+	private List<TargetDecoration> targetDecorations;
 
 	private ControlDecorationSupport(
 			ValidationStatusProvider validationStatusProvider, int position,
@@ -190,7 +190,7 @@
 		this.targets = validationStatusProvider.getTargets();
 		Assert.isTrue(!this.targets.isDisposed());
 
-		this.targetDecorations = new ArrayList();
+		this.targetDecorations = new ArrayList<TargetDecoration>();
 
 		validationStatus.addDisposeListener(disposeListener);
 		validationStatus.addValueChangeListener(statusChangeListener);
@@ -198,10 +198,10 @@
 		targets.addDisposeListener(disposeListener);
 		targets.addListChangeListener(targetsChangeListener);
 
-		for (Iterator it = targets.iterator(); it.hasNext();)
-			targetAdded((IObservable) it.next());
+		for (Iterator<IObservable> it = targets.iterator(); it.hasNext();)
+			targetAdded(it.next());
 
-		statusChanged((IStatus) validationStatus.getValue());
+		statusChanged(validationStatus.getValue());
 	}
 
 	private void targetAdded(IObservable target) {
@@ -212,8 +212,9 @@
 	}
 
 	private void targetRemoved(IObservable target) {
-		for (Iterator it = targetDecorations.iterator(); it.hasNext();) {
-			TargetDecoration targetDecoration = (TargetDecoration) it.next();
+		for (Iterator<TargetDecoration> it = targetDecorations.iterator(); it
+				.hasNext();) {
+			TargetDecoration targetDecoration = it.next();
 			if (targetDecoration.target == target) {
 				targetDecoration.decoration.dispose();
 				it.remove();
@@ -251,8 +252,9 @@
 	}
 
 	private void statusChanged(IStatus status) {
-		for (Iterator it = targetDecorations.iterator(); it.hasNext();) {
-			TargetDecoration targetDecoration = (TargetDecoration) it.next();
+		for (Iterator<TargetDecoration> it = targetDecorations.iterator(); it
+				.hasNext();) {
+			TargetDecoration targetDecoration = it.next();
 			ControlDecoration decoration = targetDecoration.decoration;
 			updater.update(decoration, status);
 		}
@@ -281,9 +283,9 @@
 		targetsChangeListener = null;
 
 		if (targetDecorations != null) {
-			for (Iterator it = targetDecorations.iterator(); it.hasNext();) {
-				TargetDecoration targetDecoration = (TargetDecoration) it
-						.next();
+			for (Iterator<TargetDecoration> it = targetDecorations.iterator(); it
+					.hasNext();) {
+				TargetDecoration targetDecoration = it.next();
 				targetDecoration.decoration.dispose();
 			}
 			targetDecorations.clear();
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/ISWTObservableList.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/ISWTObservableList.java
index 63f9c3f..c284f27 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/ISWTObservableList.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/ISWTObservableList.java
@@ -16,8 +16,11 @@
 /**
  * {@link IObservableList} observing an SWT widget.
  * 
+ * @param <E>
+ * 
  * @since 1.3
  */
-public interface ISWTObservableList extends ISWTObservable, IObservableList {
+public interface ISWTObservableList<E> extends ISWTObservable,
+		IObservableList<E> {
 
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/ISWTObservableValue.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/ISWTObservableValue.java
index d25ba3a..8657f23 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/ISWTObservableValue.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/ISWTObservableValue.java
@@ -16,9 +16,12 @@
 /**
  * {@link IObservableValue} observing an SWT widget.
  * 
+ * @param <T>
+ *            type of the value of the property
  * @since 1.1
- *
+ * 
  */
-public interface ISWTObservableValue extends ISWTObservable, IObservableValue {
+public interface ISWTObservableValue<T> extends ISWTObservable,
+		IObservableValue<T> {
 
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/IWidgetListProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/IWidgetListProperty.java
index 2f38284..fdc2fc0 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/IWidgetListProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/IWidgetListProperty.java
@@ -17,10 +17,14 @@
 /**
  * {@link IListProperty} for observing an SWT Widget
  * 
+ * @param <S>
+ * @param <E>
+ * 
  * @since 1.3
  * @noimplement This interface is not intended to be implemented by clients.
  */
-public interface IWidgetListProperty extends IListProperty {
+public interface IWidgetListProperty<S extends Widget, E> extends
+		IListProperty<S, E> {
 	/**
 	 * Returns an {@link ISWTObservableList} observing this list property on the
 	 * given widget
@@ -30,5 +34,5 @@
 	 * @return an observable list observing this list property on the given
 	 *         widget
 	 */
-	public ISWTObservableList observe(Widget widget);
+	public ISWTObservableList<E> observe(S widget);
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/IWidgetValueProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/IWidgetValueProperty.java
index 2d0a3fe..3a14154 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/IWidgetValueProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/IWidgetValueProperty.java
@@ -17,10 +17,14 @@
 /**
  * {@link IValueProperty} for observing an SWT Widget
  * 
+ * @param <S>
+ * @param <T>
+ * 
  * @since 1.3
  * @noimplement This interface is not intended to be implemented by clients.
  */
-public interface IWidgetValueProperty extends IValueProperty {
+public interface IWidgetValueProperty<S extends Widget, T> extends
+		IValueProperty<S, T> {
 	/**
 	 * Returns an {@link ISWTObservableValue} observing this value property on
 	 * the given widget
@@ -30,7 +34,7 @@
 	 * @return an observable value observing this value property on the given
 	 *         widget
 	 */
-	public ISWTObservableValue observe(Widget widget);
+	public ISWTObservableValue<T> observe(S widget);
 
 	/**
 	 * Returns an {@link ISWTObservableValue} observing this value property on
@@ -50,5 +54,5 @@
 	 *         widget, and which delays change notifications for
 	 *         <code>delay</code> milliseconds.
 	 */
-	public ISWTObservableValue observeDelayed(int delay, Widget widget);
+	public ISWTObservableValue<T> observeDelayed(int delay, S widget);
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/SWTObservables.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/SWTObservables.java
index 004ed7d..f9959af 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/SWTObservables.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/SWTObservables.java
@@ -28,8 +28,18 @@
 import org.eclipse.core.databinding.observable.value.ValueChangingEvent;
 import org.eclipse.jface.internal.databinding.swt.SWTDelayedObservableValueDecorator;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Scale;
+import org.eclipse.swt.widgets.Slider;
+import org.eclipse.swt.widgets.Spinner;
+import org.eclipse.swt.widgets.Text;
 import org.eclipse.swt.widgets.Widget;
 
 /**
@@ -39,7 +49,7 @@
  */
 public class SWTObservables {
 
-	private static java.util.List realms = new ArrayList();
+	private static java.util.List<DisplayRealm> realms = new ArrayList<DisplayRealm>();
 
 	/**
 	 * Returns the realm representing the UI thread for the given display.
@@ -49,8 +59,8 @@
 	 */
 	public static Realm getRealm(final Display display) {
 		synchronized (realms) {
-			for (Iterator it = realms.iterator(); it.hasNext();) {
-				DisplayRealm displayRealm = (DisplayRealm) it.next();
+			for (Iterator<DisplayRealm> it = realms.iterator(); it.hasNext();) {
+				DisplayRealm displayRealm = it.next();
 				if (displayRealm.display == display) {
 					return displayRealm;
 				}
@@ -92,9 +102,9 @@
 	 * 
 	 * @since 1.2
 	 */
-	public static ISWTObservableValue observeDelayedValue(int delay,
-			ISWTObservableValue observable) {
-		return new SWTDelayedObservableValueDecorator(
+	public static <T> ISWTObservableValue<T> observeDelayedValue(int delay,
+			ISWTObservableValue<T> observable) {
+		return new SWTDelayedObservableValueDecorator<T>(
 				Observables.observeDelayedValue(delay, observable),
 				observable.getWidget());
 	}
@@ -193,36 +203,124 @@
 	 * <li>org.eclipse.swt.widgets.Scale</li>
 	 * </ul>
 	 * 
-	 * @param widget
+	 * @param control
 	 * @return observable value
 	 * @throws IllegalArgumentException
 	 *             if <code>control</code> type is unsupported
-	 * @since 1.5
+	 * 
+	 * @deprecated use instead one of the more specific methods
+	 *             (observeSelection(Button), observeSelection(Combo) etc)
 	 */
-	public static ISWTObservableValue observeSelection(Widget widget) {
-		return WidgetProperties.selection().observe(widget);
+	public static ISWTObservableValue<?> observeSelection(Widget control) {
+		return WidgetProperties.selection().observe(control);
 	}
 
 	/**
 	 * Returns an observable observing the selection attribute of the provided
 	 * <code>control</code>. The supported types are:
 	 * <ul>
+	 * <li>org.eclipse.swt.widgets.Spinner</li>
 	 * <li>org.eclipse.swt.widgets.Button</li>
 	 * <li>org.eclipse.swt.widgets.Combo</li>
 	 * <li>org.eclipse.swt.custom.CCombo</li>
 	 * <li>org.eclipse.swt.widgets.List</li>
+	 * <li>org.eclipse.swt.widgets.MenuItem (since 1.5)</li>
 	 * <li>org.eclipse.swt.widgets.Scale</li>
-	 * <li>org.eclipse.swt.widgets.Slider (since 1.5)</li>
-	 * <li>org.eclipse.swt.widgets.Spinner</li>
 	 * </ul>
 	 * 
 	 * @param control
 	 * @return observable value
 	 * @throws IllegalArgumentException
 	 *             if <code>control</code> type is unsupported
+	 * @deprecated use instead one of the more specific methods
+	 *             (observeSelection(Button), observeSelection(Combo) etc)
 	 */
-	public static ISWTObservableValue observeSelection(Control control) {
-		return observeSelection((Widget) control);
+	public static ISWTObservableValue<?> observeSelection(Control control) {
+		return WidgetProperties.selection().observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the selection attribute of the provided
+	 * <code>org.eclipse.swt.widgets.Button</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<Boolean> observeSelection(Button control) {
+		return WidgetProperties.selectionButton().observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the selection attribute of the provided
+	 * <code>org.eclipse.swt.widgets.Combo</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<String> observeSelection(Combo control) {
+		return WidgetProperties.selectionCombo().observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the selection attribute of the provided
+	 * <code>org.eclipse.swt.custom.CCombo</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<String> observeSelection(CCombo control) {
+		return WidgetProperties.selectionCCombo().observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the selection attribute of the provided
+	 * <code>org.eclipse.swt.widgets.List</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<String> observeSelection(List control) {
+		return WidgetProperties.selectionList().observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the selection attribute of the provided
+	 * <code>org.eclipse.swt.widgets.MenuItem</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<Boolean> observeSelection(MenuItem control) {
+		return WidgetProperties.selectionMenuItem().observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the selection attribute of the provided
+	 * <code>org.eclipse.swt.widgets.Scale</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<Integer> observeSelection(Scale control) {
+		return WidgetProperties.selectionScale().observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the selection attribute of the provided
+	 * <code>org.eclipse.swt.widgets.Spinner</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<Integer> observeSelection(Spinner control) {
+		return WidgetProperties.selectionSpinner().observe(control);
 	}
 
 	/**
@@ -238,12 +336,52 @@
 	 * @return observable value
 	 * @throws IllegalArgumentException
 	 *             if <code>control</code> type is unsupported
+	 * @deprecated use instead one of the more specific methods
+	 *             (observeMin(Spinner), observeMin(Slider), observeMin(Scale))
 	 */
+	// ok to ignore warnings in deprecated method
+	@SuppressWarnings({ "rawtypes", "unchecked" })
 	public static ISWTObservableValue observeMin(Control control) {
 		return WidgetProperties.minimum().observe(control);
 	}
 
 	/**
+	 * Returns an observable observing the <code>minimum</code> attribute of the
+	 * provided <code>org.eclipse.swt.widgets.Scale</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<Integer> observeMin(Scale control) {
+		return WidgetProperties.minimumScale().observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the <code>minimum</code> attribute of the
+	 * provided <code>org.eclipse.swt.widgets.Scale</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<Integer> observeMin(Slider control) {
+		return WidgetProperties.minimumSlider().observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the <code>minimum</code> attribute of the
+	 * provided <code>org.eclipse.swt.widgets.Spinner</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<Integer> observeMin(Spinner control) {
+		return WidgetProperties.minimumSpinner().observe(control);
+	}
+
+	/**
 	 * Returns an observable observing the maximum attribute of the provided
 	 * <code>control</code>. The supported types are:
 	 * <ul>
@@ -256,12 +394,52 @@
 	 * @return observable value
 	 * @throws IllegalArgumentException
 	 *             if <code>control</code> type is unsupported
+	 * @deprecated use instead one of the more specific methods
+	 *             (observeMax(Spinner), observeMax(Slider), observeMax(Scale))
 	 */
+	// ok to ignore warnings in deprecated method
+	@SuppressWarnings({ "rawtypes", "unchecked" })
 	public static ISWTObservableValue observeMax(Control control) {
 		return WidgetProperties.maximum().observe(control);
 	}
 
 	/**
+	 * Returns an observable observing the <code>maximum</code> attribute of the
+	 * provided <code>org.eclipse.swt.widgets.Scale</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<Integer> observeMax(Scale control) {
+		return WidgetProperties.maximumScale().observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the <code>maximum</code> attribute of the
+	 * provided <code>org.eclipse.swt.widgets.Scale</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<Integer> observeMax(Slider control) {
+		return WidgetProperties.maximumSlider().observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the <code>maximum</code> attribute of the
+	 * provided <code>org.eclipse.swt.widgets.Spinner</code>.
+	 * 
+	 * @param control
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<Integer> observeMax(Spinner control) {
+		return WidgetProperties.maximumSpinner().observe(control);
+	}
+
+	/**
 	 * Returns an observable observing the text attribute of the provided
 	 * <code>control</code>. The supported types are:
 	 * <ul>
@@ -278,13 +456,51 @@
 	 * @throws IllegalArgumentException
 	 *             if <code>control</code> type is unsupported
 	 * @since 1.3
+	 * @deprecated use instead one of the more specific methods
+	 *             (observeText(Text), observeText(StyledText))
 	 */
+	// ok to ignore warnings in deprecated method
+	@SuppressWarnings({ "rawtypes", "unchecked" })
 	public static ISWTObservableValue observeText(Control control, int[] events) {
 		return WidgetProperties.text(events).observe(control);
 	}
 
 	/**
 	 * Returns an observable observing the text attribute of the provided
+	 * <code>Text</code>.
+	 * 
+	 * @param control
+	 * @param events
+	 *            array of SWT event types to register for change events. May
+	 *            include {@link SWT#None}, {@link SWT#Modify},
+	 *            {@link SWT#FocusOut} or {@link SWT#DefaultSelection}.
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<String> observeText(Text control,
+			int[] events) {
+		return WidgetProperties.textText(events).observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the text attribute of the provided
+	 * <code>StyledText</code>.
+	 * 
+	 * @param control
+	 * @param events
+	 *            array of SWT event types to register for change events. May
+	 *            include {@link SWT#None}, {@link SWT#Modify},
+	 *            {@link SWT#FocusOut} or {@link SWT#DefaultSelection}.
+	 * @return observable value
+	 * @since 1.7
+	 */
+	public static ISWTObservableValue<String> observeText(StyledText control,
+			int[] events) {
+		return WidgetProperties.textStyledText(events).observe(control);
+	}
+
+	/**
+	 * Returns an observable observing the text attribute of the provided
 	 * <code>control</code>. The supported types are:
 	 * <ul>
 	 * <li>org.eclipse.swt.widgets.Text</li>
@@ -298,7 +514,8 @@
 	 * @throws IllegalArgumentException
 	 *             if <code>control</code> type is unsupported
 	 */
-	public static ISWTObservableValue observeText(Control control, int event) {
+	public static ISWTObservableValue<String> observeText(Control control,
+			int event) {
 		return WidgetProperties.text(event).observe(control);
 	}
 
@@ -349,7 +566,7 @@
 	 * @throws IllegalArgumentException
 	 *             if <code>control</code> type is unsupported
 	 */
-	public static ISWTObservableValue observeText(Control control) {
+	public static ISWTObservableValue<String> observeText(Control control) {
 		return observeText((Widget) control);
 	}
 
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetListProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetListProperty.java
index 2b8775b..f9218b7 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetListProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetListProperty.java
@@ -13,7 +13,6 @@
 package org.eclipse.jface.databinding.swt;
 
 import org.eclipse.core.databinding.observable.Realm;
-import org.eclipse.core.databinding.observable.list.IObservableList;
 import org.eclipse.core.databinding.property.list.SimpleListProperty;
 import org.eclipse.jface.internal.databinding.swt.SWTObservableListDecorator;
 import org.eclipse.swt.widgets.Widget;
@@ -29,24 +28,23 @@
  * {@link ISWTObservable}
  * </ul>
  * 
+ * @param <S>
+ * @param <E>
+ * 
  * @since 1.3
  */
-public abstract class WidgetListProperty extends SimpleListProperty implements
-		IWidgetListProperty {
-	public IObservableList observe(Object source) {
-		if (source instanceof Widget) {
-			return observe((Widget) source);
-		}
-		return super.observe(source);
+public abstract class WidgetListProperty<S extends Widget, E> extends
+		SimpleListProperty<S, E> implements IWidgetListProperty<S, E> {
+
+	/**
+	 * @since 1.7
+	 */
+	public ISWTObservableList<E> observe(Realm realm, S widget) {
+		return new SWTObservableListDecorator<E>(super.observe(realm, widget),
+				widget);
 	}
 
-	public IObservableList observe(Realm realm, Object source) {
-		return new SWTObservableListDecorator(super.observe(realm, source),
-				(Widget) source);
-	}
-
-	public ISWTObservableList observe(Widget widget) {
-		return (ISWTObservableList) observe(SWTObservables.getRealm(widget
-				.getDisplay()), widget);
+	public ISWTObservableList<E> observe(S widget) {
+		return observe(SWTObservables.getRealm(widget.getDisplay()), widget);
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetProperties.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetProperties.java
index 89ad173..2baa2d2 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetProperties.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetProperties.java
@@ -13,31 +13,79 @@
 
 package org.eclipse.jface.databinding.swt;
 
+import org.eclipse.core.databinding.property.list.IListProperty;
+import org.eclipse.core.databinding.property.value.IValueProperty;
+import org.eclipse.jface.internal.databinding.swt.ButtonImageProperty;
+import org.eclipse.jface.internal.databinding.swt.ButtonSelectionProperty;
+import org.eclipse.jface.internal.databinding.swt.ButtonTextProperty;
+import org.eclipse.jface.internal.databinding.swt.CComboEditableProperty;
+import org.eclipse.jface.internal.databinding.swt.CComboItemsProperty;
+import org.eclipse.jface.internal.databinding.swt.CComboSelectionProperty;
+import org.eclipse.jface.internal.databinding.swt.CComboSingleSelectionIndexProperty;
+import org.eclipse.jface.internal.databinding.swt.CComboTextProperty;
+import org.eclipse.jface.internal.databinding.swt.CLabelImageProperty;
+import org.eclipse.jface.internal.databinding.swt.CLabelTextProperty;
+import org.eclipse.jface.internal.databinding.swt.CTabItemTooltipTextProperty;
+import org.eclipse.jface.internal.databinding.swt.ComboItemsProperty;
+import org.eclipse.jface.internal.databinding.swt.ComboSelectionProperty;
+import org.eclipse.jface.internal.databinding.swt.ComboSingleSelectionIndexProperty;
+import org.eclipse.jface.internal.databinding.swt.ComboTextProperty;
 import org.eclipse.jface.internal.databinding.swt.ControlBackgroundProperty;
 import org.eclipse.jface.internal.databinding.swt.ControlBoundsProperty;
+import org.eclipse.jface.internal.databinding.swt.ControlEnabledProperty;
 import org.eclipse.jface.internal.databinding.swt.ControlFocusedProperty;
 import org.eclipse.jface.internal.databinding.swt.ControlFontProperty;
 import org.eclipse.jface.internal.databinding.swt.ControlForegroundProperty;
 import org.eclipse.jface.internal.databinding.swt.ControlLocationProperty;
 import org.eclipse.jface.internal.databinding.swt.ControlSizeProperty;
+import org.eclipse.jface.internal.databinding.swt.ControlTooltipTextProperty;
 import org.eclipse.jface.internal.databinding.swt.ControlVisibleProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetEditableProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetEnabledProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetImageProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetItemsProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetMaximumProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetMessageProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetMinimumProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetSelectionProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetSingleSelectionIndexProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetTextProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetTextWithEventsProperty;
-import org.eclipse.jface.internal.databinding.swt.WidgetTooltipTextProperty;
+import org.eclipse.jface.internal.databinding.swt.ItemImageProperty;
+import org.eclipse.jface.internal.databinding.swt.ItemTextProperty;
+import org.eclipse.jface.internal.databinding.swt.LabelImageProperty;
+import org.eclipse.jface.internal.databinding.swt.LabelTextProperty;
+import org.eclipse.jface.internal.databinding.swt.LinkTextProperty;
+import org.eclipse.jface.internal.databinding.swt.ListItemsProperty;
+import org.eclipse.jface.internal.databinding.swt.ListSelectionProperty;
+import org.eclipse.jface.internal.databinding.swt.ListSingleSelectionIndexProperty;
+import org.eclipse.jface.internal.databinding.swt.MenuEnabledProperty;
+import org.eclipse.jface.internal.databinding.swt.MenuItemEnabledProperty;
+import org.eclipse.jface.internal.databinding.swt.MenuItemSelectionProperty;
+import org.eclipse.jface.internal.databinding.swt.ScaleMaximumProperty;
+import org.eclipse.jface.internal.databinding.swt.ScaleMinimumProperty;
+import org.eclipse.jface.internal.databinding.swt.ScaleSelectionProperty;
+import org.eclipse.jface.internal.databinding.swt.ScrollBarEnabledProperty;
+import org.eclipse.jface.internal.databinding.swt.ShellTextProperty;
+import org.eclipse.jface.internal.databinding.swt.SliderMaximumProperty;
+import org.eclipse.jface.internal.databinding.swt.SliderMinimumProperty;
+import org.eclipse.jface.internal.databinding.swt.SpinnerMaximumProperty;
+import org.eclipse.jface.internal.databinding.swt.SpinnerMinimumProperty;
+import org.eclipse.jface.internal.databinding.swt.SpinnerSelectionProperty;
+import org.eclipse.jface.internal.databinding.swt.StyledTextEditableProperty;
+import org.eclipse.jface.internal.databinding.swt.StyledTextTextProperty;
+import org.eclipse.jface.internal.databinding.swt.TabItemTooltipTextProperty;
+import org.eclipse.jface.internal.databinding.swt.TableColumnTooltipTextProperty;
+import org.eclipse.jface.internal.databinding.swt.TableSingleSelectionIndexProperty;
+import org.eclipse.jface.internal.databinding.swt.TextEditableProperty;
+import org.eclipse.jface.internal.databinding.swt.TextMessageProperty;
+import org.eclipse.jface.internal.databinding.swt.TextTextProperty;
+import org.eclipse.jface.internal.databinding.swt.ToolItemEnabledProperty;
+import org.eclipse.jface.internal.databinding.swt.ToolItemTooltipTextProperty;
+import org.eclipse.jface.internal.databinding.swt.ToolTipMessageProperty;
+import org.eclipse.jface.internal.databinding.swt.TrayItemTooltipTextProperty;
+import org.eclipse.jface.internal.databinding.swt.TreeColumnTooltipTextProperty;
+import org.eclipse.jface.internal.databinding.swt.WidgetDelegatingListProperty;
+import org.eclipse.jface.internal.databinding.swt.WidgetDelegatingValueProperty;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CCombo;
 import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.custom.CTabItem;
 import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Control;
@@ -76,7 +124,7 @@
 	 * @return a value property for observing the background color of a
 	 *         {@link Control}.
 	 */
-	public static IWidgetValueProperty background() {
+	public static IWidgetValueProperty<Control, Color> background() {
 		return new ControlBackgroundProperty();
 	}
 
@@ -85,7 +133,7 @@
 	 * 
 	 * @return a value property for observing the bounds of a {@link Control}.
 	 */
-	public static IWidgetValueProperty bounds() {
+	public static IWidgetValueProperty<Control, Rectangle> bounds() {
 		return new ControlBoundsProperty();
 	}
 
@@ -96,9 +144,81 @@
 	 * 
 	 * @return a value property for observing the editable state of a
 	 *         {@link CCombo}, {@link StyledText}, or {@link Text}.
+	 * @deprecated use one of the more specific methods below (editableCCombo,
+	 *             editableStyledText, or editableText)
 	 */
+	// ok to ignore warnings in deprecated class
+	@SuppressWarnings("rawtypes")
 	public static IWidgetValueProperty editable() {
-		return new WidgetEditableProperty();
+		return new org.eclipse.jface.internal.databinding.swt.WidgetEditableProperty();
+	}
+
+	/**
+	 * Returns a value property for observing the editable state of a
+	 * {@link CCombo}.
+	 * 
+	 * @return a value property for observing the editable state of a
+	 *         {@link CCombo}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<CCombo, Boolean> editableCCombo() {
+		return new WidgetDelegatingValueProperty<CCombo, Boolean>() {
+			IValueProperty<CCombo, Boolean> ccombo = null;
+
+			@Override
+			protected IValueProperty<CCombo, Boolean> doGetDelegate(
+					CCombo source) {
+				if (ccombo == null) {
+					ccombo = new CComboEditableProperty();
+				}
+				return ccombo;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the editable state of a
+	 * {@link StyledText}.
+	 * 
+	 * @return a value property for observing the editable state of a
+	 *         {@link StyledText}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<StyledText, Boolean> editableStyledText() {
+		return new WidgetDelegatingValueProperty<StyledText, Boolean>() {
+			IValueProperty<StyledText, Boolean> styledText = null;
+
+			@Override
+			protected IValueProperty<StyledText, Boolean> doGetDelegate(
+					StyledText source) {
+				if (styledText == null) {
+					styledText = new StyledTextEditableProperty();
+				}
+				return styledText;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the editable state of a
+	 * {@link Text}.
+	 * 
+	 * @return a value property for observing the editable state of a
+	 *         {@link Text}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Text, Boolean> editableText() {
+		return new WidgetDelegatingValueProperty<Text, Boolean>() {
+			IValueProperty<Text, Boolean> text = null;
+
+			@Override
+			protected IValueProperty<Text, Boolean> doGetDelegate(Text source) {
+				if (text == null) {
+					text = new TextEditableProperty();
+				}
+				return text;
+			}
+		};
 	}
 
 	/**
@@ -109,9 +229,130 @@
 	 * @return a value property for observing the enablement state of a
 	 *         {@link Control}, {@link Menu}, {@link MenuItem},
 	 *         {@link ScrollBar} or {@link ToolItem}.
+	 * @since 1.6
+	 * @deprecated use one of the more specific methods below (enabledControl,
+	 *             enabledMenu, enabledMenuItem, enabledScrollBar, or
+	 *             enabledToolItem)
 	 */
-	public static IWidgetValueProperty enabled() {
-		return new WidgetEnabledProperty();
+	public static IWidgetValueProperty<Widget, Boolean> enabled() {
+		return new org.eclipse.jface.internal.databinding.swt.WidgetEnabledProperty();
+	}
+
+	/**
+	 * Returns a value property for observing the enablement state of a
+	 * {@link Control}.
+	 * 
+	 * @return a value property for observing the enablement state of a
+	 *         {@link Control}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Control, Boolean> enabledControl() {
+		return new WidgetDelegatingValueProperty<Control, Boolean>(Boolean.TYPE) {
+
+			IValueProperty<Control, Boolean> control = null;
+
+			@Override
+			protected IValueProperty<Control, Boolean> doGetDelegate(
+					Control source) {
+				if (control == null)
+					control = new ControlEnabledProperty();
+				return control;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the enablement state of a
+	 * {@link Menu}.
+	 * 
+	 * @return a value property for observing the enablement state of a
+	 *         {@link Menu}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Menu, Boolean> enabledMenu() {
+		return new WidgetDelegatingValueProperty<Menu, Boolean>(Boolean.TYPE) {
+
+			IValueProperty<Menu, Boolean> menu = null;
+
+			@Override
+			protected IValueProperty<Menu, Boolean> doGetDelegate(Menu source) {
+				if (menu == null)
+					menu = new MenuEnabledProperty();
+				return menu;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the enablement state of a
+	 * {@link MenuItem}.
+	 * 
+	 * @return a value property for observing the enablement state of a
+	 *         {@link MenuItem}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<MenuItem, Boolean> enabledMenuItem() {
+		return new WidgetDelegatingValueProperty<MenuItem, Boolean>(
+				Boolean.TYPE) {
+
+			IValueProperty<MenuItem, Boolean> menu = null;
+
+			@Override
+			protected IValueProperty<MenuItem, Boolean> doGetDelegate(
+					MenuItem source) {
+				if (menu == null)
+					menu = new MenuItemEnabledProperty();
+				return menu;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the enablement state of a
+	 * {@link ScrollBar}.
+	 * 
+	 * @return a value property for observing the enablement state of a
+	 *         {@link ScrollBar}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<ScrollBar, Boolean> enabledScrollBar() {
+		return new WidgetDelegatingValueProperty<ScrollBar, Boolean>(
+				Boolean.TYPE) {
+
+			IValueProperty<ScrollBar, Boolean> menu = null;
+
+			@Override
+			protected IValueProperty<ScrollBar, Boolean> doGetDelegate(
+					ScrollBar source) {
+				if (menu == null)
+					menu = new ScrollBarEnabledProperty();
+				return menu;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the enablement state of a
+	 * {@link ToolItem}.
+	 * 
+	 * @return a value property for observing the enablement state of a
+	 *         {@link ToolItem}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<ToolItem, Boolean> enabledToolItem() {
+		return new WidgetDelegatingValueProperty<ToolItem, Boolean>(
+				Boolean.TYPE) {
+
+			IValueProperty<ToolItem, Boolean> menu = null;
+
+			@Override
+			protected IValueProperty<ToolItem, Boolean> doGetDelegate(
+					ToolItem source) {
+				if (menu == null)
+					menu = new ToolItemEnabledProperty();
+				return menu;
+			}
+		};
 	}
 
 	/**
@@ -121,7 +362,7 @@
 	 * @return a value property for observing the focus state of a
 	 *         {@link Control}.
 	 */
-	public static IWidgetValueProperty focused() {
+	public static IWidgetValueProperty<Control, Boolean> focused() {
 		return new ControlFocusedProperty();
 	}
 
@@ -130,7 +371,7 @@
 	 * 
 	 * @return a value property for observing the font of a {@link Control}.
 	 */
-	public static IWidgetValueProperty font() {
+	public static IWidgetValueProperty<Control, Font> font() {
 		return new ControlFontProperty();
 	}
 
@@ -141,7 +382,7 @@
 	 * @return a value property for observing the foreground color of a
 	 *         {@link Control}.
 	 */
-	public static IWidgetValueProperty foreground() {
+	public static IWidgetValueProperty<Control, Color> foreground() {
 		return new ControlForegroundProperty();
 	}
 
@@ -151,9 +392,93 @@
 	 * 
 	 * @return a value property for observing the image of a {@link Button},
 	 *         {@link CLabel}, {@link Item} or {@link Label}.
+	 * @deprecated use one of the more specific methods below (imageButton,
+	 *             imageCLabel, imageItem, or ImageLabel)
 	 */
+	// ok to ignore warnings in deprecated class
+	@SuppressWarnings("rawtypes")
 	public static IWidgetValueProperty image() {
-		return new WidgetImageProperty();
+		return new org.eclipse.jface.internal.databinding.swt.WidgetImageProperty();
+	}
+
+	/**
+	 * Returns a value property for observing the image of a {@link Button}.
+	 * 
+	 * @return a value property for observing the image of a {@link Button}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Button, Image> imageButton() {
+		return new WidgetDelegatingValueProperty<Button, Image>(Image.class) {
+
+			IValueProperty<Button, Image> button = null;
+
+			@Override
+			protected IValueProperty<Button, Image> doGetDelegate(Button source) {
+				if (button == null)
+					button = new ButtonImageProperty();
+				return button;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the image of a {@link CLabel}.
+	 * 
+	 * @return a value property for observing the image of a {@link CLabel}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<CLabel, Image> imageCLabel() {
+		return new WidgetDelegatingValueProperty<CLabel, Image>(Image.class) {
+
+			IValueProperty<CLabel, Image> clabel = null;
+
+			@Override
+			protected IValueProperty<CLabel, Image> doGetDelegate(CLabel source) {
+				if (clabel == null)
+					clabel = new CLabelImageProperty();
+				return clabel;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the image of a {@link Item}.
+	 * 
+	 * @return a value property for observing the image of a {@link Item}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Item, Image> imageItem() {
+		return new WidgetDelegatingValueProperty<Item, Image>(Image.class) {
+
+			IValueProperty<Item, Image> item = null;
+
+			@Override
+			protected IValueProperty<Item, Image> doGetDelegate(Item source) {
+				if (item == null)
+					item = new ItemImageProperty();
+				return item;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the image of a {@link Label}.
+	 * 
+	 * @return a value property for observing the image of a {@link Label}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Label, Image> imageLabel() {
+		return new WidgetDelegatingValueProperty<Label, Image>(Image.class) {
+
+			IValueProperty<Label, Image> label = null;
+
+			@Override
+			protected IValueProperty<Label, Image> doGetDelegate(Label source) {
+				if (label == null)
+					label = new LabelImageProperty();
+				return label;
+			}
+		};
 	}
 
 	/**
@@ -162,9 +487,67 @@
 	 * 
 	 * @return a list property for observing the items of a {@link CCombo},
 	 *         {@link Combo} or {@link List}.
+	 * @deprecated use instead one of the more specific methods (itemsCCombo,
+	 *             itemsCombo, or itemsList)
 	 */
+	// ok to ignore warnings in deprecated class
+	@SuppressWarnings("rawtypes")
 	public static IWidgetListProperty items() {
-		return new WidgetItemsProperty();
+		return new org.eclipse.jface.internal.databinding.swt.WidgetItemsProperty();
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the items of a {@link Combo}.
+	 * @since 1.7
+	 */
+	public static IWidgetListProperty<CCombo, String> itemsCCombo() {
+		return new WidgetDelegatingListProperty<CCombo, String>(CCombo.class) {
+			IListProperty<CCombo, String> cCombo = null;
+
+			@Override
+			protected IListProperty<CCombo, String> doGetDelegate(CCombo source) {
+				if (cCombo == null)
+					cCombo = new CComboItemsProperty();
+				return cCombo;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the items of a {@link Combo}.
+	 * @since 1.7
+	 */
+	public static IWidgetListProperty<Combo, String> itemsCombo() {
+		return new WidgetDelegatingListProperty<Combo, String>(Combo.class) {
+			IListProperty<Combo, String> combo = null;
+
+			@Override
+			protected IListProperty<Combo, String> doGetDelegate(Combo source) {
+				if (combo == null)
+					combo = new ComboItemsProperty();
+				return combo;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the items of a {@link Combo}.
+	 * @since 1.7
+	 */
+	public static IWidgetListProperty<List, String> itemsList() {
+		return new WidgetDelegatingListProperty<List, String>(List.class) {
+			IListProperty<List, String> combo = null;
+
+			@Override
+			protected IListProperty<List, String> doGetDelegate(List source) {
+				if (combo == null)
+					combo = new ListItemsProperty();
+				return combo;
+			}
+		};
 	}
 
 	/**
@@ -172,7 +555,7 @@
 	 * 
 	 * @return a value property for observing the location of a {@link Control}.
 	 */
-	public static IWidgetValueProperty location() {
+	public static IWidgetValueProperty<Control, Point> location() {
 		return new ControlLocationProperty();
 	}
 
@@ -182,9 +565,76 @@
 	 * 
 	 * @return a value property for observing the maximum value of a
 	 *         {@link Scale}, {@link Slider} (since 1.5) or {@link Spinner}.
+	 * @deprecated use instead one of the more specific methods (maximumScale,
+	 *             maximumSlider, or maximumSpinner)
 	 */
+	// ok to ignore warnings in deprecated class
+	@SuppressWarnings("rawtypes")
 	public static IWidgetValueProperty maximum() {
-		return new WidgetMaximumProperty();
+		return new org.eclipse.jface.internal.databinding.swt.WidgetMaximumProperty();
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the value of the maximum property
+	 *         of a {@link Scale}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Scale, Integer> maximumScale() {
+		return new WidgetDelegatingValueProperty<Scale, Integer>(Scale.class) {
+
+			IValueProperty<Scale, Integer> scale = null;
+
+			@Override
+			protected IValueProperty<Scale, Integer> doGetDelegate(Scale source) {
+				if (scale == null)
+					scale = new ScaleMaximumProperty();
+				return scale;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the value of the maximum property
+	 *         of a {@link Slider}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Slider, Integer> maximumSlider() {
+		return new WidgetDelegatingValueProperty<Slider, Integer>(Slider.class) {
+
+			IValueProperty<Slider, Integer> slider = null;
+
+			@Override
+			protected IValueProperty<Slider, Integer> doGetDelegate(
+					Slider source) {
+				if (slider == null)
+					slider = new SliderMaximumProperty();
+				return slider;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the value of the maximum property
+	 *         of a {@link Spinner}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Spinner, Integer> maximumSpinner() {
+		return new WidgetDelegatingValueProperty<Spinner, Integer>(
+				Spinner.class) {
+
+			IValueProperty<Spinner, Integer> spinner = null;
+
+			@Override
+			protected IValueProperty<Spinner, Integer> doGetDelegate(
+					Spinner source) {
+				if (spinner == null)
+					spinner = new SpinnerMaximumProperty();
+				return spinner;
+			}
+		};
 	}
 
 	/**
@@ -193,9 +643,54 @@
 	 * 
 	 * @return a value property for observing the message of a {@link Text} or
 	 *         {@link ToolTip}.
+	 * @deprecated use instead one of the more specific methods (messageText or
+	 *             messageToolTip)
 	 */
+	// ok to ignore warnings in deprecated class
+	@SuppressWarnings("rawtypes")
 	public static IWidgetValueProperty message() {
-		return new WidgetMessageProperty();
+		return new org.eclipse.jface.internal.databinding.swt.WidgetMessageProperty();
+	}
+
+	/**
+	 * Returns a value property for observing the message of a {@link Text}.
+	 * 
+	 * @return a value property for observing the message of a {@link Text}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Text, String> messageText() {
+		return new WidgetDelegatingValueProperty<Text, String>(Text.class) {
+
+			IValueProperty<Text, String> property = null;
+
+			@Override
+			protected IValueProperty<Text, String> doGetDelegate(Text source) {
+				if (property == null)
+					property = new TextMessageProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the message of a {@link ToolTip}.
+	 * 
+	 * @return a value property for observing the message of a {@link ToolTip}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<ToolTip, String> messageToolTip() {
+		return new WidgetDelegatingValueProperty<ToolTip, String>(ToolTip.class) {
+
+			IValueProperty<ToolTip, String> property = null;
+
+			@Override
+			protected IValueProperty<ToolTip, String> doGetDelegate(
+					ToolTip source) {
+				if (property == null)
+					property = new ToolTipMessageProperty();
+				return property;
+			}
+		};
 	}
 
 	/**
@@ -204,9 +699,76 @@
 	 * 
 	 * @return a value property for observing the minimum value of a
 	 *         {@link Scale}, {@link Slider} (since 1.5) or {@link Spinner}.
+	 * @deprecated use instead one of the more specific methods (minimumScale,
+	 *             minimumSlider, or minimumSpinner)
 	 */
+	// ok to ignore warnings in deprecated class
+	@SuppressWarnings("rawtypes")
 	public static IWidgetValueProperty minimum() {
-		return new WidgetMinimumProperty();
+		return new org.eclipse.jface.internal.databinding.swt.WidgetMinimumProperty();
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the value of the minimum property
+	 *         of a {@link Scale}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Scale, Integer> minimumScale() {
+		return new WidgetDelegatingValueProperty<Scale, Integer>(Scale.class) {
+
+			IValueProperty<Scale, Integer> scale = null;
+
+			@Override
+			protected IValueProperty<Scale, Integer> doGetDelegate(Scale source) {
+				if (scale == null)
+					scale = new ScaleMinimumProperty();
+				return scale;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the value of the minimum property
+	 *         of a {@link Slider}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Slider, Integer> minimumSlider() {
+		return new WidgetDelegatingValueProperty<Slider, Integer>(Slider.class) {
+
+			IValueProperty<Slider, Integer> slider = null;
+
+			@Override
+			protected IValueProperty<Slider, Integer> doGetDelegate(
+					Slider source) {
+				if (slider == null)
+					slider = new SliderMinimumProperty();
+				return slider;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the value of the minimum property
+	 *         of a {@link Spinner}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Spinner, Integer> minimumSpinner() {
+		return new WidgetDelegatingValueProperty<Spinner, Integer>(
+				Spinner.class) {
+
+			IValueProperty<Spinner, Integer> spinner = null;
+
+			@Override
+			protected IValueProperty<Spinner, Integer> doGetDelegate(
+					Spinner source) {
+				if (spinner == null)
+					spinner = new SpinnerMinimumProperty();
+				return spinner;
+			}
+		};
 	}
 
 	/**
@@ -219,9 +781,158 @@
 	 *         {@link Button}, {@link CCombo}, {@link Combo}, {@link DateTime},
 	 *         {@link List}, {@link MenuItem}, {@link Scale}, {@link Slider} or
 	 *         {@link Spinner}.
+	 * @deprecated use instead one of the more specific methods
+	 *             (selectionButton, selectionCCombo etc)
 	 */
+	// ok to ignore warnings in deprecated class
+	@SuppressWarnings({ "rawtypes" })
 	public static IWidgetValueProperty selection() {
-		return new WidgetSelectionProperty();
+		return new org.eclipse.jface.internal.databinding.swt.WidgetSelectionProperty();
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the selection state of a
+	 *         {@link Combo}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Combo, String> selectionCombo() {
+		return new WidgetDelegatingValueProperty<Combo, String>(Combo.class) {
+
+			IValueProperty<Combo, String> combo = null;
+
+			@Override
+			protected IValueProperty<Combo, String> doGetDelegate(Combo source) {
+				if (combo == null)
+					combo = new ComboSelectionProperty();
+				return combo;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the selection state of a
+	 *         {@link Button}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Button, Boolean> selectionButton() {
+		return new WidgetDelegatingValueProperty<Button, Boolean>(Button.class) {
+
+			IValueProperty<Button, Boolean> button = null;
+
+			@Override
+			protected IValueProperty<Button, Boolean> doGetDelegate(
+					Button source) {
+				if (button == null)
+					button = new ButtonSelectionProperty();
+				return button;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the selection state of a
+	 *         {@link CCombo}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<CCombo, String> selectionCCombo() {
+		return new WidgetDelegatingValueProperty<CCombo, String>(CCombo.class) {
+
+			IValueProperty<CCombo, String> cCombo = null;
+
+			@Override
+			protected IValueProperty<CCombo, String> doGetDelegate(CCombo source) {
+				if (cCombo == null)
+					cCombo = new CComboSelectionProperty();
+				return cCombo;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the selection state of a
+	 *         {@link List}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<List, String> selectionList() {
+		return new WidgetDelegatingValueProperty<List, String>(List.class) {
+
+			IValueProperty<List, String> listControl = null;
+
+			@Override
+			protected IValueProperty<List, String> doGetDelegate(List source) {
+				if (listControl == null)
+					listControl = new ListSelectionProperty();
+				return listControl;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the selection state of a
+	 *         {@link MenuItem}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<MenuItem, Boolean> selectionMenuItem() {
+		return new WidgetDelegatingValueProperty<MenuItem, Boolean>(
+				MenuItem.class) {
+
+			IValueProperty<MenuItem, Boolean> menuItem = null;
+
+			@Override
+			protected IValueProperty<MenuItem, Boolean> doGetDelegate(
+					MenuItem source) {
+				if (menuItem == null)
+					menuItem = new MenuItemSelectionProperty();
+				return menuItem;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the selection state of a
+	 *         {@link Scale}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Scale, Integer> selectionScale() {
+		return new WidgetDelegatingValueProperty<Scale, Integer>(Scale.class) {
+
+			IValueProperty<Scale, Integer> scale = null;
+
+			@Override
+			protected IValueProperty<Scale, Integer> doGetDelegate(Scale source) {
+				if (scale == null)
+					scale = new ScaleSelectionProperty();
+				return scale;
+			}
+		};
+	}
+
+	/**
+	 * 
+	 * @return a value property for observing the selection state of a
+	 *         {@link Spinner}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Spinner, Integer> selectionSpinner() {
+		return new WidgetDelegatingValueProperty<Spinner, Integer>(
+				Spinner.class) {
+
+			IValueProperty<Spinner, Integer> spinner = null;
+
+			@Override
+			protected IValueProperty<Spinner, Integer> doGetDelegate(
+					Spinner source) {
+				if (spinner == null)
+					spinner = new SpinnerSelectionProperty();
+				return spinner;
+			}
+		};
 	}
 
 	/**
@@ -229,9 +940,99 @@
 	 * {@link CCombo}, {@link Combo}, {@link List} or {@link Table}.
 	 * 
 	 * @return a value property for the single selection index of a SWT Combo.
+	 * @deprecated use one of the more specific methods below
+	 *             (singleSelectionIndexCCombo, singleSelectionIndexCombo,
+	 *             singleSelectionIndexList, or singleSelectionIndexTable)
 	 */
+	// ok to ignore warnings in deprecated class
+	@SuppressWarnings("rawtypes")
 	public static IWidgetValueProperty singleSelectionIndex() {
-		return new WidgetSingleSelectionIndexProperty();
+		return new org.eclipse.jface.internal.databinding.swt.WidgetSingleSelectionIndexProperty();
+	}
+
+	/**
+	 * Returns a value property for observing the single selection index of a
+	 * {@link CCombo}.
+	 * 
+	 * @return a value property for the single selection index of a SWT CCombo.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<CCombo, Integer> singleSelectionIndexCCombo() {
+		return new WidgetDelegatingValueProperty<CCombo, Integer>(CCombo.class) {
+
+			IValueProperty<CCombo, Integer> property = null;
+
+			@Override
+			protected IValueProperty<CCombo, Integer> doGetDelegate(
+					CCombo source) {
+				if (property == null)
+					property = new CComboSingleSelectionIndexProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the single selection index of a
+	 * {@link Combo}.
+	 * 
+	 * @return a value property for the single selection index of a SWT Combo.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Combo, Integer> singleSelectionIndexCombo() {
+		return new WidgetDelegatingValueProperty<Combo, Integer>(Combo.class) {
+
+			IValueProperty<Combo, Integer> property = null;
+
+			@Override
+			protected IValueProperty<Combo, Integer> doGetDelegate(Combo source) {
+				if (property == null)
+					property = new ComboSingleSelectionIndexProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the single selection index of a
+	 * {@link List}.
+	 * 
+	 * @return a value property for the single selection index of a SWT List.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<List, Integer> singleSelectionIndexList() {
+		return new WidgetDelegatingValueProperty<List, Integer>(List.class) {
+
+			IValueProperty<List, Integer> property = null;
+
+			@Override
+			protected IValueProperty<List, Integer> doGetDelegate(List source) {
+				if (property == null)
+					property = new ListSingleSelectionIndexProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the single selection index of a
+	 * {@link Table}.
+	 * 
+	 * @return a value property for the single selection index of a SWT Table.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Table, Integer> singleSelectionIndexTable() {
+		return new WidgetDelegatingValueProperty<Table, Integer>(Table.class) {
+
+			IValueProperty<Table, Integer> property = null;
+
+			@Override
+			protected IValueProperty<Table, Integer> doGetDelegate(Table source) {
+				if (property == null)
+					property = new TableSingleSelectionIndexProperty();
+				return property;
+			}
+		};
 	}
 
 	/**
@@ -239,7 +1040,7 @@
 	 * 
 	 * @return a value property for observing the size of a {@link Control}.
 	 */
-	public static IWidgetValueProperty size() {
+	public static IWidgetValueProperty<Control, Point> size() {
 		return new ControlSizeProperty();
 	}
 
@@ -253,9 +1054,216 @@
 	 *         {@link CCombo}, {@link CLabel}, {@link Combo}, {@link Item},
 	 *         {@link Label}, {@link Link}, {@link Shell}, {@link StyledText} or
 	 *         {@link Text}.
+	 * @deprecated use one of the more specific methods below (textButton,
+	 *             textCCombo, textCLabel, textCombo, textItem, textLabel,
+	 *             textLink, textShell, textStyledText, or textText)
 	 */
+	// ok to ignore warnings in deprecated class
+	@SuppressWarnings("rawtypes")
 	public static IWidgetValueProperty text() {
-		return new WidgetTextProperty();
+		return new org.eclipse.jface.internal.databinding.swt.WidgetTextProperty();
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link Button}.
+	 * 
+	 * @return a value property for observing the text of a {@link Button}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Button, String> textButton() {
+		return new WidgetDelegatingValueProperty<Button, String>(Button.class) {
+
+			IValueProperty<Button, String> property = null;
+
+			@Override
+			protected IValueProperty<Button, String> doGetDelegate(Button source) {
+				if (property == null)
+					property = new ButtonTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link CCombo}.
+	 * 
+	 * @return a value property for observing the text of a {@link CCombo}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<CCombo, String> textCCombo() {
+		return new WidgetDelegatingValueProperty<CCombo, String>(CCombo.class) {
+
+			IValueProperty<CCombo, String> property = null;
+
+			@Override
+			protected IValueProperty<CCombo, String> doGetDelegate(CCombo source) {
+				if (property == null)
+					property = new CComboTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link CLabel}.
+	 * 
+	 * @return a value property for observing the text of a {@link CLabel}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<CLabel, String> textCLabel() {
+		return new WidgetDelegatingValueProperty<CLabel, String>(CLabel.class) {
+
+			IValueProperty<CLabel, String> property = null;
+
+			@Override
+			protected IValueProperty<CLabel, String> doGetDelegate(CLabel source) {
+				if (property == null)
+					property = new CLabelTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link Combo}.
+	 * 
+	 * @return a value property for observing the text of a {@link Combo}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Combo, String> textCombo() {
+		return new WidgetDelegatingValueProperty<Combo, String>(Combo.class) {
+
+			IValueProperty<Combo, String> property = null;
+
+			@Override
+			protected IValueProperty<Combo, String> doGetDelegate(Combo source) {
+				if (property == null)
+					property = new ComboTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link Item}.
+	 * 
+	 * @return a value property for observing the text of a {@link Item}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Item, String> textItem() {
+		return new WidgetDelegatingValueProperty<Item, String>(Item.class) {
+
+			IValueProperty<Item, String> property = null;
+
+			@Override
+			protected IValueProperty<Item, String> doGetDelegate(Item source) {
+				if (property == null)
+					property = new ItemTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link Label}.
+	 * 
+	 * @return a value property for observing the text of a {@link Label}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Label, String> textLabel() {
+		return new WidgetDelegatingValueProperty<Label, String>(Label.class) {
+
+			IValueProperty<Label, String> property = null;
+
+			@Override
+			protected IValueProperty<Label, String> doGetDelegate(Label source) {
+				if (property == null)
+					property = new LabelTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link Link}.
+	 * 
+	 * @return a value property for observing the text of a {@link Link}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Link, String> textLink() {
+		return new WidgetDelegatingValueProperty<Link, String>(Link.class) {
+
+			IValueProperty<Link, String> property = null;
+
+			@Override
+			protected IValueProperty<Link, String> doGetDelegate(Link source) {
+				if (property == null)
+					property = new LinkTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link Shell}.
+	 * 
+	 * @return a value property for observing the text of a {@link Shell}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Shell, String> textShell() {
+		return new WidgetDelegatingValueProperty<Shell, String>(Shell.class) {
+
+			IValueProperty<Shell, String> property = null;
+
+			@Override
+			protected IValueProperty<Shell, String> doGetDelegate(Shell source) {
+				if (property == null)
+					property = new ShellTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link StyledText}.
+	 * 
+	 * @return a value property for observing the text of a {@link StyledText}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<StyledText, String> textStyledText() {
+		return new WidgetDelegatingValueProperty<StyledText, String>(
+				StyledText.class) {
+
+			IValueProperty<StyledText, String> property = null;
+
+			@Override
+			protected IValueProperty<StyledText, String> doGetDelegate(
+					StyledText source) {
+				if (property == null)
+					property = new StyledTextTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link Text}.
+	 * 
+	 * @return a value property for observing the text of a {@link Text}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Text, String> textText() {
+		return new WidgetDelegatingValueProperty<Text, String>(Text.class) {
+
+			IValueProperty<Text, String> property = null;
+
+			@Override
+			protected IValueProperty<Text, String> doGetDelegate(Text source) {
+				if (property == null)
+					property = new TextTextProperty();
+				return property;
+			}
+		};
 	}
 
 	/**
@@ -269,12 +1277,47 @@
 	 * 
 	 * @return a value property for observing the text of a {@link StyledText}
 	 *         or {@link Text}.
+	 * @deprecated use instead one of the more specific methods textText(event)
+	 *             or textStyledText(event)
 	 */
+	// ok to ignore warnings in deprecated method
+	@SuppressWarnings("rawtypes")
 	public static IWidgetValueProperty text(final int event) {
 		return text(new int[] { event });
 	}
 
 	/**
+	 * Returns a value property for observing the text of a {@link StyledText}.
+	 * 
+	 * @param event
+	 *            the SWT event type to register for change events. May be
+	 *            {@link SWT#None}, {@link SWT#Modify}, {@link SWT#FocusOut} or
+	 *            {@link SWT#DefaultSelection}.
+	 * 
+	 * @return a value property for observing the text of a {@link StyledText}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<StyledText, String> textStyledText(
+			int event) {
+		return textStyledText(new int[] { event });
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link Text}.
+	 * 
+	 * @param event
+	 *            the SWT event type to register for change events. May be
+	 *            {@link SWT#None}, {@link SWT#Modify}, {@link SWT#FocusOut} or
+	 *            {@link SWT#DefaultSelection}.
+	 * 
+	 * @return a value property for observing the text of a {@link Text}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Text, String> textText(int event) {
+		return textText(new int[] { event });
+	}
+
+	/**
 	 * Returns a value property for observing the text of a {@link StyledText}
 	 * or {@link Text}.
 	 * 
@@ -285,9 +1328,84 @@
 	 * 
 	 * @return a value property for observing the text of a {@link StyledText}
 	 *         or {@link Text}.
+	 * @deprecated use instead one of the more specific methods textText() or
+	 *             textStyledText()
 	 */
+	// ok to ignore warnings in deprecated method
+	@SuppressWarnings("rawtypes")
 	public static IWidgetValueProperty text(int[] events) {
-		return new WidgetTextWithEventsProperty((int[]) events.clone());
+		return new org.eclipse.jface.internal.databinding.swt.WidgetTextWithEventsProperty(
+				events.clone());
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link Text}.
+	 * 
+	 * @param events
+	 *            array of SWT event types to register for change events. May
+	 *            include {@link SWT#None}, {@link SWT#Modify},
+	 *            {@link SWT#FocusOut} or {@link SWT#DefaultSelection}.
+	 * 
+	 * @return a value property for observing the text of a {@link Text}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Text, String> textText(int[] events) {
+
+		for (int event : events) {
+			if (event != SWT.None && event != SWT.Modify
+					&& event != SWT.FocusOut && event != SWT.DefaultSelection)
+				throw new IllegalArgumentException("UpdateEventType [" //$NON-NLS-1$
+						+ event + "] is not supported."); //$NON-NLS-1$
+		}
+
+		final int[] finalEvents = events.clone();
+
+		return new WidgetDelegatingValueProperty<Text, String>() {
+			private IValueProperty<Text, String> text = null;
+
+			@Override
+			protected IValueProperty<Text, String> doGetDelegate(Text source) {
+				if (text == null)
+					text = new TextTextProperty(finalEvents);
+				return text;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the text of a {@link StyledText}.
+	 * 
+	 * @param events
+	 *            array of SWT event types to register for change events. May
+	 *            include {@link SWT#None}, {@link SWT#Modify},
+	 *            {@link SWT#FocusOut} or {@link SWT#DefaultSelection}.
+	 * 
+	 * @return a value property for observing the text of a {@link StyledText}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<StyledText, String> textStyledText(
+			int[] events) {
+
+		for (int event : events) {
+			if (event != SWT.None && event != SWT.Modify
+					&& event != SWT.FocusOut && event != SWT.DefaultSelection)
+				throw new IllegalArgumentException("UpdateEventType [" //$NON-NLS-1$
+						+ event + "] is not supported."); //$NON-NLS-1$
+		}
+
+		final int[] finalEvents = events.clone();
+
+		return new WidgetDelegatingValueProperty<StyledText, String>() {
+			private IValueProperty<StyledText, String> text = null;
+
+			@Override
+			protected IValueProperty<StyledText, String> doGetDelegate(
+					StyledText source) {
+				if (text == null)
+					text = new StyledTextTextProperty(finalEvents);
+				return text;
+			}
+		};
 	}
 
 	/**
@@ -299,9 +1417,176 @@
 	 *         {@link CTabItem}, {@link Control}, {@link TabItem},
 	 *         {@link TableColumn}, {@link ToolItem}, {@link TrayItem} or
 	 *         {@link TreeColumn}.
+	 * @deprecated use instead one of the more specific methods
+	 *             tooltipCTabItem(), tooltipControl() etc
 	 */
+	// ok to ignore warnings in deprecated method
+	@SuppressWarnings("rawtypes")
 	public static IWidgetValueProperty tooltipText() {
-		return new WidgetTooltipTextProperty();
+		return new org.eclipse.jface.internal.databinding.swt.WidgetTooltipTextProperty();
+	}
+
+	/**
+	 * Returns a value property for observing the tooltip text of a
+	 * {@link CTabItem}.
+	 * 
+	 * @return a value property for observing the tooltip text of a
+	 *         {@link CTabItem}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<CTabItem, String> tooltipCTabItem() {
+		return new WidgetDelegatingValueProperty<CTabItem, String>(String.class) {
+
+			IValueProperty<CTabItem, String> property = null;
+
+			@Override
+			protected IValueProperty<CTabItem, String> doGetDelegate(
+					CTabItem source) {
+				if (property == null)
+					property = new CTabItemTooltipTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the tooltip text of a
+	 * {@link Control}.
+	 * 
+	 * @return a value property for observing the tooltip text of a
+	 *         {@link Control}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<Control, String> tooltipControl() {
+		return new WidgetDelegatingValueProperty<Control, String>(String.class) {
+
+			IValueProperty<Control, String> property = null;
+
+			@Override
+			protected IValueProperty<Control, String> doGetDelegate(
+					Control source) {
+				if (property == null)
+					property = new ControlTooltipTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the tooltip text of a
+	 * {@link TabItem}.
+	 * 
+	 * @return a value property for observing the tooltip text of a
+	 *         {@link TabItem}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<TabItem, String> tooltipTabItem() {
+		return new WidgetDelegatingValueProperty<TabItem, String>(String.class) {
+
+			IValueProperty<TabItem, String> property = null;
+
+			@Override
+			protected IValueProperty<TabItem, String> doGetDelegate(
+					TabItem source) {
+				if (property == null)
+					property = new TabItemTooltipTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the tooltip text of a
+	 * {@link TableColumn}.
+	 * 
+	 * @return a value property for observing the tooltip text of a
+	 *         {@link TableColumn}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<TableColumn, String> tooltipTableColumn() {
+		return new WidgetDelegatingValueProperty<TableColumn, String>(
+				String.class) {
+
+			IValueProperty<TableColumn, String> property = null;
+
+			@Override
+			protected IValueProperty<TableColumn, String> doGetDelegate(
+					TableColumn source) {
+				if (property == null)
+					property = new TableColumnTooltipTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the tooltip text of a
+	 * {@link ToolItem}.
+	 * 
+	 * @return a value property for observing the tooltip text of a
+	 *         {@link ToolItem}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<ToolItem, String> tooltipToolItem() {
+		return new WidgetDelegatingValueProperty<ToolItem, String>(String.class) {
+
+			IValueProperty<ToolItem, String> property = null;
+
+			@Override
+			protected IValueProperty<ToolItem, String> doGetDelegate(
+					ToolItem source) {
+				if (property == null)
+					property = new ToolItemTooltipTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the tooltip text of a
+	 * {@link TrayItem}.
+	 * 
+	 * @return a value property for observing the tooltip text of a
+	 *         {@link TrayItem}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<TrayItem, String> tooltipTrayItem() {
+		return new WidgetDelegatingValueProperty<TrayItem, String>(String.class) {
+
+			IValueProperty<TrayItem, String> property = null;
+
+			@Override
+			protected IValueProperty<TrayItem, String> doGetDelegate(
+					TrayItem source) {
+				if (property == null)
+					property = new TrayItemTooltipTextProperty();
+				return property;
+			}
+		};
+	}
+
+	/**
+	 * Returns a value property for observing the tooltip text of a
+	 * {@link TreeColumn}.
+	 * 
+	 * @return a value property for observing the tooltip text of a
+	 *         {@link TreeColumn}.
+	 * @since 1.7
+	 */
+	public static IWidgetValueProperty<TreeColumn, String> tooltipTreeColumn() {
+		return new WidgetDelegatingValueProperty<TreeColumn, String>(
+				String.class) {
+
+			IValueProperty<TreeColumn, String> property = null;
+
+			@Override
+			protected IValueProperty<TreeColumn, String> doGetDelegate(
+					TreeColumn source) {
+				if (property == null)
+					property = new TreeColumnTooltipTextProperty();
+				return property;
+			}
+		};
 	}
 
 	/**
@@ -311,7 +1596,7 @@
 	 * @return a value property for observing the visibility state of a
 	 *         {@link Control}.
 	 */
-	public static IWidgetValueProperty visible() {
+	public static IWidgetValueProperty<Control, Boolean> visible() {
 		return new ControlVisibleProperty();
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetValueProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetValueProperty.java
index 00cffa7..395b27c 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetValueProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/swt/WidgetValueProperty.java
@@ -14,6 +14,7 @@
 
 import org.eclipse.core.databinding.observable.Realm;
 import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.ValueDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.value.SimpleValueProperty;
@@ -37,10 +38,12 @@
  * event type constants to the super constructor to indicate which events signal
  * a property change.
  * 
+ * @param <S>
+ * @param <T>
  * @since 1.3
  */
-public abstract class WidgetValueProperty extends SimpleValueProperty implements
-		IWidgetValueProperty {
+public abstract class WidgetValueProperty<S extends Widget, T> extends
+		SimpleValueProperty<S, T> implements IWidgetValueProperty<S, T> {
 	private int[] changeEvents;
 	private int[] staleEvents;
 
@@ -89,35 +92,38 @@
 		this.staleEvents = staleEvents;
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<S> adaptListener(
+			ISimplePropertyListener<ValueDiff<T>> listener) {
 		if (changeEvents == null && staleEvents == null)
 			return null;
-		return new WidgetListener(this, listener, changeEvents, staleEvents);
+		return new WidgetListener<S, ValueDiff<T>>(this, listener,
+				changeEvents, staleEvents);
 	}
 
-	public IObservableValue observe(Object source) {
-		if (source instanceof Widget) {
-			return observe((Widget) source);
-		}
-		return super.observe(source);
+	/**
+	 * @return observable
+	 * @since 1.7
+	 */
+	public ISWTObservableValue<T> observe(Realm realm, S source) {
+		return wrapObservable(super.observe(realm, source), source);
 	}
 
-	public IObservableValue observe(Realm realm, Object source) {
-		return wrapObservable(super.observe(realm, source), (Widget) source);
+	/**
+	 * @param observable
+	 * @param widget
+	 * @return observable value
+	 * @since 1.7
+	 */
+	protected ISWTObservableValue<T> wrapObservable(
+			IObservableValue<T> observable, S widget) {
+		return new SWTObservableValueDecorator<T>(observable, widget);
 	}
 
-	protected ISWTObservableValue wrapObservable(IObservableValue observable,
-			Widget widget) {
-		return new SWTObservableValueDecorator(observable, widget);
+	public ISWTObservableValue<T> observe(S widget) {
+		return observe(SWTObservables.getRealm(widget.getDisplay()), widget);
 	}
 
-	public ISWTObservableValue observe(Widget widget) {
-		return (ISWTObservableValue) observe(SWTObservables.getRealm(widget
-				.getDisplay()), widget);
-	}
-
-	public ISWTObservableValue observeDelayed(int delay, Widget widget) {
+	public ISWTObservableValue<T> observeDelayed(int delay, S widget) {
 		return SWTObservables.observeDelayedValue(delay, observe(widget));
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/util/JFaceProperties.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/util/JFaceProperties.java
index 1119c1e..ebc329a 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/util/JFaceProperties.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/util/JFaceProperties.java
@@ -39,9 +39,9 @@
 	 * 
 	 * @return an observable value
 	 */
-	public static IValueProperty value(Class clazz, String fieldName,
-			String propertyName) {
-		return new JFaceProperty(fieldName, propertyName, clazz);
+	public static <S, T> IValueProperty<S, T> value(Class<S> clazz,
+			String fieldName, String propertyName) {
+		return new JFaceProperty<S, T>(fieldName, propertyName, clazz);
 	}
 
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/util/Util.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/util/Util.java
new file mode 100644
index 0000000..17eddd0
--- /dev/null
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/util/Util.java
@@ -0,0 +1,56 @@
+package org.eclipse.jface.databinding.util;
+
+import java.lang.reflect.Array;
+
+/**
+ * @since 1.7
+ * 
+ */
+public class Util {
+
+	/**
+	 * Checks whether the two objects are <code>null</code> -- allowing for
+	 * <code>null</code>.
+	 * 
+	 * @param left
+	 *            The left object to compare; may be <code>null</code>.
+	 * @param right
+	 *            The right object to compare; may be <code>null</code>.
+	 * @return <code>true</code> if the two objects are equivalent;
+	 *         <code>false</code> otherwise.
+	 */
+	public static final boolean equals(final Object left, final Object right) {
+		return left == null ? right == null : ((right != null) && left
+				.equals(right));
+	}
+
+	/**
+	 * This method carries out an operation that the Java 5 compiler claims is
+	 * an unchecked cast but if fact it should not be. No cast should be
+	 * necessary in the following code because the getComponentType method
+	 * should return a correctly typed result.
+	 * 
+	 * @param a
+	 * @return the class of the elements of the given array
+	 */
+	@SuppressWarnings("unchecked")
+	public static <E> Class<E> getComponentType(E[] a) {
+		return (Class<E>) a.getClass().getComponentType();
+	}
+
+	/**
+	 * This method carries out an operation that the Java 5 compiler claims is
+	 * an unchecked cast but if fact it should not be. No cast should be
+	 * necessary in the following code because the newInstance method should
+	 * return a correctly typed result.
+	 * 
+	 * @param componentType
+	 * @param size
+	 * @return an array of the given element type and size
+	 */
+	@SuppressWarnings("unchecked")
+	public static <E> E[] createArrayInstance(Class<E> componentType, int size) {
+		return (E[]) Array.newInstance(componentType, size);
+	}
+
+}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerListProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerListProperty.java
index 81d5cc2..ce1de18 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerListProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerListProperty.java
@@ -17,10 +17,13 @@
 /**
  * {@link IListProperty} for observing a JFace viewer
  * 
+ * @param <S>
+ * 
  * @since 1.3
  * @noimplement This interface is not intended to be implemented by clients.
  */
-public interface IViewerListProperty extends IListProperty {
+public interface IViewerListProperty<S extends Viewer> extends
+		IListProperty<S, Object> {
 	/**
 	 * Returns an {@link IViewerObservableList} observing this list property on
 	 * the given viewer
@@ -30,5 +33,5 @@
 	 * @return an observable list observing this list property on the given
 	 *         viewer
 	 */
-	public IViewerObservableList observe(Viewer viewer);
+	public IViewerObservableList<S> observe(S viewer);
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservable.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservable.java
index 50703cd..06f44cc 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservable.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservable.java
@@ -17,14 +17,16 @@
 /**
  * {@link IObservable} observing a JFace Viewer.
  * 
+ * @param <S>
+ * 
  * @since 1.2
  * 
  */
-public interface IViewerObservable extends IObservable {
+public interface IViewerObservable<S extends Viewer> extends IObservable {
 	/**
 	 * Returns the underlying viewer for this observable.
 	 * 
 	 * @return the viewer.
 	 */
-	public Viewer getViewer();
+	public S getViewer();
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableList.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableList.java
index 6b3ed4b..91679c6 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableList.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableList.java
@@ -12,13 +12,16 @@
 package org.eclipse.jface.databinding.viewers;
 
 import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.jface.viewers.Viewer;
 
 /**
  * {@link IObservableList} observing a JFace Viewer.
  * 
+ * @param <S>
+ * 
  * @since 1.2
  * 
  */
-public interface IViewerObservableList extends IObservableList,
-		IViewerObservable {
+public interface IViewerObservableList<S extends Viewer> extends
+		IObservableList<Object>, IViewerObservable<S> {
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableSet.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableSet.java
index b8f98e6..1b30d59 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableSet.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableSet.java
@@ -12,12 +12,17 @@
 package org.eclipse.jface.databinding.viewers;
 
 import org.eclipse.core.databinding.observable.set.IObservableSet;
+import org.eclipse.jface.viewers.Viewer;
 
 /**
  * {@link IObservableSet} observing a JFace Viewer.
  * 
+ * @param <S>
+ * @param <E>
+ * 
  * @since 1.2
  * 
  */
-public interface IViewerObservableSet extends IObservableSet, IViewerObservable {
+public interface IViewerObservableSet<S extends Viewer, E> extends
+		IObservableSet<E>, IViewerObservable<S> {
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableValue.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableValue.java
index 6c145cf..3665116 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableValue.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerObservableValue.java
@@ -12,13 +12,16 @@
 package org.eclipse.jface.databinding.viewers;
 
 import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.viewers.Viewer;
 
 /**
  * {@link IObservableValue} observing a JFace Viewer.
  * 
+ * @param <S>
+ * 
  * @since 1.2
  * 
  */
-public interface IViewerObservableValue extends IObservableValue,
-		IViewerObservable {
+public interface IViewerObservableValue<S extends Viewer> extends
+		IObservableValue<Object>, IViewerObservable<S> {
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerSetProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerSetProperty.java
index fb842bc..a1bfded 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerSetProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerSetProperty.java
@@ -17,10 +17,14 @@
 /**
  * {@link ISetProperty} for observing a JFace viewer
  * 
+ * @param <S>
+ * @param <E>
+ * 
  * @since 1.3
  * @noimplement This interface is not intended to be implemented by clients.
  */
-public interface IViewerSetProperty extends ISetProperty {
+public interface IViewerSetProperty<S extends Viewer, E> extends
+		ISetProperty<S, E> {
 	/**
 	 * Returns an {@link IViewerObservableSet} observing this set property on
 	 * the given viewer
@@ -29,5 +33,5 @@
 	 *            the source viewer
 	 * @return an observable set observing this set property on the given viewer
 	 */
-	public IViewerObservableSet observe(Viewer viewer);
+	public IViewerObservableSet<S, E> observe(S viewer);
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerValueProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerValueProperty.java
index c9f8092..6c04faf 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerValueProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/IViewerValueProperty.java
@@ -17,10 +17,13 @@
 /**
  * {@link IValueProperty} for observing a JFace viewer
  * 
+ * @param <S>
+ * 
  * @since 1.3
  * @noimplement This interface is not intended to be implemented by clients.
  */
-public interface IViewerValueProperty extends IValueProperty {
+public interface IViewerValueProperty<S extends Viewer> extends
+		IValueProperty<S, Object> {
 	/**
 	 * Returns an {@link IViewerObservableValue} observing this value property
 	 * on the given viewer
@@ -30,7 +33,7 @@
 	 * @return an observable value observing this value property on the given
 	 *         viewer
 	 */
-	public IViewerObservableValue observe(Viewer viewer);
+	public IViewerObservableValue<S> observe(S viewer);
 
 	/**
 	 * Returns an {@link IViewerObservableValue} observing this value property
@@ -50,5 +53,5 @@
 	 *         viewer, and which delays change notifications for
 	 *         <code>delay</code> milliseconds.
 	 */
-	public IViewerObservableValue observeDelayed(int delay, Viewer viewer);
+	public IViewerObservableValue<S> observeDelayed(int delay, S viewer);
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ListeningLabelProvider.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ListeningLabelProvider.java
index 5588a6f..da45445 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ListeningLabelProvider.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ListeningLabelProvider.java
@@ -24,26 +24,28 @@
  */
 public abstract class ListeningLabelProvider extends ViewerLabelProvider {
 
-	private ISetChangeListener listener = new ISetChangeListener() {
-		public void handleSetChange(SetChangeEvent event) {
-			for (Iterator it = event.diff.getAdditions().iterator(); it.hasNext();) {
+	private ISetChangeListener<Object> listener = new ISetChangeListener<Object>() {
+		public void handleSetChange(SetChangeEvent<Object> event) {
+			for (Iterator<Object> it = event.diff.getAdditions().iterator(); it
+					.hasNext();) {
 				addListenerTo(it.next());
 			}
-			for (Iterator it = event.diff.getRemovals().iterator(); it.hasNext();) {
+			for (Iterator<Object> it = event.diff.getRemovals().iterator(); it
+					.hasNext();) {
 				removeListenerFrom(it.next());
 			}
 		}
 	};
 
-	private IObservableSet items;
+	private IObservableSet<Object> items;
 
 	/**
 	 * @param itemsThatNeedLabels
 	 */
-	public ListeningLabelProvider(IObservableSet itemsThatNeedLabels) {
+	public ListeningLabelProvider(IObservableSet<Object> itemsThatNeedLabels) {
 		this.items = itemsThatNeedLabels;
 		items.addSetChangeListener(listener);
-		for (Iterator it = items.iterator(); it.hasNext();) {
+		for (Iterator<Object> it = items.iterator(); it.hasNext();) {
 			addListenerTo(it.next());
 		}
 	}
@@ -59,7 +61,7 @@
 	protected abstract void addListenerTo(Object next);
 
 	public void dispose() {
-		for (Iterator iter = items.iterator(); iter.hasNext();) {
+		for (Iterator<Object> iter = items.iterator(); iter.hasNext();) {
 			removeListenerFrom(iter.next());
 		}
 		items.removeSetChangeListener(listener);
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableListContentProvider.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableListContentProvider.java
index 2345369..f9fc4d5 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableListContentProvider.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableListContentProvider.java
@@ -45,7 +45,7 @@
 	private ObservableCollectionContentProvider impl;
 
 	private static class Impl extends ObservableCollectionContentProvider
-			implements IListChangeListener {
+			implements IListChangeListener<Object> {
 		private Viewer viewer;
 
 		Impl(IViewerUpdater explicitViewerUpdater) {
@@ -63,26 +63,26 @@
 		}
 
 		protected void addCollectionChangeListener(
-				IObservableCollection collection) {
-			((IObservableList) collection).addListChangeListener(this);
+				IObservableCollection<?> collection) {
+			((IObservableList<?>) collection).addListChangeListener(this);
 		}
 
 		protected void removeCollectionChangeListener(
-				IObservableCollection collection) {
-			((IObservableList) collection).removeListChangeListener(this);
+				IObservableCollection<?> collection) {
+			((IObservableList<?>) collection).removeListChangeListener(this);
 		}
 
-		public void handleListChange(ListChangeEvent event) {
+		public void handleListChange(ListChangeEvent<Object> event) {
 			if (isViewerDisposed())
 				return;
 
 			// Determine which elements were added and removed
-			final Set knownElementAdditions = ViewerElementSet
+			final Set<Object> knownElementAdditions = ViewerElementSet
 					.withComparer(comparer);
-			final Set knownElementRemovals = ViewerElementSet
+			final Set<Object> knownElementRemovals = ViewerElementSet
 					.withComparer(comparer);
 			final boolean[] suspendRedraw = new boolean[] { false };
-			event.diff.accept(new ListDiffVisitor() {
+			event.diff.accept(new ListDiffVisitor<Object>() {
 				public void handleAdd(int index, Object element) {
 					knownElementAdditions.add(element);
 				}
@@ -114,7 +114,7 @@
 			if (suspendRedraw[0])
 				viewer.getControl().setRedraw(false);
 			try {
-				event.diff.accept(new ListDiffVisitor() {
+				event.diff.accept(new ListDiffVisitor<Object>() {
 					public void handleAdd(int index, Object element) {
 						viewerUpdater.insert(element, index);
 					}
@@ -199,7 +199,7 @@
 	 * 
 	 * @return readableSet of items that will need labels
 	 */
-	public IObservableSet getKnownElements() {
+	public IObservableSet<Object> getKnownElements() {
 		return impl.getKnownElements();
 	}
 
@@ -211,7 +211,7 @@
 	 * @return the set of known elements which have been realized in the viewer.
 	 * @since 1.3
 	 */
-	public IObservableSet getRealizedElements() {
+	public IObservableSet<Object> getRealizedElements() {
 		return impl.getRealizedElements();
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableListTreeContentProvider.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableListTreeContentProvider.java
index fc94004..00153b8 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableListTreeContentProvider.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableListTreeContentProvider.java
@@ -45,7 +45,8 @@
 	private static class Impl extends ObservableCollectionTreeContentProvider {
 		private Viewer viewer;
 
-		public Impl(IObservableFactory listFactory,
+		public Impl(
+				IObservableFactory<Object, IObservableList<Object>> listFactory,
 				TreeStructureAdvisor structureAdvisor) {
 			super(listFactory, structureAdvisor);
 		}
@@ -55,24 +56,24 @@
 			super.inputChanged(viewer, oldInput, newInput);
 		}
 
-		private class ListChangeListener implements IListChangeListener {
+		private class ListChangeListener implements IListChangeListener<Object> {
 			final Object parentElement;
 
 			public ListChangeListener(Object parentElement) {
 				this.parentElement = parentElement;
 			}
 
-			public void handleListChange(ListChangeEvent event) {
+			public void handleListChange(ListChangeEvent<Object> event) {
 				if (isViewerDisposed())
 					return;
 
 				// Determine which elements are being added and removed
-				final Set localKnownElementAdditions = ViewerElementSet
+				final Set<Object> localKnownElementAdditions = ViewerElementSet
 						.withComparer(comparer);
-				final Set localKnownElementRemovals = ViewerElementSet
+				final Set<Object> localKnownElementRemovals = ViewerElementSet
 						.withComparer(comparer);
 				final boolean[] suspendRedraw = new boolean[] { false };
-				event.diff.accept(new ListDiffVisitor() {
+				event.diff.accept(new ListDiffVisitor<Object>() {
 					public void handleAdd(int index, Object element) {
 						localKnownElementAdditions.add(element);
 					}
@@ -95,13 +96,13 @@
 				});
 				localKnownElementRemovals.removeAll(event.getObservableList());
 
-				Set knownElementAdditions = ViewerElementSet
+				Set<Object> knownElementAdditions = ViewerElementSet
 						.withComparer(comparer);
 				knownElementAdditions.addAll(localKnownElementAdditions);
 				knownElementAdditions.removeAll(knownElements);
 
-				Set knownElementRemovals = findPendingRemovals(parentElement,
-						localKnownElementRemovals);
+				Set<Object> knownElementRemovals = findPendingRemovals(
+						parentElement, localKnownElementRemovals);
 				knownElementRemovals.retainAll(knownElements);
 
 				knownElements.addAll(knownElementAdditions);
@@ -109,15 +110,15 @@
 					realizedElements.removeAll(knownElementRemovals);
 				}
 
-				for (Iterator it = localKnownElementAdditions.iterator(); it
-						.hasNext();) {
+				for (Iterator<Object> it = localKnownElementAdditions
+						.iterator(); it.hasNext();) {
 					getOrCreateNode(it.next()).addParent(parentElement);
 				}
 
 				if (suspendRedraw[0])
 					viewer.getControl().setRedraw(false);
 				try {
-					event.diff.accept(new ListDiffVisitor() {
+					event.diff.accept(new ListDiffVisitor<Object>() {
 						public void handleAdd(int index, Object child) {
 							viewerUpdater.insert(parentElement, child, index);
 						}
@@ -143,7 +144,7 @@
 						viewer.getControl().setRedraw(true);
 				}
 
-				for (Iterator it = localKnownElementRemovals.iterator(); it
+				for (Iterator<Object> it = localKnownElementRemovals.iterator(); it
 						.hasNext();) {
 					TreeNode node = getExistingNode(it.next());
 					if (node != null) {
@@ -164,16 +165,18 @@
 		}
 
 		protected void addCollectionChangeListener(
-				IObservableCollection collection, IObservablesListener listener) {
-			IObservableList list = (IObservableList) collection;
-			IListChangeListener listListener = (IListChangeListener) listener;
+				IObservableCollection<Object> collection,
+				IObservablesListener listener) {
+			IObservableList<Object> list = (IObservableList<Object>) collection;
+			IListChangeListener<Object> listListener = (IListChangeListener<Object>) listener;
 			list.addListChangeListener(listListener);
 		}
 
 		protected void removeCollectionChangeListener(
-				IObservableCollection collection, IObservablesListener listener) {
-			IObservableList list = (IObservableList) collection;
-			IListChangeListener listListener = (IListChangeListener) listener;
+				IObservableCollection<Object> collection,
+				IObservablesListener listener) {
+			IObservableList<Object> list = (IObservableList<Object>) collection;
+			IListChangeListener<Object> listListener = (IListChangeListener<Object>) listener;
 			list.removeListChangeListener(listListener);
 		}
 	}
@@ -194,7 +197,8 @@
 	 *            non-null advisor if they can provide additional structural
 	 *            information about the tree.
 	 */
-	public ObservableListTreeContentProvider(IObservableFactory listFactory,
+	public ObservableListTreeContentProvider(
+			IObservableFactory<Object, IObservableList<Object>> listFactory,
 			TreeStructureAdvisor structureAdvisor) {
 		impl = new Impl(listFactory, structureAdvisor);
 	}
@@ -244,7 +248,7 @@
 	 * 
 	 * @return readableSet of items that will need labels
 	 */
-	public IObservableSet getKnownElements() {
+	public IObservableSet<Object> getKnownElements() {
 		return impl.getKnownElements();
 	}
 
@@ -256,7 +260,7 @@
 	 * @return the set of known elements which have been realized in the viewer.
 	 * @since 1.3
 	 */
-	public IObservableSet getRealizedElements() {
+	public IObservableSet<Object> getRealizedElements() {
 		return impl.getRealizedElements();
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableMapCellLabelProvider.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableMapCellLabelProvider.java
index 6ef1d31..73f23e1 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableMapCellLabelProvider.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableMapCellLabelProvider.java
@@ -39,14 +39,14 @@
 	 * 
 	 * @since 1.4
 	 */
-	protected IObservableMap[] attributeMaps;
+	protected IObservableMap<Object, Object>[] attributeMaps;
 
-	private IMapChangeListener mapChangeListener = new IMapChangeListener() {
-		public void handleMapChange(MapChangeEvent event) {
-			Set affectedElements = event.diff.getChangedKeys();
+	private IMapChangeListener<Object, Object> mapChangeListener = new IMapChangeListener<Object, Object>() {
+		public void handleMapChange(MapChangeEvent<Object, Object> event) {
+			Set<Object> affectedElements = event.diff.getChangedKeys();
 			LabelProviderChangedEvent newEvent = new LabelProviderChangedEvent(
-					ObservableMapCellLabelProvider.this, affectedElements
-							.toArray());
+					ObservableMapCellLabelProvider.this,
+					affectedElements.toArray());
 			fireLabelProviderChanged(newEvent);
 		}
 	};
@@ -56,7 +56,8 @@
 	 * 
 	 * @param attributeMap
 	 */
-	public ObservableMapCellLabelProvider(IObservableMap attributeMap) {
+	public ObservableMapCellLabelProvider(
+			IObservableMap<Object, Object> attributeMap) {
 		this(new IObservableMap[] { attributeMap });
 	}
 
@@ -67,7 +68,8 @@
 	 * 
 	 * @param attributeMaps
 	 */
-	protected ObservableMapCellLabelProvider(IObservableMap[] attributeMaps) {
+	protected ObservableMapCellLabelProvider(
+			IObservableMap<Object, Object>[] attributeMaps) {
 		System.arraycopy(attributeMaps, 0,
 				this.attributeMaps = new IObservableMap[attributeMaps.length],
 				0, attributeMaps.length);
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableMapLabelProvider.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableMapLabelProvider.java
index 7e7066c..0d69bb2 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableMapLabelProvider.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableMapLabelProvider.java
@@ -13,6 +13,10 @@
 
 package org.eclipse.jface.databinding.viewers;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 import org.eclipse.core.databinding.observable.map.IMapChangeListener;
@@ -31,10 +35,17 @@
  * {@link #getColumnImage(Object, int)}, for tables or trees with columns, or by
  * implementing additional mixin interfaces for colors, fonts etc.
  * 
+ * @param <T>
+ *            the basemost class of all elements expected
+ * @param <E>
+ *            the basemost class of all label values, which will often be
+ *            <String> but no always because values are converted using
+ *            toString() method
+ * 
  * @since 1.1
  * 
  */
-public class ObservableMapLabelProvider extends LabelProvider implements
+public class ObservableMapLabelProvider<T, E> extends LabelProvider implements
 		ILabelProvider, ITableLabelProvider {
 
 	/**
@@ -42,12 +53,21 @@
 	 * Subclasses may reference these maps to provide custom labels.
 	 * 
 	 * @since 1.4
+	 * @deprecated to access the maps use attributeMapsList instead
 	 */
-	protected IObservableMap[] attributeMaps;
+	protected IObservableMap<?, ?>[] attributeMaps;
 
-	private IMapChangeListener mapChangeListener = new IMapChangeListener() {
-		public void handleMapChange(MapChangeEvent event) {
-			Set affectedElements = event.diff.getChangedKeys();
+	/**
+	 * Observable maps typically mapping from viewer elements to label values.
+	 * Subclasses may reference these maps to provide custom labels.
+	 * 
+	 * @since 1.7
+	 */
+	protected List<IObservableMap<T, E>> attributeMapsList;
+
+	private IMapChangeListener<T, E> mapChangeListener = new IMapChangeListener<T, E>() {
+		public void handleMapChange(MapChangeEvent<T, E> event) {
+			Set<T> affectedElements = event.diff.getChangedKeys();
 			LabelProviderChangedEvent newEvent = new LabelProviderChangedEvent(
 					ObservableMapLabelProvider.this, affectedElements.toArray());
 			fireLabelProviderChanged(newEvent);
@@ -57,28 +77,44 @@
 	/**
 	 * @param attributeMap
 	 */
-	public ObservableMapLabelProvider(IObservableMap attributeMap) {
-		this(new IObservableMap[] { attributeMap });
+	public ObservableMapLabelProvider(IObservableMap<T, E> attributeMap) {
+		this(Collections.singletonList(attributeMap));
 	}
 
 	/**
 	 * @param attributeMaps
+	 * @deprecated use the constructor that takes a List instead
 	 */
-	public ObservableMapLabelProvider(IObservableMap[] attributeMaps) {
-		System.arraycopy(attributeMaps, 0,
-				this.attributeMaps = new IObservableMap[attributeMaps.length],
-				0, attributeMaps.length);
-		for (int i = 0; i < attributeMaps.length; i++) {
-			attributeMaps[i].addMapChangeListener(mapChangeListener);
+	public ObservableMapLabelProvider(IObservableMap<T, E>[] attributeMaps) {
+		this(Arrays.asList(attributeMaps));
+	}
+
+	/**
+	 * @param attributeMapsList
+	 * @since 1.7
+	 */
+	@SuppressWarnings("deprecation")
+	// This class must initialize the deprecated field
+	public ObservableMapLabelProvider(
+			List<IObservableMap<T, E>> attributeMapsList) {
+		this.attributeMapsList = new ArrayList<IObservableMap<T, E>>(
+				attributeMapsList);
+
+		// Also copy to the array for legacy reasons
+		this.attributeMaps = attributeMapsList
+				.toArray(new IObservableMap<?, ?>[attributeMapsList.size()]);
+
+		for (IObservableMap<T, E> map : attributeMapsList) {
+			map.addMapChangeListener(mapChangeListener);
 		}
 	}
 
 	public void dispose() {
-		for (int i = 0; i < attributeMaps.length; i++) {
-			attributeMaps[i].removeMapChangeListener(mapChangeListener);
+		for (IObservableMap<T, E> map : attributeMapsList) {
+			map.removeMapChangeListener(mapChangeListener);
 		}
 		super.dispose();
-		this.attributeMaps = null;
+		this.attributeMapsList = null;
 		this.mapChangeListener = null;
 	}
 
@@ -95,8 +131,8 @@
 	}
 
 	public String getColumnText(Object element, int columnIndex) {
-		if (columnIndex < attributeMaps.length) {
-			Object result = attributeMaps[columnIndex].get(element);
+		if (columnIndex < attributeMapsList.size()) {
+			Object result = attributeMapsList.get(columnIndex).get(element);
 			return result == null ? "" : result.toString(); //$NON-NLS-1$
 		}
 		return null;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableSetContentProvider.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableSetContentProvider.java
index 3240eb2..c8261a4 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableSetContentProvider.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableSetContentProvider.java
@@ -39,7 +39,7 @@
 	private ObservableCollectionContentProvider impl;
 
 	private static class Impl extends ObservableCollectionContentProvider
-			implements ISetChangeListener {
+			implements ISetChangeListener<Object> {
 		protected Impl(IViewerUpdater explicitViewerUpdater) {
 			super(explicitViewerUpdater);
 		}
@@ -50,21 +50,21 @@
 		}
 
 		protected void addCollectionChangeListener(
-				IObservableCollection collection) {
-			((IObservableSet) collection).addSetChangeListener(this);
+				IObservableCollection<?> collection) {
+			((IObservableSet<?>) collection).addSetChangeListener(this);
 		}
 
 		protected void removeCollectionChangeListener(
-				IObservableCollection collection) {
-			((IObservableSet) collection).removeSetChangeListener(this);
+				IObservableCollection<?> collection) {
+			((IObservableSet<?>) collection).removeSetChangeListener(this);
 		}
 
-		public void handleSetChange(SetChangeEvent event) {
+		public void handleSetChange(SetChangeEvent<Object> event) {
 			if (isViewerDisposed())
 				return;
 
-			Set removals = event.diff.getRemovals();
-			Set additions = event.diff.getAdditions();
+			Set<Object> removals = event.diff.getRemovals();
+			Set<Object> additions = event.diff.getAdditions();
 
 			knownElements.addAll(additions);
 			if (realizedElements != null)
@@ -133,7 +133,7 @@
 	 * 
 	 * @return unmodifiable set of items that will need labels
 	 */
-	public IObservableSet getKnownElements() {
+	public IObservableSet<Object> getKnownElements() {
 		return impl.getKnownElements();
 	}
 
@@ -145,7 +145,7 @@
 	 * @return the set of known elements which have been realized in the viewer.
 	 * @since 1.3
 	 */
-	public IObservableSet getRealizedElements() {
+	public IObservableSet<Object> getRealizedElements() {
 		return impl.getRealizedElements();
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableSetTreeContentProvider.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableSetTreeContentProvider.java
index 2ca876c..c02430e 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableSetTreeContentProvider.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableSetTreeContentProvider.java
@@ -41,32 +41,32 @@
 	private final ObservableCollectionTreeContentProvider impl;
 
 	private static class Impl extends ObservableCollectionTreeContentProvider {
-		Impl(IObservableFactory setFactory,
+		Impl(IObservableFactory<Object, IObservableSet<Object>> setFactory,
 				TreeStructureAdvisor structureAdvisor) {
 			super(setFactory, structureAdvisor);
 		}
 
-		private class SetChangeListener implements ISetChangeListener {
+		private class SetChangeListener implements ISetChangeListener<Object> {
 			final Object parentElement;
 
 			public SetChangeListener(Object parentElement) {
 				this.parentElement = parentElement;
 			}
 
-			public void handleSetChange(SetChangeEvent event) {
+			public void handleSetChange(SetChangeEvent<Object> event) {
 				if (isViewerDisposed())
 					return;
 
-				Set localAdditions = event.diff.getAdditions();
-				Set localRemovals = event.diff.getRemovals();
+				Set<Object> localAdditions = event.diff.getAdditions();
+				Set<Object> localRemovals = event.diff.getRemovals();
 
-				Set knownElementAdditions = ViewerElementSet
+				Set<Object> knownElementAdditions = ViewerElementSet
 						.withComparer(comparer);
 				knownElementAdditions.addAll(localAdditions);
 				knownElementAdditions.removeAll(knownElements);
 
-				Set knownElementRemovals = findPendingRemovals(parentElement,
-						localRemovals);
+				Set<Object> knownElementRemovals = findPendingRemovals(
+						parentElement, localRemovals);
 				knownElementRemovals.retainAll(knownElements);
 
 				knownElements.addAll(knownElementAdditions);
@@ -74,7 +74,7 @@
 					realizedElements.removeAll(knownElementRemovals);
 				}
 
-				for (Iterator iterator = localAdditions.iterator(); iterator
+				for (Iterator<Object> iterator = localAdditions.iterator(); iterator
 						.hasNext();) {
 					Object child = iterator.next();
 					getOrCreateNode(child).addParent(parentElement);
@@ -83,7 +83,7 @@
 				viewerUpdater.add(parentElement, localAdditions.toArray());
 				viewerUpdater.remove(parentElement, localRemovals.toArray());
 
-				for (Iterator iterator = localRemovals.iterator(); iterator
+				for (Iterator<Object> iterator = localRemovals.iterator(); iterator
 						.hasNext();) {
 					Object child = iterator.next();
 					TreeNode childNode = getExistingNode(child);
@@ -104,16 +104,17 @@
 		}
 
 		protected void addCollectionChangeListener(
-				IObservableCollection collection, IObservablesListener listener) {
-			IObservableSet set = (IObservableSet) collection;
-			ISetChangeListener setListener = (ISetChangeListener) listener;
+				IObservableCollection<Object> collection,
+				IObservablesListener listener) {
+			IObservableSet<Object> set = (IObservableSet<Object>) collection;
+			ISetChangeListener<Object> setListener = (ISetChangeListener<Object>) listener;
 			set.addSetChangeListener(setListener);
 		}
 
 		protected void removeCollectionChangeListener(
-				IObservableCollection collection, IObservablesListener listener) {
-			IObservableSet set = (IObservableSet) collection;
-			ISetChangeListener setListener = (ISetChangeListener) listener;
+				IObservableCollection<Object> collection, IObservablesListener listener) {
+			IObservableSet<Object> set = (IObservableSet<Object>) collection;
+			ISetChangeListener<Object> setListener = (ISetChangeListener) listener;
 			set.removeSetChangeListener(setListener);
 		}
 	}
@@ -134,7 +135,7 @@
 	 *            non-null advisor if they can provide additional structural
 	 *            information about the tree.
 	 */
-	public ObservableSetTreeContentProvider(IObservableFactory setFactory,
+	public ObservableSetTreeContentProvider(IObservableFactory<Object, IObservableSet<Object>> setFactory,
 			TreeStructureAdvisor structureAdvisor) {
 		impl = new Impl(setFactory, structureAdvisor);
 	}
@@ -184,7 +185,7 @@
 	 * 
 	 * @return readableSet of items that will need labels
 	 */
-	public IObservableSet getKnownElements() {
+	public IObservableSet<Object> getKnownElements() {
 		return impl.getKnownElements();
 	}
 
@@ -196,7 +197,7 @@
 	 * @return the set of known elements which have been realized in the viewer.
 	 * @since 1.3
 	 */
-	public IObservableSet getRealizedElements() {
+	public IObservableSet<Object> getRealizedElements() {
 		return impl.getRealizedElements();
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableValueEditingSupport.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableValueEditingSupport.java
index 020fbec..a346524 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableValueEditingSupport.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ObservableValueEditingSupport.java
@@ -32,9 +32,13 @@
  * {@link EditingSupport} using the JFace Data Binding concepts to handle the
  * updating of an element from a {@link CellEditor}.
  * 
+ * @param <M>
+ * @param <T>
+ * 
  * @since 1.2
  */
-public abstract class ObservableValueEditingSupport extends EditingSupport {
+public abstract class ObservableValueEditingSupport<M, T> extends
+		EditingSupport {
 	/**
 	 * Returns an ObservableValueEditingSupport instance which binds the given
 	 * cell editor property to the given element property.
@@ -54,17 +58,17 @@
 	 *         arguments.
 	 * @since 1.3
 	 */
-	public static EditingSupport create(ColumnViewer viewer,
+	public static <M, T> EditingSupport create(ColumnViewer viewer,
 			DataBindingContext dbc, final CellEditor cellEditor,
-			final IValueProperty cellEditorProperty,
-			final IValueProperty elementProperty) {
-		return new ObservableValueEditingSupport(viewer, dbc) {
-			protected IObservableValue doCreateCellEditorObservable(
+			final IValueProperty<CellEditor, T> cellEditorProperty,
+			final IValueProperty<Object, M> elementProperty) {
+		return new ObservableValueEditingSupport<M, T>(viewer, dbc) {
+			protected IObservableValue<T> doCreateCellEditorObservable(
 					CellEditor cellEditor) {
 				return cellEditorProperty.observe(cellEditor);
 			}
 
-			protected IObservableValue doCreateElementObservable(
+			protected IObservableValue<M> doCreateElementObservable(
 					Object element, ViewerCell cell) {
 				return elementProperty.observe(element);
 			}
@@ -79,7 +83,7 @@
 	 * Maintains references to the instances currently imployed while editing.
 	 * Will be <code>null</code> when not editing.
 	 */
-	private EditingState editingState;
+	private EditingState<M, T> editingState;
 
 	private final ColumnViewerEditorActivationListenerHelper activationListener = new ColumnViewerEditorActivationListenerHelper();
 
@@ -147,18 +151,18 @@
 	 */
 	final protected void initializeCellEditorValue(CellEditor cellEditor,
 			ViewerCell cell) {
-		IObservableValue target = doCreateCellEditorObservable(cellEditor);
+		IObservableValue<T> target = doCreateCellEditorObservable(cellEditor);
 		Assert.isNotNull(target,
 				"doCreateCellEditorObservable(...) did not return an observable"); //$NON-NLS-1$
 
-		IObservableValue model = doCreateElementObservable(cell.getElement(),
-				cell);
+		IObservableValue<M> model = doCreateElementObservable(
+				cell.getElement(), cell);
 		Assert.isNotNull(model,
 				"doCreateElementObservable(...) did not return an observable"); //$NON-NLS-1$
 
 		dirty = false;
 
-		Binding binding = createBinding(target, model);
+		Binding<?, ?> binding = createBinding(target, model);
 
 		target.addChangeListener(new IChangeListener() {
 			public void handleChange(ChangeEvent event) {
@@ -168,7 +172,7 @@
 
 		Assert.isNotNull(binding, "createBinding(...) did not return a binding"); //$NON-NLS-1$
 
-		editingState = new EditingState(binding, target, model);
+		editingState = new EditingState<M, T>(binding, target, model);
 
 		getViewer().getColumnViewerEditor().addEditorActivationListener(
 				activationListener);
@@ -180,7 +184,7 @@
 	 * @param cellEditor
 	 * @return observable value
 	 */
-	protected abstract IObservableValue doCreateCellEditorObservable(
+	protected abstract IObservableValue<T> doCreateCellEditorObservable(
 			CellEditor cellEditor);
 
 	/**
@@ -190,7 +194,7 @@
 	 * @param cell
 	 * @return observable value
 	 */
-	protected abstract IObservableValue doCreateElementObservable(
+	protected abstract IObservableValue<M> doCreateElementObservable(
 			Object element, ViewerCell cell);
 
 	/**
@@ -203,9 +207,9 @@
 	 * @param model
 	 * @return binding
 	 */
-	protected Binding createBinding(IObservableValue target,
-			IObservableValue model) {
-		return dbc.bindValue(target, model, new UpdateValueStrategy(
+	protected Binding<?, ?> createBinding(IObservableValue<T> target,
+			IObservableValue<M> model) {
+		return dbc.bindValue(target, model, new UpdateValueStrategy<T, M>(
 				UpdateValueStrategy.POLICY_CONVERT), null);
 	}
 
@@ -252,15 +256,15 @@
 	 * Maintains references to objects that only live for the length of the edit
 	 * cycle.
 	 */
-	private static class EditingState {
-		IObservableValue target;
+	private static class EditingState<M, T> {
+		IObservableValue<T> target;
 
-		IObservableValue model;
+		IObservableValue<M> model;
 
-		Binding binding;
+		Binding<?, ?> binding;
 
-		EditingState(Binding binding, IObservableValue target,
-				IObservableValue model) {
+		EditingState(Binding<?, ?> binding, IObservableValue<T> target,
+				IObservableValue<M> model) {
 			this.binding = binding;
 			this.target = target;
 			this.model = model;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/SelectionProviderProperties.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/SelectionProviderProperties.java
new file mode 100644
index 0000000..da5f8c5
--- /dev/null
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/SelectionProviderProperties.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jface.databinding.viewers;
+
+import org.eclipse.core.databinding.property.list.IListProperty;
+import org.eclipse.core.databinding.property.value.IValueProperty;
+import org.eclipse.jface.internal.databinding.viewers.SelectionProviderMultipleSelectionProperty;
+import org.eclipse.jface.internal.databinding.viewers.SelectionProviderSingleSelectionProperty;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelectionProvider;
+
+/**
+ * @since 1.7
+ * 
+ */
+public class SelectionProviderProperties {
+
+	/**
+	 * Returns a list property for observing the multiple selection of an
+	 * {@link ISelectionProvider}.
+	 * 
+	 * @return a list property for observing the multiple selection of an
+	 *         {@link ISelectionProvider}.
+	 * @since 1.7
+	 */
+	public static IListProperty<ISelectionProvider, Object> multipleSelection() {
+		return new SelectionProviderMultipleSelectionProperty<ISelectionProvider>(
+				false);
+	}
+
+	/**
+	 * Returns a list property for observing the multiple <i>post</i> selection
+	 * of an {@link IPostSelectionProvider}.
+	 * 
+	 * @return a list property for observing the multiple <i>post</i> selection
+	 *         of an {@link IPostSelectionProvider}.
+	 * 
+	 * @since 1.7
+	 */
+	public static IListProperty<ISelectionProvider, Object> multiplePostSelection() {
+		return new SelectionProviderMultipleSelectionProperty<ISelectionProvider>(
+				true);
+	}
+
+	/**
+	 * Returns a value property for observing the single selection of a
+	 * {@link ISelectionProvider}.
+	 * 
+	 * @return a value property for observing the single selection of a
+	 *         {@link ISelectionProvider}.
+	 * @since 1.7
+	 */
+	public static IValueProperty<ISelectionProvider, Object> singleSelection() {
+		return new SelectionProviderSingleSelectionProperty<ISelectionProvider>(
+				false);
+	}
+
+	/**
+	 * Returns a value property for observing the single selection of a
+	 * {@link IPostSelectionProvider}.
+	 * 
+	 * @return a value property for observing the single selection of a
+	 *         {@link IPostSelectionProvider}.
+	 * @since 1.7
+	 */
+	public static IValueProperty<ISelectionProvider, Object> singlePostSelection() {
+		return new SelectionProviderSingleSelectionProperty<ISelectionProvider>(
+				true);
+	}
+
+}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerListProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerListProperty.java
index 216c404..b264274 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerListProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerListProperty.java
@@ -30,27 +30,23 @@
  * {@link IViewerObservableList}
  * </ul>
  * 
+ * @param <S>
+ * 
  * @since 1.3
  */
-public abstract class ViewerListProperty extends SimpleListProperty implements
-		IViewerListProperty {
-	public IObservableList observe(Object source) {
-		if (source instanceof Viewer) {
-			return observe((Viewer) source);
-		}
-		return super.observe(source);
+public abstract class ViewerListProperty<S extends Viewer> extends
+		SimpleListProperty<S, Object> implements IViewerListProperty<S> {
+	/**
+	 * @since 1.7
+	 */
+	public IViewerObservableList<S> observe(Realm realm, S source) {
+		IObservableList<Object> observable = super.observe(realm, source);
+		return new ViewerObservableListDecorator<S>(observable, source);
 	}
 
-	public IObservableList observe(Realm realm, Object source) {
-		IObservableList observable = super.observe(realm, source);
-		if (source instanceof Viewer)
-			observable = new ViewerObservableListDecorator(observable,
-					(Viewer) source);
-		return observable;
-	}
-
-	public IViewerObservableList observe(Viewer viewer) {
-		return (IViewerObservableList) observe(SWTObservables.getRealm(viewer
-				.getControl().getDisplay()), viewer);
+	public IViewerObservableList<S> observe(S viewer) {
+		return observe(
+				SWTObservables.getRealm(viewer.getControl().getDisplay()),
+				viewer);
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerProperties.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerProperties.java
index 398a72d..65d1009 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerProperties.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerProperties.java
@@ -13,11 +13,14 @@
 
 package org.eclipse.jface.databinding.viewers;
 
-import org.eclipse.jface.internal.databinding.viewers.SelectionProviderMultipleSelectionProperty;
-import org.eclipse.jface.internal.databinding.viewers.SelectionProviderSingleSelectionProperty;
+import org.eclipse.core.databinding.property.set.ISetProperty;
+import org.eclipse.jface.internal.databinding.viewers.CheckableCheckedElementsProperty;
+import org.eclipse.jface.internal.databinding.viewers.CheckboxTableViewerCheckedElementsProperty;
+import org.eclipse.jface.internal.databinding.viewers.CheckboxTreeViewerCheckedElementsProperty;
 import org.eclipse.jface.internal.databinding.viewers.StructuredViewerFiltersProperty;
-import org.eclipse.jface.internal.databinding.viewers.ViewerCheckedElementsProperty;
 import org.eclipse.jface.internal.databinding.viewers.ViewerInputProperty;
+import org.eclipse.jface.internal.databinding.viewers.ViewerMultipleSelectionProperty;
+import org.eclipse.jface.internal.databinding.viewers.ViewerSingleSelectionProperty;
 import org.eclipse.jface.viewers.CheckboxTableViewer;
 import org.eclipse.jface.viewers.CheckboxTreeViewer;
 import org.eclipse.jface.viewers.ICheckable;
@@ -25,6 +28,7 @@
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.StructuredViewer;
 import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
 
 /**
  * A factory for creating properties of JFace {@link Viewer viewers}.
@@ -40,12 +44,65 @@
 	 * @param elementType
 	 *            the element type of the returned property
 	 * 
-	 * @return a set property for observing the checked elements of a
-	 *         {@link CheckboxTableViewer}, {@link CheckboxTreeViewer} or
-	 *         {@link ICheckable}.
+	 * @return a set property for observing the checked elements of an
+	 *         {@link ICheckable}, for example {@link CheckboxTableViewer} or
+	 *         {@link CheckboxTreeViewer}.
+	 * @deprecated use one of checkableElements, checkboxTableElements,
+	 *             checkboxTreeElements
 	 */
+	@SuppressWarnings("rawtypes")
+	// ok to ignore warnings on deprecated method
 	public static IViewerSetProperty checkedElements(Object elementType) {
-		return new ViewerCheckedElementsProperty(elementType);
+		return new org.eclipse.jface.internal.databinding.viewers.ViewerCheckedElementsProperty(
+				elementType);
+	}
+
+	/**
+	 * Returns a set property for observing the checked elements of a
+	 * {@link CheckboxTableViewer}.
+	 * 
+	 * @param elementType
+	 *            the element type of the returned property
+	 * 
+	 * @return a set property for observing the checked elements of an
+	 *         {@link CheckboxTableViewer}
+	 * @since 1.7
+	 */
+	public static IViewerSetProperty<CheckboxTableViewer, Object> checkboxTableElements(
+			Object elementType) {
+		return new CheckboxTableViewerCheckedElementsProperty(elementType);
+	}
+
+	/**
+	 * Returns a set property for observing the checked elements of a
+	 * {@link CheckboxTreeViewer}.
+	 * 
+	 * @param elementType
+	 *            the element type of the returned property
+	 * 
+	 * @return a set property for observing the checked elements of a
+	 *         {@link CheckboxTreeViewer}.
+	 * @since 1.7
+	 */
+	public static IViewerSetProperty<CheckboxTreeViewer, Object> checkboxTreeElements(
+			Object elementType) {
+		return new CheckboxTreeViewerCheckedElementsProperty(elementType);
+	}
+
+	/**
+	 * Returns a set property for observing the checked elements of a
+	 * {@link ICheckable}.
+	 * 
+	 * @param elementType
+	 *            the element type of the returned property
+	 * 
+	 * @return a set property for observing the checked elements of an
+	 *         {@link ICheckable}
+	 * @since 1.7
+	 */
+	public static ISetProperty<ICheckable, Object> checkableElements(
+			Object elementType) {
+		return new CheckableCheckedElementsProperty(elementType);
 	}
 
 	/**
@@ -55,7 +112,7 @@
 	 * @return a value property for observing the input of a
 	 *         {@link StructuredViewer}.
 	 */
-	public static IViewerSetProperty filters() {
+	public static IViewerSetProperty<StructuredViewer, ViewerFilter> filters() {
 		return new StructuredViewerFiltersProperty();
 	}
 
@@ -64,43 +121,20 @@
 	 * 
 	 * @return a value property for observing the input of a {@link Viewer}.
 	 */
-	public static IViewerValueProperty input() {
+	public static IViewerValueProperty<Viewer> input() {
 		return new ViewerInputProperty();
 	}
 
 	/**
-	 * Returns a list property for observing the multiple selection of an
-	 * {@link ISelectionProvider}.
-	 * 
-	 * @return a list property for observing the multiple selection of an
-	 *         {@link ISelectionProvider}.
-	 */
-	public static IViewerListProperty multipleSelection() {
-		return new SelectionProviderMultipleSelectionProperty(false);
-	}
-
-	/**
-	 * Returns a list property for observing the multiple <i>post</i> selection
-	 * of an {@link IPostSelectionProvider}.
-	 * 
-	 * @return a list property for observing the multiple <i>post</i> selection
-	 *         of an {@link IPostSelectionProvider}.
-	 * 
-	 * @since 1.4
-	 */
-	public static IViewerListProperty multiplePostSelection() {
-		return new SelectionProviderMultipleSelectionProperty(true);
-	}
-
-	/**
 	 * Returns a value property for observing the single selection of a
 	 * {@link ISelectionProvider}.
 	 * 
 	 * @return a value property for observing the single selection of a
 	 *         {@link ISelectionProvider}.
+	 * @since 1.7
 	 */
-	public static IViewerValueProperty singleSelection() {
-		return new SelectionProviderSingleSelectionProperty(false);
+	public static IViewerListProperty<Viewer> multipleSelection() {
+		return new ViewerMultipleSelectionProperty<Viewer>(false);
 	}
 
 	/**
@@ -110,9 +144,34 @@
 	 * @return a value property for observing the single <i>post</i> selection
 	 *         of a {@link IPostSelectionProvider}.
 	 * 
-	 * @since 1.4
+	 * @since 1.7
 	 */
-	public static IViewerValueProperty singlePostSelection() {
-		return new SelectionProviderSingleSelectionProperty(true);
+	public static IViewerListProperty<Viewer> multiplePostSelection() {
+		return new ViewerMultipleSelectionProperty<Viewer>(true);
+	}
+
+	/**
+	 * Returns a value property for observing the single selection of a
+	 * {@link ISelectionProvider}.
+	 * 
+	 * @return a value property for observing the single selection of a
+	 *         {@link ISelectionProvider}.
+	 * @since 1.7
+	 */
+	public static IViewerValueProperty<Viewer> singleSelection() {
+		return new ViewerSingleSelectionProperty<Viewer>(false);
+	}
+
+	/**
+	 * Returns a value property for observing the single <i>post</i> selection
+	 * of a {@link IPostSelectionProvider}.
+	 * 
+	 * @return a value property for observing the single <i>post</i> selection
+	 *         of a {@link IPostSelectionProvider}.
+	 * 
+	 * @since 1.7
+	 */
+	public static IViewerValueProperty<Viewer> singlePostSelection() {
+		return new ViewerSingleSelectionProperty<Viewer>(true);
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerSetProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerSetProperty.java
index c191c40..d3440da 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerSetProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerSetProperty.java
@@ -30,26 +30,24 @@
  * {@link IViewerObservableSet}
  * </ul>
  * 
+ * @param <S>
+ * @param <E>
+ * 
  * @since 1.3
  */
-public abstract class ViewerSetProperty extends SimpleSetProperty implements
-		IViewerSetProperty {
-	public IObservableSet observe(Object source) {
-		if (source instanceof Viewer) {
-			return observe((Viewer) source);
-		}
-		return super.observe(source);
+public abstract class ViewerSetProperty<S extends Viewer, E> extends
+		SimpleSetProperty<S, E> implements IViewerSetProperty<S, E> {
+
+	/**
+	 * @since 1.7
+	 */
+	public IViewerObservableSet<S, E> observe(Realm realm, S viewer) {
+		IObservableSet<E> observable = super.observe(realm, viewer);
+		return new ViewerObservableSetDecorator<S, E>(observable, viewer);
 	}
 
-	public IObservableSet observe(Realm realm, Object source) {
-		IObservableSet observable = super.observe(realm, source);
-		if (source instanceof Viewer)
-			return new ViewerObservableSetDecorator(observable, (Viewer) source);
-		return observable;
-	}
-
-	public IViewerObservableSet observe(Viewer viewer) {
-		return (IViewerObservableSet) observe(SWTObservables.getRealm(viewer
-				.getControl().getDisplay()), viewer);
+	public IViewerObservableSet<S, E> observe(S viewer) {
+		return observe(SWTObservables.getRealm(((Viewer) viewer).getControl()
+				.getDisplay()), viewer);
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerValueProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerValueProperty.java
index 7a800c7..4e4a8bd 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerValueProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewerValueProperty.java
@@ -30,31 +30,27 @@
  * {@link IViewerObservableValue}
  * </ul>
  * 
+ * @param <S>
+ * 
  * @since 1.3
  */
-public abstract class ViewerValueProperty extends SimpleValueProperty implements
-		IViewerValueProperty {
-	public IObservableValue observe(Object source) {
-		if (source instanceof Viewer) {
-			return observe((Viewer) source);
-		}
-		return super.observe(source);
+public abstract class ViewerValueProperty<S extends Viewer> extends
+		SimpleValueProperty<S, Object> implements IViewerValueProperty<S> {
+	/**
+	 * @since 1.7
+	 */
+	public IViewerObservableValue<S> observe(Realm realm, S source) {
+		IObservableValue<Object> observable = super.observe(realm, source);
+		return new ViewerObservableValueDecorator<S>(observable, source);
 	}
 
-	public IObservableValue observe(Realm realm, Object source) {
-		IObservableValue observable = super.observe(realm, source);
-		if (source instanceof Viewer)
-			observable = new ViewerObservableValueDecorator(observable,
-					(Viewer) source);
-		return observable;
+	public IViewerObservableValue<S> observe(S viewer) {
+		return observe(
+				SWTObservables.getRealm(viewer.getControl().getDisplay()),
+				viewer);
 	}
 
-	public IViewerObservableValue observe(Viewer viewer) {
-		return (IViewerObservableValue) observe(SWTObservables.getRealm(viewer
-				.getControl().getDisplay()), viewer);
-	}
-
-	public IViewerObservableValue observeDelayed(int delay, Viewer viewer) {
+	public IViewerObservableValue<S> observeDelayed(int delay, S viewer) {
 		return ViewersObservables.observeDelayedValue(delay, observe(viewer));
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewersObservables.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewersObservables.java
index 0f36401..27eed58 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewersObservables.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/viewers/ViewersObservables.java
@@ -18,6 +18,7 @@
 import org.eclipse.core.databinding.observable.list.IObservableList;
 import org.eclipse.core.databinding.observable.set.IObservableSet;
 import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.internal.databinding.viewers.ViewerMultipleSelectionProperty;
 import org.eclipse.jface.internal.databinding.viewers.ViewerObservableValueDecorator;
 import org.eclipse.jface.viewers.CheckboxTableViewer;
 import org.eclipse.jface.viewers.CheckboxTreeViewer;
@@ -27,6 +28,7 @@
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredViewer;
 import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
 
 /**
  * Factory methods for creating observables for JFace viewers
@@ -60,10 +62,11 @@
 	 * 
 	 * @since 1.3
 	 */
-	public static IViewerObservableValue observeDelayedValue(int delay,
-			IViewerObservableValue observable) {
-		return new ViewerObservableValueDecorator(Observables
-				.observeDelayedValue(delay, observable), observable.getViewer());
+	public static <S extends Viewer> IViewerObservableValue<S> observeDelayedValue(
+			int delay, IViewerObservableValue<S> observable) {
+		return new ViewerObservableValueDecorator<S>(
+				Observables.observeDelayedValue(delay, observable),
+				observable.getViewer());
 	}
 
 	/**
@@ -77,10 +80,11 @@
 	 * @return the observable value tracking the (single) selection of the given
 	 *         selection provider
 	 */
-	public static IObservableValue observeSingleSelection(
+	public static IObservableValue<Object> observeSingleSelection(
 			ISelectionProvider selectionProvider) {
 		checkNull(selectionProvider);
-		return ViewerProperties.singleSelection().observe(selectionProvider);
+		return SelectionProviderProperties.singleSelection().observe(
+				selectionProvider);
 	}
 
 	/**
@@ -98,11 +102,11 @@
 	 * 
 	 * @since 1.4
 	 */
-	public static IObservableValue observeSinglePostSelection(
+	public static IObservableValue<Object> observeSinglePostSelection(
 			IPostSelectionProvider selectionProvider) {
 		checkNull(selectionProvider);
-		return ViewerProperties.singlePostSelection()
-				.observe(selectionProvider);
+		return SelectionProviderProperties.singlePostSelection().observe(
+				selectionProvider);
 	}
 
 	/**
@@ -123,10 +127,11 @@
 	 * 
 	 * @since 1.2
 	 */
-	public static IObservableList observeMultiSelection(
+	public static IObservableList<Object> observeMultiSelection(
 			ISelectionProvider selectionProvider) {
 		checkNull(selectionProvider);
-		return ViewerProperties.multipleSelection().observe(selectionProvider);
+		return SelectionProviderProperties.multipleSelection().observe(
+				selectionProvider);
 	}
 
 	/**
@@ -149,10 +154,10 @@
 	 * 
 	 * @since 1.4
 	 */
-	public static IObservableList observeMultiPostSelection(
+	public static IObservableList<Object> observeMultiPostSelection(
 			IPostSelectionProvider selectionProvider) {
 		checkNull(selectionProvider);
-		return ViewerProperties.multiplePostSelection().observe(
+		return SelectionProviderProperties.multiplePostSelection().observe(
 				selectionProvider);
 	}
 
@@ -169,7 +174,8 @@
 	 *         viewer
 	 * @since 1.2
 	 */
-	public static IViewerObservableValue observeSingleSelection(Viewer viewer) {
+	public static IViewerObservableValue<Viewer> observeSingleSelection(
+			Viewer viewer) {
 		checkNull(viewer);
 		return ViewerProperties.singleSelection().observe(viewer);
 	}
@@ -188,7 +194,7 @@
 	 * 
 	 * @since 1.4
 	 */
-	public static IViewerObservableValue observeSinglePostSelection(
+	public static IViewerObservableValue<Viewer> observeSinglePostSelection(
 			StructuredViewer viewer) {
 		checkNull(viewer);
 		return ViewerProperties.singlePostSelection().observe(viewer);
@@ -211,9 +217,10 @@
 	 * 
 	 * @since 1.2
 	 */
-	public static IViewerObservableList observeMultiSelection(Viewer viewer) {
+	public static <S extends Viewer> IViewerObservableList<S> observeMultiSelection(
+			S viewer) {
 		checkNull(viewer);
-		return ViewerProperties.multipleSelection().observe(viewer);
+		return new ViewerMultipleSelectionProperty<S>(false).observe(viewer);
 	}
 
 	/**
@@ -234,10 +241,10 @@
 	 * 
 	 * @since 1.4
 	 */
-	public static IViewerObservableList observeMultiPostSelection(
-			StructuredViewer viewer) {
+	public static <S extends StructuredViewer> IViewerObservableList<S> observeMultiPostSelection(
+			S viewer) {
 		checkNull(viewer);
-		return ViewerProperties.multiplePostSelection().observe(viewer);
+		return new ViewerMultipleSelectionProperty<S>(true).observe(viewer);
 	}
 
 	/**
@@ -251,7 +258,7 @@
 	 * @return an observable value tracking the input of the given viewer
 	 * @since 1.2
 	 */
-	public static IObservableValue observeInput(Viewer viewer) {
+	public static IObservableValue<Object> observeInput(Viewer viewer) {
 		checkNull(viewer);
 		return ViewerProperties.input().observe(viewer);
 	}
@@ -268,8 +275,8 @@
 	 *         checkable.
 	 * @since 1.2
 	 */
-	public static IObservableSet observeCheckedElements(ICheckable checkable,
-			Object elementType) {
+	public static IObservableSet<Object> observeCheckedElements(
+			ICheckable checkable, Object elementType) {
 		checkNull(checkable);
 		return ViewerProperties.checkedElements(elementType).observe(checkable);
 	}
@@ -287,10 +294,11 @@
 	 *         viewer.
 	 * @since 1.2
 	 */
-	public static IViewerObservableSet observeCheckedElements(
+	public static IViewerObservableSet<CheckboxTableViewer, Object> observeCheckedElements(
 			CheckboxTableViewer viewer, Object elementType) {
 		checkNull(viewer);
-		return ViewerProperties.checkedElements(elementType).observe(viewer);
+		return ViewerProperties.checkboxTableElements(elementType).observe(
+				viewer);
 	}
 
 	/**
@@ -306,10 +314,11 @@
 	 *         viewer.
 	 * @since 1.2
 	 */
-	public static IViewerObservableSet observeCheckedElements(
+	public static IViewerObservableSet<CheckboxTreeViewer, Object> observeCheckedElements(
 			CheckboxTreeViewer viewer, Object elementType) {
 		checkNull(viewer);
-		return ViewerProperties.checkedElements(elementType).observe(viewer);
+		return ViewerProperties.checkboxTreeElements(elementType).observe(
+				viewer);
 	}
 
 	/**
@@ -329,7 +338,8 @@
 	 * @return an observable set that tracks the filters of the given viewer.
 	 * @since 1.3
 	 */
-	public static IViewerObservableSet observeFilters(StructuredViewer viewer) {
+	public static IViewerObservableSet<StructuredViewer, ViewerFilter> observeFilters(
+			StructuredViewer viewer) {
 		checkNull(viewer);
 		return ViewerProperties.filters().observe(viewer);
 	}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/CompositeUpdater.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/CompositeUpdater.java
index 8ccf7f5..e73068d 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/CompositeUpdater.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/CompositeUpdater.java
@@ -13,6 +13,7 @@
 
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 
 import org.eclipse.core.databinding.observable.ChangeEvent;
@@ -100,7 +101,7 @@
 
 	private class LayoutRunnable implements Runnable {
 		private boolean posted = false;
-		private Set controlsToLayout = new HashSet();
+		private Set<Control> controlsToLayout = new HashSet<Control>();
 
 		void add(Control toLayout) {
 			controlsToLayout.add(toLayout);
@@ -113,8 +114,8 @@
 		public void run() {
 			posted = false;
 			theComposite.getShell().layout(
-					(Control[]) controlsToLayout
-							.toArray(new Control[controlsToLayout.size()]));
+					controlsToLayout.toArray(new Control[controlsToLayout
+							.size()]));
 			controlsToLayout.clear();
 		}
 	}
@@ -134,20 +135,20 @@
 	}
 
 	private class PrivateInterface implements DisposeListener,
-			IListChangeListener {
+			IListChangeListener<Object> {
 
 		// DisposeListener implementation
 		public void widgetDisposed(DisposeEvent e) {
 			CompositeUpdater.this.dispose();
 		}
 
-		public void handleListChange(ListChangeEvent event) {
-			ListDiffEntry[] diffs = event.diff.getDifferences();
-			for (int i = 0; i < diffs.length; i++) {
-				ListDiffEntry listDiffEntry = diffs[i];
+		public void handleListChange(ListChangeEvent<Object> event) {
+			List<ListDiffEntry<Object>> diffs = event.diff
+					.getDifferencesAsList();
+			for (ListDiffEntry<Object> listDiffEntry : diffs) {
 				if (listDiffEntry.isAddition()) {
-					createChild(listDiffEntry.getElement(), listDiffEntry
-							.getPosition());
+					createChild(listDiffEntry.getElement(),
+							listDiffEntry.getPosition());
 				} else {
 					disposeWidget(listDiffEntry.getPosition());
 				}
@@ -161,7 +162,7 @@
 
 	private Composite theComposite;
 
-	private IObservableList model;
+	private IObservableList<Object> model;
 
 	/**
 	 * Creates an updater for the given control and list. For each element of
@@ -173,7 +174,7 @@
 	 * @param model
 	 *            an observable list to track
 	 */
-	public CompositeUpdater(Composite toUpdate, IObservableList model) {
+	public CompositeUpdater(Composite toUpdate, IObservableList<Object> model) {
 		this.theComposite = toUpdate;
 		this.model = model;
 
@@ -182,7 +183,7 @@
 		ObservableTracker.setIgnore(true);
 		try {
 			int index = 0;
-			for (Iterator it = CompositeUpdater.this.model.iterator(); it
+			for (Iterator<Object> it = CompositeUpdater.this.model.iterator(); it
 					.hasNext();) {
 				Object element = it.next();
 				createChild(element, index++);
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/TableUpdater.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/TableUpdater.java
index 8570a3c..bac8198 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/TableUpdater.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/TableUpdater.java
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.jface.internal.databinding.provisional.swt;
 
+import java.util.List;
+
 import org.eclipse.core.databinding.observable.ChangeEvent;
 import org.eclipse.core.databinding.observable.IChangeListener;
 import org.eclipse.core.databinding.observable.IObservable;
@@ -126,7 +128,8 @@
 			if (e.type == SWT.SetData) {
 				UpdateRunnable runnable = (UpdateRunnable) e.item.getData();
 				if (runnable == null) {
-					runnable = new UpdateRunnable((TableItem) e.item, list.get(e.index));
+					runnable = new UpdateRunnable((TableItem) e.item,
+							list.get(e.index));
 					e.item.setData(runnable);
 					runnable.makeDirty();
 				} else {
@@ -146,15 +149,16 @@
 
 	private Table table;
 
-	private IListChangeListener listChangeListener = new IListChangeListener() {
-		public void handleListChange(ListChangeEvent event) {
-			ListDiffEntry[] differences = event.diff.getDifferences();
-			for (int i = 0; i < differences.length; i++) {
-				ListDiffEntry entry = differences[i];
+	private IListChangeListener<Object> listChangeListener = new IListChangeListener<Object>() {
+		public void handleListChange(ListChangeEvent<Object> event) {
+			List<ListDiffEntry<Object>> differences = event.diff
+					.getDifferencesAsList();
+			for (ListDiffEntry<Object> entry : differences) {
 				if (entry.isAddition()) {
-					TableItem item = new TableItem(table, SWT.NONE, entry
-							.getPosition());
-					UpdateRunnable updateRunnable = new UpdateRunnable(item, entry.getElement());
+					TableItem item = new TableItem(table, SWT.NONE,
+							entry.getPosition());
+					UpdateRunnable updateRunnable = new UpdateRunnable(item,
+							entry.getElement());
 					item.setData(updateRunnable);
 					updateRunnable.makeDirty();
 				} else {
@@ -164,17 +168,18 @@
 		}
 	};
 
-	private IObservableList list;
+	private IObservableList<IListChangeListener<Object>> list;
 
 	/**
-	 * Creates an updator for the given control.
+	 * Creates an updater for the given control.
 	 * 
 	 * @param table
 	 *            table to update
 	 * @param list
 	 * @since 1.2
 	 */
-	public TableUpdater(Table table, IObservableList list) {
+	public TableUpdater(Table table,
+			IObservableList<IListChangeListener<Object>> list) {
 		this.table = table;
 		this.list = list;
 		Assert.isLegal((table.getStyle() & SWT.VIRTUAL) != 0,
@@ -189,7 +194,7 @@
 
 	/**
 	 * This is called automatically when the control is disposed. It may also be
-	 * called explicitly to remove this updator from the control. Subclasses
+	 * called explicitly to remove this updater from the control. Subclasses
 	 * will normally extend this method to detach any listeners they attached in
 	 * their constructor.
 	 */
@@ -202,7 +207,7 @@
 	}
 
 	/**
-	 * Updates the control. This method will be invoked once after the updator
+	 * Updates the control. This method will be invoked once after the updater
 	 * is created, and once before any repaint during which the control is
 	 * visible and dirty.
 	 * 
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/WorkQueue.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/WorkQueue.java
index 07d7205..d351ff5 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/WorkQueue.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/WorkQueue.java
@@ -27,11 +27,11 @@
 
 	private boolean updateScheduled = false;
 
-	private LinkedList pendingWork = new LinkedList();
+	private LinkedList<Runnable> pendingWork = new LinkedList<Runnable>();
 
 	private Display d;
 
-	private Set pendingWorkSet = new HashSet();
+	private Set<Runnable> pendingWorkSet = new HashSet<Runnable>();
 
 	private Runnable updateJob = new Runnable() {
 		public void run() {
@@ -54,7 +54,7 @@
 				if (pendingWork.isEmpty()) {
 					break;
 				}
-				next = (Runnable) pendingWork.removeFirst();
+				next = pendingWork.removeFirst();
 				pendingWorkSet.remove(next);
 			}
 
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/viewers/ViewerLabelProvider.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/viewers/ViewerLabelProvider.java
index bfc1a56..384dea7 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/viewers/ViewerLabelProvider.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/viewers/ViewerLabelProvider.java
@@ -27,13 +27,14 @@
 
 /**
  * NON-API - Generic viewer label provider.
+ * 
  * @since 1.1
- *
+ * 
  */
 public class ViewerLabelProvider implements IViewerLabelProvider,
 		ILabelProvider {
 
-	private List listeners = new ArrayList();
+	private List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>();
 
 	/**
 	 * Subclasses should override this method. They should not call the base
@@ -43,10 +44,10 @@
 		label.setText(element.toString());
 	}
 
-	protected final void fireChangeEvent(Collection changes) {
+	protected final void fireChangeEvent(Collection<?> changes) {
 		final LabelProviderChangedEvent event = new LabelProviderChangedEvent(
 				this, changes.toArray());
-		ILabelProviderListener[] listenerArray = (ILabelProviderListener[]) listeners
+		ILabelProviderListener[] listenerArray = listeners
 				.toArray(new ILabelProviderListener[listeners.size()]);
 		for (int i = 0; i < listenerArray.length; i++) {
 			ILabelProviderListener listener = listenerArray[i];
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonImageProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonImageProperty.java
index dd8aae3..5de2db9 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonImageProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonImageProperty.java
@@ -18,13 +18,13 @@
  * @since 3.3
  * 
  */
-public class ButtonImageProperty extends WidgetImageValueProperty {
-	Image doGetImageValue(Object source) {
-		return ((Button) source).getImage();
+public class ButtonImageProperty extends WidgetImageValueProperty<Button> {
+	Image doGetImageValue(Button source) {
+		return source.getImage();
 	}
 
-	void doSetImageValue(Object source, Image value) {
-		((Button) source).setImage(value);
+	void doSetImageValue(Button source, Image value) {
+		source.setImage(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonSelectionProperty.java
index cbd5811..f25d3b4 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonSelectionProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonSelectionProperty.java
@@ -18,7 +18,7 @@
  * @since 3.3
  * 
  */
-public class ButtonSelectionProperty extends WidgetBooleanValueProperty {
+public class ButtonSelectionProperty extends WidgetBooleanValueProperty<Button> {
 	/**
 	 * 
 	 */
@@ -26,12 +26,12 @@
 		super(SWT.Selection);
 	}
 
-	boolean doGetBooleanValue(Object source) {
-		return ((Button) source).getSelection();
+	boolean doGetBooleanValue(Button source) {
+		return source.getSelection();
 	}
 
-	void doSetBooleanValue(Object source, boolean value) {
-		((Button) source).setSelection(value);
+	void doSetBooleanValue(Button source, boolean value) {
+		source.setSelection(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonTextProperty.java
index 4c54be4..5fe661a 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ButtonTextProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class ButtonTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((Button) source).getText();
+public class ButtonTextProperty extends WidgetStringValueProperty<Button> {
+	protected String doGetValue(Button source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((Button) source).setText(value == null ? "" : value); //$NON-NLS-1$
+	protected void doSetValue(Button source, String value) {
+		source.setText(value == null ? "" : value); //$NON-NLS-1$
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboEditableProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboEditableProperty.java
index 401771d..44a8d2f 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboEditableProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboEditableProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class CComboEditableProperty extends WidgetBooleanValueProperty {
-	boolean doGetBooleanValue(Object source) {
-		return ((CCombo) source).getEditable();
+public class CComboEditableProperty extends WidgetBooleanValueProperty<CCombo> {
+	boolean doGetBooleanValue(CCombo source) {
+		return source.getEditable();
 	}
 
-	void doSetBooleanValue(Object source, boolean value) {
-		((CCombo) source).setEditable(value);
+	void doSetBooleanValue(CCombo source, boolean value) {
+		source.setEditable(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboItemsProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboItemsProperty.java
index 2a6de88..3909088 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboItemsProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboItemsProperty.java
@@ -21,16 +21,17 @@
  * @since 3.3
  * 
  */
-public class CComboItemsProperty extends ControlStringListProperty {
-	protected void doUpdateStringList(final Control control, ListDiff diff) {
-		diff.accept(new ListDiffVisitor() {
-			CCombo combo = (CCombo) control;
+public class CComboItemsProperty extends ControlStringListProperty<CCombo> {
+	protected void doUpdateStringList(final CCombo control,
+			ListDiff<String> diff) {
+		diff.accept(new ListDiffVisitor<String>() {
+			CCombo combo = control;
 
-			public void handleAdd(int index, Object element) {
-				combo.add((String) element, index);
+			public void handleAdd(int index, String element) {
+				combo.add(element, index);
 			}
 
-			public void handleRemove(int index, Object element) {
+			public void handleRemove(int index, String element) {
 				combo.remove(index);
 			}
 
@@ -52,9 +53,9 @@
 			// }
 			// }
 
-			public void handleReplace(int index, Object oldElement,
-					Object newElement) {
-				combo.setItem(index, (String) newElement);
+			public void handleReplace(int index, String oldElement,
+					String newElement) {
+				combo.setItem(index, newElement);
 			}
 		});
 	}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboSelectionProperty.java
index 1bb4a11..330cdac 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboSelectionProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboSelectionProperty.java
@@ -18,7 +18,7 @@
  * @since 3.3
  * 
  */
-public class CComboSelectionProperty extends WidgetStringValueProperty {
+public class CComboSelectionProperty extends WidgetStringValueProperty<CCombo> {
 	/**
 	 * 
 	 */
@@ -26,12 +26,11 @@
 		super(SWT.Modify);
 	}
 
-	String doGetStringValue(Object source) {
-		return ((CCombo) source).getText();
+	protected String doGetValue(CCombo source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		CCombo ccombo = (CCombo) source;
+	protected void doSetValue(CCombo ccombo, String value) {
 		String items[] = ccombo.getItems();
 		int index = -1;
 		if (value == null) {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboSingleSelectionIndexProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboSingleSelectionIndexProperty.java
index 168c94a..a85d5d1 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboSingleSelectionIndexProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboSingleSelectionIndexProperty.java
@@ -18,7 +18,8 @@
  * @since 3.3
  * 
  */
-public class CComboSingleSelectionIndexProperty extends SingleSelectionIndexProperty {
+public class CComboSingleSelectionIndexProperty extends
+		WidgetIntValueProperty<CCombo> {
 	/**
 	 * 
 	 */
@@ -26,15 +27,18 @@
 		super(new int[] { SWT.Selection, SWT.DefaultSelection });
 	}
 
-	int doGetIntValue(Object source) {
-		return ((CCombo) source).getSelectionIndex();
+	protected Integer doGetValue(CCombo source) {
+		// Ideally we would return null when no selection but
+		// that might break existing users so we stick with -1
+		return source.getSelectionIndex();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		if (value == -1)
-			((CCombo) source).deselectAll();
-		else
-			((CCombo) source).select(value);
+	protected void doSetValue(CCombo source, Integer value) {
+		if (value == null || value.intValue() == -1) {
+			source.deselectAll();
+		} else {
+			source.select(value);
+		}
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboTextProperty.java
index cc44515..dfc93f6 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CComboTextProperty.java
@@ -18,7 +18,7 @@
  * @since 3.3
  * 
  */
-public class CComboTextProperty extends WidgetStringValueProperty {
+public class CComboTextProperty extends WidgetStringValueProperty<CCombo> {
 	/**
 	 * 
 	 */
@@ -26,12 +26,12 @@
 		super(SWT.Modify);
 	}
 
-	String doGetStringValue(Object source) {
-		return ((CCombo) source).getText();
+	protected String doGetValue(CCombo source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((CCombo) source).setText(value != null ? value : ""); //$NON-NLS-1$
+	protected void doSetValue(CCombo source, String value) {
+		source.setText(value != null ? value : ""); //$NON-NLS-1$
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CLabelImageProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CLabelImageProperty.java
index e72cc84..3e58dac 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CLabelImageProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CLabelImageProperty.java
@@ -18,13 +18,13 @@
  * @since 3.3
  * 
  */
-public class CLabelImageProperty extends WidgetImageValueProperty {
-	Image doGetImageValue(Object source) {
-		return ((CLabel) source).getImage();
+public class CLabelImageProperty extends WidgetImageValueProperty<CLabel> {
+	Image doGetImageValue(CLabel source) {
+		return source.getImage();
 	}
 
-	void doSetImageValue(Object source, Image value) {
-		((CLabel) source).setImage(value);
+	void doSetImageValue(CLabel source, Image value) {
+		source.setImage(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CLabelTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CLabelTextProperty.java
index 5aeb166..e25f286 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CLabelTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CLabelTextProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class CLabelTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((CLabel) source).getText();
+public class CLabelTextProperty extends WidgetStringValueProperty<CLabel> {
+	protected String doGetValue(CLabel source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((CLabel) source).setText(value == null ? "" : value); //$NON-NLS-1$
+	protected void doSetValue(CLabel source, String value) {
+		source.setText(value == null ? "" : value); //$NON-NLS-1$
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CTabItemTooltipTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CTabItemTooltipTextProperty.java
index 790fda2..86565d6 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CTabItemTooltipTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/CTabItemTooltipTextProperty.java
@@ -18,13 +18,14 @@
  * @since 3.3
  * 
  */
-public class CTabItemTooltipTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((CTabItem) source).getToolTipText();
+public class CTabItemTooltipTextProperty extends
+		WidgetStringValueProperty<CTabItem> {
+	protected String doGetValue(CTabItem source) {
+		return source.getToolTipText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((CTabItem) source).setToolTipText(value);
+	protected void doSetValue(CTabItem source, String value) {
+		source.setToolTipText(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboItemsProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboItemsProperty.java
index 12c8588..9f562b8 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboItemsProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboItemsProperty.java
@@ -21,7 +21,7 @@
  * @since 3.3
  * 
  */
-public class ComboItemsProperty extends ControlStringListProperty {
+public class ComboItemsProperty extends ControlStringListProperty<Combo> {
 	protected void doUpdateStringList(final Control control, ListDiff diff) {
 		diff.accept(new ListDiffVisitor() {
 			Combo combo = (Combo) control;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboSelectionProperty.java
index 3aab542..b50fbfe 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboSelectionProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboSelectionProperty.java
@@ -18,7 +18,7 @@
  * @since 3.3
  * 
  */
-public class ComboSelectionProperty extends WidgetStringValueProperty {
+public class ComboSelectionProperty extends WidgetStringValueProperty<Combo> {
 	/**
 	 * 
 	 */
@@ -26,13 +26,12 @@
 		super(SWT.Modify);
 	}
 
-	String doGetStringValue(Object source) {
-		return ((Combo) source).getText();
+	protected String doGetValue(Combo source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		Combo combo = (Combo) source;
-		String items[] = combo.getItems();
+	protected void doSetValue(Combo source, String value) {
+		String items[] = source.getItems();
 		int index = -1;
 		if (items != null && value != null) {
 			for (int i = 0; i < items.length; i++) {
@@ -42,9 +41,9 @@
 				}
 			}
 			if (index == -1) {
-				combo.setText(value);
+				source.setText(value);
 			} else {
-				combo.select(index); // -1 will not "unselect"
+				source.select(index); // -1 will not "unselect"
 			}
 		}
 	}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboSingleSelectionIndexProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboSingleSelectionIndexProperty.java
index ab5bc16..e3f890d 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboSingleSelectionIndexProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboSingleSelectionIndexProperty.java
@@ -19,7 +19,7 @@
  * 
  */
 public class ComboSingleSelectionIndexProperty extends
-		SingleSelectionIndexProperty {
+		WidgetIntValueProperty<Combo> {
 	/**
 	 * 
 	 */
@@ -27,15 +27,18 @@
 		super(new int[] { SWT.Selection, SWT.DefaultSelection });
 	}
 
-	int doGetIntValue(Object source) {
-		return ((Combo) source).getSelectionIndex();
+	protected Integer doGetValue(Combo source) {
+		// Ideally we would return null when no selection but
+		// that might break existing users so we stick with -1
+		return source.getSelectionIndex();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		if (value == -1)
-			((Combo) source).deselectAll();
-		else
-			((Combo) source).select(value);
+	protected void doSetValue(Combo source, Integer value) {
+		if (value == null || value.intValue() == -1) {
+			source.deselectAll();
+		} else {
+			source.select(value);
+		}
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboTextProperty.java
index f35b9a8..07b2980 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ComboTextProperty.java
@@ -18,7 +18,7 @@
  * @since 3.3
  * 
  */
-public class ComboTextProperty extends WidgetStringValueProperty {
+public class ComboTextProperty extends WidgetStringValueProperty<Combo> {
 	/**
 	 * 
 	 */
@@ -26,12 +26,12 @@
 		super(SWT.Modify);
 	}
 
-	String doGetStringValue(Object source) {
-		return ((Combo) source).getText();
+	protected String doGetValue(Combo source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((Combo) source).setText(value != null ? value : ""); //$NON-NLS-1$
+	protected void doSetValue(Combo source, String value) {
+		source.setText(value != null ? value : ""); //$NON-NLS-1$
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlBackgroundProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlBackgroundProperty.java
index 6af816d..1042c41 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlBackgroundProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlBackgroundProperty.java
@@ -20,17 +20,18 @@
  * @since 3.3
  * 
  */
-public class ControlBackgroundProperty extends WidgetValueProperty {
+public class ControlBackgroundProperty extends
+		WidgetValueProperty<Control, Color> {
 	public Object getValueType() {
 		return Color.class;
 	}
 
-	protected Object doGetValue(Object source) {
-		return ((Control) source).getBackground();
+	protected Color doGetValue(Control source) {
+		return source.getBackground();
 	}
 
-	protected void doSetValue(Object source, Object value) {
-		((Control) source).setBackground((Color) value);
+	protected void doSetValue(Control source, Color value) {
+		source.setBackground(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlBoundsProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlBoundsProperty.java
index 95c290e..ba4353c 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlBoundsProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlBoundsProperty.java
@@ -22,7 +22,8 @@
  * @since 3.3
  * 
  */
-public class ControlBoundsProperty extends WidgetValueProperty {
+public class ControlBoundsProperty extends
+		WidgetValueProperty<Control, Rectangle> {
 	/**
 	 * 
 	 */
@@ -34,12 +35,12 @@
 		return Rectangle.class;
 	}
 
-	protected Object doGetValue(Object source) {
-		return ((Control) source).getBounds();
+	protected Rectangle doGetValue(Control source) {
+		return source.getBounds();
 	}
 
-	protected void doSetValue(Object source, Object value) {
-		((Control) source).setBounds((Rectangle) value);
+	protected void doSetValue(Control source, Rectangle value) {
+		source.setBounds(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlEnabledProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlEnabledProperty.java
index 1cd2c25..e6e8190 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlEnabledProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlEnabledProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class ControlEnabledProperty extends WidgetBooleanValueProperty {
-	public boolean doGetBooleanValue(Object source) {
-		return ((Control) source).getEnabled();
+public class ControlEnabledProperty extends WidgetBooleanValueProperty<Control> {
+	public boolean doGetBooleanValue(Control source) {
+		return source.getEnabled();
 	}
 
-	void doSetBooleanValue(Object source, boolean value) {
-		((Control) source).setEnabled(value);
+	void doSetBooleanValue(Control source, boolean value) {
+		source.setEnabled(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlFocusedProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlFocusedProperty.java
index caa5f58..6d18f4f 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlFocusedProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlFocusedProperty.java
@@ -13,6 +13,7 @@
 package org.eclipse.jface.internal.databinding.swt;
 
 import org.eclipse.core.databinding.observable.Diffs;
+import org.eclipse.core.databinding.observable.value.ValueDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.IProperty;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
@@ -24,7 +25,7 @@
  * @since 3.3
  * 
  */
-public class ControlFocusedProperty extends WidgetBooleanValueProperty {
+public class ControlFocusedProperty extends WidgetBooleanValueProperty<Control> {
 	/**
 	 * 
 	 */
@@ -32,22 +33,23 @@
 		super();
 	}
 
-	public boolean doGetBooleanValue(Object source) {
-		return ((Control) source).isFocusControl();
+	public boolean doGetBooleanValue(Control source) {
+		return source.isFocusControl();
 	}
 
-	public void doSetBooleanValue(Object source, boolean value) {
+	public void doSetBooleanValue(Control source, boolean value) {
 		if (value)
-			((Control) source).setFocus();
+			source.setFocus();
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<Control> adaptListener(
+			ISimplePropertyListener<ValueDiff<Boolean>> listener) {
 		int[] events = { SWT.FocusIn, SWT.FocusOut };
 		return new ControlFocusListener(this, listener, events, null);
 	}
 
-	private class ControlFocusListener extends WidgetListener {
+	private class ControlFocusListener extends
+			WidgetListener<Control, ValueDiff<Boolean>> {
 		/**
 		 * @param property
 		 * @param listener
@@ -55,20 +57,20 @@
 		 * @param staleEvents
 		 */
 		private ControlFocusListener(IProperty property,
-				ISimplePropertyListener listener, int[] changeEvents,
-				int[] staleEvents) {
+				ISimplePropertyListener<ValueDiff<Boolean>> listener,
+				int[] changeEvents, int[] staleEvents) {
 			super(property, listener, changeEvents, staleEvents);
 		}
 
 		public void handleEvent(Event event) {
 			switch (event.type) {
 			case SWT.FocusIn:
-				fireChange(event.widget, Diffs.createValueDiff(Boolean.FALSE,
-						Boolean.TRUE));
+				fireChange(event.widget,
+						Diffs.createValueDiff(Boolean.FALSE, Boolean.TRUE));
 				break;
 			case SWT.FocusOut:
-				fireChange(event.widget, Diffs.createValueDiff(Boolean.TRUE,
-						Boolean.FALSE));
+				fireChange(event.widget,
+						Diffs.createValueDiff(Boolean.TRUE, Boolean.FALSE));
 				break;
 			}
 		}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlFontProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlFontProperty.java
index dc6ea7f..fc6fbc5 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlFontProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlFontProperty.java
@@ -20,17 +20,17 @@
  * @since 3.3
  * 
  */
-public class ControlFontProperty extends WidgetValueProperty {
+public class ControlFontProperty extends WidgetValueProperty<Control, Font> {
 	public Object getValueType() {
 		return Font.class;
 	}
 
-	protected Object doGetValue(Object source) {
-		return ((Control) source).getFont();
+	protected Font doGetValue(Control source) {
+		return source.getFont();
 	}
 
-	protected void doSetValue(Object source, Object value) {
-		((Control) source).setFont((Font) value);
+	protected void doSetValue(Control source, Font value) {
+		source.setFont(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlForegroundProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlForegroundProperty.java
index ba415ed..d11d717 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlForegroundProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlForegroundProperty.java
@@ -20,17 +20,18 @@
  * @since 3.3
  * 
  */
-public class ControlForegroundProperty extends WidgetValueProperty {
+public class ControlForegroundProperty extends
+		WidgetValueProperty<Control, Color> {
 	public Object getValueType() {
 		return Color.class;
 	}
 
-	protected Object doGetValue(Object source) {
-		return ((Control) source).getForeground();
+	protected Color doGetValue(Control source) {
+		return source.getForeground();
 	}
 
-	protected void doSetValue(Object source, Object value) {
-		((Control) source).setForeground((Color) value);
+	protected void doSetValue(Control source, Color value) {
+		source.setForeground(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlLocationProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlLocationProperty.java
index 5178995..28353e3 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlLocationProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlLocationProperty.java
@@ -22,7 +22,8 @@
  * @since 3.3
  * 
  */
-public class ControlLocationProperty extends WidgetValueProperty {
+public class ControlLocationProperty extends
+		WidgetValueProperty<Control, Point> {
 	/**
 	 * 
 	 */
@@ -34,12 +35,12 @@
 		return Point.class;
 	}
 
-	protected Object doGetValue(Object source) {
-		return ((Control) source).getLocation();
+	protected Point doGetValue(Control source) {
+		return source.getLocation();
 	}
 
-	protected void doSetValue(Object source, Object value) {
-		((Control) source).setLocation((Point) value);
+	protected void doSetValue(Control source, Point value) {
+		source.setLocation(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlSizeProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlSizeProperty.java
index 4f4bbee..1eaa13b 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlSizeProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlSizeProperty.java
@@ -22,7 +22,7 @@
  * @since 3.3
  * 
  */
-public class ControlSizeProperty extends WidgetValueProperty {
+public class ControlSizeProperty extends WidgetValueProperty<Control, Point> {
 	/**
 	 * 
 	 */
@@ -34,12 +34,12 @@
 		return Point.class;
 	}
 
-	protected Object doGetValue(Object source) {
-		return ((Control) source).getSize();
+	protected Point doGetValue(Control source) {
+		return source.getSize();
 	}
 
-	protected void doSetValue(Object source, Object value) {
-		((Control) source).setSize((Point) value);
+	protected void doSetValue(Control source, Point value) {
+		source.setSize(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlStringListProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlStringListProperty.java
index b06d8e4..eb290f6 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlStringListProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlStringListProperty.java
@@ -22,33 +22,33 @@
 import org.eclipse.swt.widgets.Control;
 
 /**
+ * @param <S>
  * @since 3.3
  * 
  */
-public abstract class ControlStringListProperty extends WidgetListProperty {
+public abstract class ControlStringListProperty<S extends Control> extends
+		WidgetListProperty<S, String> {
 	public Object getElementType() {
 		return String.class;
 	}
 
-	protected void doSetList(Object source, List list, ListDiff diff) {
+	public Class<String> getElementClass() {
+		return String.class;
+	}
+
+	protected void doSetList(S source, List<String> list, ListDiff<String> diff) {
 		doUpdateList(source, diff);
 	}
 
-	protected void doUpdateList(Object source, ListDiff diff) {
-		doUpdateStringList((Control) source, diff);
-	}
-
-	abstract void doUpdateStringList(Control control, ListDiff diff);
-
-	protected List doGetList(Object source) {
-		String[] list = doGetStringList((Control) source);
+	protected List<String> doGetList(S source) {
+		String[] list = doGetStringList(source);
 		return Arrays.asList(list);
 	}
 
 	abstract String[] doGetStringList(Control control);
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<S> adaptListener(
+			ISimplePropertyListener<ListDiff<String>> listener) {
 		return null;
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlTooltipTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlTooltipTextProperty.java
index 1c4a9c0..a63009e 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlTooltipTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlTooltipTextProperty.java
@@ -17,13 +17,14 @@
  * @since 3.3
  * 
  */
-public class ControlTooltipTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((Control) source).getToolTipText();
+public class ControlTooltipTextProperty extends
+		WidgetStringValueProperty<Control> {
+	protected String doGetValue(Control source) {
+		return source.getToolTipText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((Control) source).setToolTipText(value);
+	protected void doSetValue(Control source, String value) {
+		source.setToolTipText(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlVisibleProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlVisibleProperty.java
index 055657d..7ba3b3c 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlVisibleProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ControlVisibleProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class ControlVisibleProperty extends WidgetBooleanValueProperty {
-	boolean doGetBooleanValue(Object source) {
-		return ((Control) source).getVisible();
+public class ControlVisibleProperty extends WidgetBooleanValueProperty<Control> {
+	boolean doGetBooleanValue(Control source) {
+		return source.getVisible();
 	}
 
-	void doSetBooleanValue(Object source, boolean value) {
-		((Control) source).setVisible(value);
+	void doSetBooleanValue(Control source, boolean value) {
+		source.setVisible(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ItemImageProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ItemImageProperty.java
index 310ea68..ca58a69 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ItemImageProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ItemImageProperty.java
@@ -18,13 +18,13 @@
  * @since 3.3
  * 
  */
-public class ItemImageProperty extends WidgetImageValueProperty {
-	Image doGetImageValue(Object source) {
-		return ((Item) source).getImage();
+public class ItemImageProperty extends WidgetImageValueProperty<Item> {
+	Image doGetImageValue(Item source) {
+		return source.getImage();
 	}
 
-	void doSetImageValue(Object source, Image value) {
-		((Item) source).setImage(value);
+	void doSetImageValue(Item source, Image value) {
+		source.setImage(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ItemTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ItemTextProperty.java
index bfcf462..21ae0b6 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ItemTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ItemTextProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class ItemTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((Item) source).getText();
+public class ItemTextProperty extends WidgetStringValueProperty<Item> {
+	protected String doGetValue(Item source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((Item) source).setText(value == null ? "" : value); //$NON-NLS-1$
+	protected void doSetValue(Item source, String value) {
+		source.setText(value == null ? "" : value); //$NON-NLS-1$
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LabelImageProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LabelImageProperty.java
index 3722125..de3c071 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LabelImageProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LabelImageProperty.java
@@ -18,13 +18,13 @@
  * @since 3.3
  * 
  */
-public class LabelImageProperty extends WidgetImageValueProperty {
-	Image doGetImageValue(Object source) {
-		return ((Label) source).getImage();
+public class LabelImageProperty extends WidgetImageValueProperty<Label> {
+	Image doGetImageValue(Label source) {
+		return source.getImage();
 	}
 
-	void doSetImageValue(Object source, Image value) {
-		((Label) source).setImage(value);
+	void doSetImageValue(Label source, Image value) {
+		source.setImage(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LabelTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LabelTextProperty.java
index f7baeee..fd62ecd 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LabelTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LabelTextProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class LabelTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((Label) source).getText();
+public class LabelTextProperty extends WidgetStringValueProperty<Label> {
+	protected String doGetValue(Label source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((Label) source).setText(value == null ? "" : value); //$NON-NLS-1$
+	protected void doSetValue(Label source, String value) {
+		source.setText(value == null ? "" : value); //$NON-NLS-1$
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LinkTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LinkTextProperty.java
index 7a7141d..c8d6097 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LinkTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/LinkTextProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class LinkTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((Link) source).getText();
+public class LinkTextProperty extends WidgetStringValueProperty<Link> {
+	protected String doGetValue(Link source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((Link) source).setText(value == null ? "" : value); //$NON-NLS-1$
+	protected void doSetValue(Link source, String value) {
+		source.setText(value == null ? "" : value); //$NON-NLS-1$
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListItemsProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListItemsProperty.java
index c5e3035..efc405e 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListItemsProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListItemsProperty.java
@@ -21,16 +21,16 @@
  * @since 3.3
  * 
  */
-public class ListItemsProperty extends ControlStringListProperty {
-	protected void doUpdateStringList(final Control control, ListDiff diff) {
-		diff.accept(new ListDiffVisitor() {
-			List list = (List) control;
+public class ListItemsProperty extends ControlStringListProperty<List> {
+	protected void doUpdateStringList(final List control, ListDiff<String> diff) {
+		diff.accept(new ListDiffVisitor<String>() {
+			List list = control;
 
-			public void handleAdd(int index, Object element) {
-				list.add((String) element, index);
+			public void handleAdd(int index, String element) {
+				list.add(element, index);
 			}
 
-			public void handleRemove(int index, Object element) {
+			public void handleRemove(int index, String element) {
 				list.remove(index);
 			}
 
@@ -52,9 +52,9 @@
 			// }
 			// }
 
-			public void handleReplace(int index, Object oldElement,
-					Object newElement) {
-				list.setItem(index, (String) newElement);
+			public void handleReplace(int index, String oldElement,
+					String newElement) {
+				list.setItem(index, newElement);
 			}
 		});
 	}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListSelectionProperty.java
index 7648d6e..16dce37 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListSelectionProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListSelectionProperty.java
@@ -18,7 +18,7 @@
  * @since 3.3
  * 
  */
-public class ListSelectionProperty extends WidgetStringValueProperty {
+public class ListSelectionProperty extends WidgetStringValueProperty<List> {
 	/**
 	 * 
 	 */
@@ -26,17 +26,15 @@
 		super(SWT.Selection);
 	}
 
-	String doGetStringValue(Object source) {
-		List list = (List) source;
-		int index = list.getSelectionIndex();
+	protected String doGetValue(List source) {
+		int index = source.getSelectionIndex();
 		if (index >= 0)
-			return list.getItem(index);
+			return source.getItem(index);
 		return null;
 	}
 
-	void doSetStringValue(Object source, String value) {
-		List list = (List) source;
-		String items[] = list.getItems();
+	protected void doSetValue(List source, String value) {
+		String items[] = source.getItems();
 		int index = -1;
 		if (items != null && value != null) {
 			for (int i = 0; i < items.length; i++) {
@@ -45,7 +43,7 @@
 					break;
 				}
 			}
-			list.select(index);
+			source.select(index);
 		}
 	}
 
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListSingleSelectionIndexProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListSingleSelectionIndexProperty.java
index 33e9680..c20ec0c 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListSingleSelectionIndexProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ListSingleSelectionIndexProperty.java
@@ -19,7 +19,7 @@
  * 
  */
 public class ListSingleSelectionIndexProperty extends
-		SingleSelectionIndexProperty {
+		WidgetIntValueProperty<List> {
 	/**
 	 * 
 	 */
@@ -27,15 +27,18 @@
 		super(new int[] { SWT.Selection, SWT.DefaultSelection });
 	}
 
-	int doGetIntValue(Object source) {
-		return ((List) source).getSelectionIndex();
+	protected Integer doGetValue(List source) {
+		// Ideally we would return null when no selection but
+		// that might break existing users so we stick with -1
+		return source.getSelectionIndex();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		if (value == -1)
-			((List) source).deselectAll();
-		else
-			((List) source).setSelection(value);
+	protected void doSetValue(List source, Integer value) {
+		if (value == null || value.intValue() == -1) {
+			source.deselectAll();
+		} else {
+			source.setSelection(value);
+		}
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuEnabledProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuEnabledProperty.java
index 05e3c25..bd0fe77 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuEnabledProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuEnabledProperty.java
@@ -16,13 +16,13 @@
 /**
  * 
  */
-public class MenuEnabledProperty extends WidgetBooleanValueProperty {
-	public boolean doGetBooleanValue(Object source) {
-		return ((Menu) source).getEnabled();
+public class MenuEnabledProperty extends WidgetBooleanValueProperty<Menu> {
+	public boolean doGetBooleanValue(Menu source) {
+		return source.getEnabled();
 	}
 
-	void doSetBooleanValue(Object source, boolean value) {
-		((Menu) source).setEnabled(value);
+	void doSetBooleanValue(Menu source, boolean value) {
+		source.setEnabled(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuItemEnabledProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuItemEnabledProperty.java
index 9340e00..22d6621 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuItemEnabledProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuItemEnabledProperty.java
@@ -16,13 +16,14 @@
 /**
  * 
  */
-public class MenuItemEnabledProperty extends WidgetBooleanValueProperty {
-	public boolean doGetBooleanValue(Object source) {
-		return ((MenuItem) source).getEnabled();
+public class MenuItemEnabledProperty extends
+		WidgetBooleanValueProperty<MenuItem> {
+	public boolean doGetBooleanValue(MenuItem source) {
+		return source.getEnabled();
 	}
 
-	void doSetBooleanValue(Object source, boolean value) {
-		((MenuItem) source).setEnabled(value);
+	void doSetBooleanValue(MenuItem source, boolean value) {
+		source.setEnabled(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuItemSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuItemSelectionProperty.java
index ae3182d..a2b496d 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuItemSelectionProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/MenuItemSelectionProperty.java
@@ -17,7 +17,8 @@
 /**
  * 
  */
-public class MenuItemSelectionProperty extends WidgetBooleanValueProperty {
+public class MenuItemSelectionProperty extends
+		WidgetBooleanValueProperty<MenuItem> {
 	/**
 	 * 
 	 */
@@ -25,12 +26,12 @@
 		super(SWT.Selection);
 	}
 
-	boolean doGetBooleanValue(Object source) {
-		return ((MenuItem) source).getSelection();
+	boolean doGetBooleanValue(MenuItem source) {
+		return source.getSelection();
 	}
 
-	void doSetBooleanValue(Object source, boolean value) {
-		((MenuItem) source).setSelection(value);
+	void doSetBooleanValue(MenuItem source, boolean value) {
+		source.setSelection(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTDelayedObservableValueDecorator.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTDelayedObservableValueDecorator.java
index 2f7031b..6e1e9b5 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTDelayedObservableValueDecorator.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTDelayedObservableValueDecorator.java
@@ -35,10 +35,12 @@
  * Note that this class will not forward {@link ValueChangingEvent} events from
  * a wrapped {@link IVetoableValue}.
  * 
+ * @param <T>
+ * 
  * @since 1.2
  */
-public class SWTDelayedObservableValueDecorator extends
-		SWTObservableValueDecorator {
+public class SWTDelayedObservableValueDecorator<T> extends
+		SWTObservableValueDecorator<T> {
 	private Control control;
 
 	/**
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTObservableListDecorator.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTObservableListDecorator.java
index dfc88e7..7483d11 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTObservableListDecorator.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTObservableListDecorator.java
@@ -21,18 +21,20 @@
 import org.eclipse.swt.widgets.Widget;
 
 /**
+ * @param <E>
  * @since 3.3
  * 
  */
-public class SWTObservableListDecorator extends DecoratingObservableList
-		implements ISWTObservableList {
+public class SWTObservableListDecorator<E> extends DecoratingObservableList<E>
+		implements ISWTObservableList<E> {
 	private Widget widget;
 
 	/**
 	 * @param decorated
 	 * @param widget
 	 */
-	public SWTObservableListDecorator(IObservableList decorated, Widget widget) {
+	public SWTObservableListDecorator(IObservableList<E> decorated,
+			Widget widget) {
 		super(decorated, true);
 		this.widget = widget;
 		WidgetListenerUtil.asyncAddListener(widget, SWT.Dispose,
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTObservableValueDecorator.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTObservableValueDecorator.java
index 22d9e52..5f6bade 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTObservableValueDecorator.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTObservableValueDecorator.java
@@ -21,18 +21,21 @@
 import org.eclipse.swt.widgets.Widget;
 
 /**
+ * @param <T>
  * @since 3.3
  * 
  */
-public class SWTObservableValueDecorator extends DecoratingObservableValue
-		implements ISWTObservableValue, Listener {
+public class SWTObservableValueDecorator<T> extends
+		DecoratingObservableValue<T> implements ISWTObservableValue<T>,
+		Listener {
 	private Widget widget;
 
 	/**
 	 * @param decorated
 	 * @param widget
 	 */
-	public SWTObservableValueDecorator(IObservableValue decorated, Widget widget) {
+	public SWTObservableValueDecorator(IObservableValue<T> decorated,
+			Widget widget) {
 		super(decorated, true);
 		this.widget = widget;
 		WidgetListenerUtil.asyncAddListener(widget, SWT.Dispose, this);
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTVetoableValueDecorator.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTVetoableValueDecorator.java
index 212c234..5b051d3 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTVetoableValueDecorator.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SWTVetoableValueDecorator.java
@@ -23,17 +23,18 @@
 import org.eclipse.swt.widgets.Widget;
 
 /**
+ * @param <S>
  * @since 3.3
  * 
  */
-public class SWTVetoableValueDecorator extends DecoratingVetoableValue
-		implements ISWTObservableValue {
-	private Widget widget;
-	private WidgetStringValueProperty property;
+public class SWTVetoableValueDecorator<S extends Widget> extends
+		DecoratingVetoableValue<String> implements ISWTObservableValue<String> {
+	private S widget;
+	private WidgetStringValueProperty<S> property;
 
 	private Listener verifyListener = new Listener() {
 		public void handleEvent(Event event) {
-			String currentText = (String) property.getValue(widget);
+			String currentText = property.getValue(widget);
 			String newText = currentText.substring(0, event.start) + event.text
 					+ currentText.substring(event.end);
 			if (!fireValueChanging(Diffs.createValueDiff(currentText, newText))) {
@@ -53,14 +54,15 @@
 	 * @param property
 	 * @param decorated
 	 */
-	public SWTVetoableValueDecorator(Widget widget,
-			WidgetStringValueProperty property, IObservableValue decorated) {
+	public SWTVetoableValueDecorator(S widget,
+			WidgetStringValueProperty<S> property,
+			IObservableValue<String> decorated) {
 		super(decorated, true);
 		this.property = property;
 		this.widget = widget;
-		Assert
-				.isTrue(decorated.getValueType().equals(String.class),
-						"SWTVetoableValueDecorator can only decorate observable values of String value type"); //$NON-NLS-1$
+		Assert.isTrue(
+				decorated.getValueType().equals(String.class),
+				"SWTVetoableValueDecorator can only decorate observable values of String value type"); //$NON-NLS-1$
 		WidgetListenerUtil.asyncAddListener(widget, SWT.Dispose,
 				disposeListener);
 	}
@@ -85,7 +87,7 @@
 		super.dispose();
 	}
 
-	public Widget getWidget() {
+	public S getWidget() {
 		return widget;
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleMaximumProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleMaximumProperty.java
index 885f3b6..f25a480 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleMaximumProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleMaximumProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class ScaleMaximumProperty extends WidgetIntValueProperty {
-	int doGetIntValue(Object source) {
-		return ((Scale) source).getMaximum();
+public class ScaleMaximumProperty extends WidgetIntValueProperty<Scale> {
+	protected Integer doGetValue(Scale source) {
+		return source.getMaximum();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		((Scale) source).setMaximum(value);
+	protected void doSetValue(Scale source, Integer value) {
+		source.setMaximum(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleMinimumProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleMinimumProperty.java
index 23513d8..d2b8bee 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleMinimumProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleMinimumProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class ScaleMinimumProperty extends WidgetIntValueProperty {
-	int doGetIntValue(Object source) {
-		return ((Scale) source).getMinimum();
+public class ScaleMinimumProperty extends WidgetIntValueProperty<Scale> {
+	protected Integer doGetValue(Scale source) {
+		return source.getMinimum();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		((Scale) source).setMinimum(value);
+	protected void doSetValue(Scale source, Integer value) {
+		source.setMinimum(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleSelectionProperty.java
index 00591b5..6bdbb16 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleSelectionProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScaleSelectionProperty.java
@@ -18,7 +18,7 @@
  * @since 3.3
  * 
  */
-public class ScaleSelectionProperty extends WidgetIntValueProperty {
+public class ScaleSelectionProperty extends WidgetIntValueProperty<Scale> {
 	/**
 	 * 
 	 */
@@ -26,12 +26,12 @@
 		super(SWT.Selection);
 	}
 
-	int doGetIntValue(Object source) {
-		return ((Scale) source).getSelection();
+	protected Integer doGetValue(Scale source) {
+		return source.getSelection();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		((Scale) source).setSelection(value);
+	protected void doSetValue(Scale source, Integer value) {
+		source.setSelection(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScrollBarEnabledProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScrollBarEnabledProperty.java
index 241c5c9..cd79cb3 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScrollBarEnabledProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ScrollBarEnabledProperty.java
@@ -16,13 +16,14 @@
 /**
  * 
  */
-public class ScrollBarEnabledProperty extends WidgetBooleanValueProperty {
-	public boolean doGetBooleanValue(Object source) {
-		return ((ScrollBar) source).getEnabled();
+public class ScrollBarEnabledProperty extends
+		WidgetBooleanValueProperty<ScrollBar> {
+	public boolean doGetBooleanValue(ScrollBar source) {
+		return source.getEnabled();
 	}
 
-	void doSetBooleanValue(Object source, boolean value) {
-		((ScrollBar) source).setEnabled(value);
+	void doSetBooleanValue(ScrollBar source, boolean value) {
+		source.setEnabled(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ShellTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ShellTextProperty.java
index 46d8aa6..9ac87d2 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ShellTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ShellTextProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class ShellTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((Shell) source).getText();
+public class ShellTextProperty extends WidgetStringValueProperty<Shell> {
+	protected String doGetValue(Shell source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((Shell) source).setText(value == null ? "" : value); //$NON-NLS-1$
+	protected void doSetValue(Shell source, String value) {
+		source.setText(value == null ? "" : value); //$NON-NLS-1$
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SingleSelectionIndexProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SingleSelectionIndexProperty.java
deleted file mode 100644
index 742f930..0000000
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SingleSelectionIndexProperty.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 Matthew Hall and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Matthew Hall - initial API and implementation (bug 288642)
- ******************************************************************************/
-
-package org.eclipse.jface.internal.databinding.swt;
-
-/**
- * @since 3.3
- * 
- */
-public abstract class SingleSelectionIndexProperty extends
-		WidgetIntValueProperty {
-	/**
-	 * @param events
-	 */
-	public SingleSelectionIndexProperty(int[] events) {
-		super(events);
-	}
-
-	protected void doSetValue(Object source, Object value) {
-		super.doSetValue(source, value == null ? new Integer(-1) : value);
-	}
-}
\ No newline at end of file
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderMaximumProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderMaximumProperty.java
index fa5ce5a..4c04ddc 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderMaximumProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderMaximumProperty.java
@@ -16,13 +16,13 @@
 /**
  * 
  */
-public class SliderMaximumProperty extends WidgetIntValueProperty {
-	int doGetIntValue(Object source) {
-		return ((Slider) source).getMaximum();
+public class SliderMaximumProperty extends WidgetIntValueProperty<Slider> {
+	protected Integer doGetValue(Slider source) {
+		return source.getMaximum();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		((Slider) source).setMaximum(value);
+	protected void doSetValue(Slider source, Integer value) {
+		source.setMaximum(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderMinimumProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderMinimumProperty.java
index 6f36a36..d6aff7f 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderMinimumProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderMinimumProperty.java
@@ -16,13 +16,13 @@
 /**
  * 
  */
-public class SliderMinimumProperty extends WidgetIntValueProperty {
-	int doGetIntValue(Object source) {
-		return ((Slider) source).getMinimum();
+public class SliderMinimumProperty extends WidgetIntValueProperty<Slider> {
+	protected Integer doGetValue(Slider source) {
+		return source.getMinimum();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		((Slider) source).setMinimum(value);
+	protected void doSetValue(Slider source, Integer value) {
+		source.setMinimum(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderSelectionProperty.java
index 99757ce..070acdf 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderSelectionProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SliderSelectionProperty.java
@@ -17,7 +17,7 @@
 /**
  * 
  */
-public class SliderSelectionProperty extends WidgetIntValueProperty {
+public class SliderSelectionProperty extends WidgetIntValueProperty<Slider> {
 	/**
 	 * 
 	 */
@@ -25,12 +25,12 @@
 		super(SWT.Selection);
 	}
 
-	int doGetIntValue(Object source) {
-		return ((Slider) source).getSelection();
+	protected Integer doGetValue(Slider source) {
+		return source.getSelection();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		((Slider) source).setSelection(value);
+	protected void doSetValue(Slider source, Integer value) {
+		source.setSelection(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerMaximumProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerMaximumProperty.java
index 2e01bf2..2d74f82 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerMaximumProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerMaximumProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class SpinnerMaximumProperty extends WidgetIntValueProperty {
-	int doGetIntValue(Object source) {
-		return ((Spinner) source).getMaximum();
+public class SpinnerMaximumProperty extends WidgetIntValueProperty<Spinner> {
+	protected Integer doGetValue(Spinner source) {
+		return source.getMaximum();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		((Spinner) source).setMaximum(value);
+	protected void doSetValue(Spinner source, Integer value) {
+		source.setMaximum(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerMinimumProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerMinimumProperty.java
index e5b05cb..ec4e88c 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerMinimumProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerMinimumProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class SpinnerMinimumProperty extends WidgetIntValueProperty {
-	int doGetIntValue(Object source) {
-		return ((Spinner) source).getMinimum();
+public class SpinnerMinimumProperty extends WidgetIntValueProperty<Spinner> {
+	protected Integer doGetValue(Spinner source) {
+		return source.getMinimum();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		((Spinner) source).setMinimum(value);
+	protected void doSetValue(Spinner source, Integer value) {
+		source.setMinimum(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerSelectionProperty.java
index 26ecfe0..965a4cf 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerSelectionProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/SpinnerSelectionProperty.java
@@ -18,7 +18,7 @@
  * @since 3.3
  * 
  */
-public class SpinnerSelectionProperty extends WidgetIntValueProperty {
+public class SpinnerSelectionProperty extends WidgetIntValueProperty<Spinner> {
 	/**
 	 * 
 	 */
@@ -26,12 +26,12 @@
 		super(SWT.Modify);
 	}
 
-	int doGetIntValue(Object source) {
-		return ((Spinner) source).getSelection();
+	protected Integer doGetValue(Spinner source) {
+		return source.getSelection();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		((Spinner) source).setSelection(value);
+	protected void doSetValue(Spinner source, Integer value) {
+		source.setSelection(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/StyledTextEditableProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/StyledTextEditableProperty.java
index 179809c..6d57a20 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/StyledTextEditableProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/StyledTextEditableProperty.java
@@ -17,13 +17,14 @@
  * @since 3.3
  * 
  */
-public class StyledTextEditableProperty extends WidgetBooleanValueProperty {
-	boolean doGetBooleanValue(Object source) {
-		return ((StyledText) source).getEditable();
+public class StyledTextEditableProperty extends
+		WidgetBooleanValueProperty<StyledText> {
+	boolean doGetBooleanValue(StyledText source) {
+		return source.getEditable();
 	}
 
-	void doSetBooleanValue(Object source, boolean value) {
-		((StyledText) source).setEditable(value);
+	void doSetBooleanValue(StyledText source, boolean value) {
+		source.setEditable(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/StyledTextTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/StyledTextTextProperty.java
index a306359..e7580d2 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/StyledTextTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/StyledTextTextProperty.java
@@ -16,13 +16,13 @@
 import org.eclipse.jface.databinding.swt.ISWTObservableValue;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.widgets.Widget;
 
 /**
  * @since 3.3
  * 
  */
-public class StyledTextTextProperty extends WidgetStringValueProperty {
+public class StyledTextTextProperty extends
+		WidgetStringValueProperty<StyledText> {
 	/**
 	 * 
 	 */
@@ -59,20 +59,20 @@
 		return new int[] { SWT.Modify };
 	}
 
-	String doGetStringValue(Object source) {
-		return ((StyledText) source).getText();
+	protected String doGetValue(StyledText source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((StyledText) source).setText(value == null ? "" : value); //$NON-NLS-1$
+	protected void doSetValue(StyledText source, String value) {
+		source.setText(value == null ? "" : value); //$NON-NLS-1$
 	}
 
 	public String toString() {
 		return "StyledText.text <String>"; //$NON-NLS-1$
 	}
 
-	protected ISWTObservableValue wrapObservable(IObservableValue observable,
-			Widget widget) {
+	protected ISWTObservableValue<String> wrapObservable(
+			IObservableValue<String> observable, StyledText widget) {
 		return new SWTVetoableValueDecorator(widget, this, observable);
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TabItemTooltipTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TabItemTooltipTextProperty.java
index d773fd9..e7ed9cb 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TabItemTooltipTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TabItemTooltipTextProperty.java
@@ -18,13 +18,14 @@
  * @since 3.3
  * 
  */
-public class TabItemTooltipTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((TabItem) source).getToolTipText();
+public class TabItemTooltipTextProperty extends
+		WidgetStringValueProperty<TabItem> {
+	protected String doGetValue(TabItem source) {
+		return source.getToolTipText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((TabItem) source).setToolTipText(value);
+	protected void doSetValue(TabItem source, String value) {
+		source.setToolTipText(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TableColumnTooltipTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TableColumnTooltipTextProperty.java
index bf88296..502abd1 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TableColumnTooltipTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TableColumnTooltipTextProperty.java
@@ -18,13 +18,14 @@
  * @since 3.3
  * 
  */
-public class TableColumnTooltipTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((TableColumn) source).getToolTipText();
+public class TableColumnTooltipTextProperty extends
+		WidgetStringValueProperty<TableColumn> {
+	protected String doGetValue(TableColumn source) {
+		return source.getToolTipText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((TableColumn) source).setToolTipText(value);
+	protected void doSetValue(TableColumn source, String value) {
+		source.setToolTipText(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TableSingleSelectionIndexProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TableSingleSelectionIndexProperty.java
index 1715338..d924c9b 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TableSingleSelectionIndexProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TableSingleSelectionIndexProperty.java
@@ -19,7 +19,7 @@
  * 
  */
 public class TableSingleSelectionIndexProperty extends
-		SingleSelectionIndexProperty {
+		WidgetIntValueProperty<Table> {
 	/**
 	 * 
 	 */
@@ -27,15 +27,18 @@
 		super(new int[] { SWT.Selection, SWT.DefaultSelection });
 	}
 
-	int doGetIntValue(Object source) {
-		return ((Table) source).getSelectionIndex();
+	protected Integer doGetValue(Table source) {
+		// Ideally we would return null when no selection but
+		// that might break existing users so we stick with -1
+		return source.getSelectionIndex();
 	}
 
-	void doSetIntValue(Object source, int value) {
-		if (value == -1)
-			((Table) source).deselectAll();
-		else
-			((Table) source).setSelection(value);
+	protected void doSetValue(Table source, Integer value) {
+		if (value == null || value.intValue() == -1) {
+			source.deselectAll();
+		} else {
+			source.setSelection(value);
+		}
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextEditableProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextEditableProperty.java
index a806510..c400bb7 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextEditableProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextEditableProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class TextEditableProperty extends WidgetBooleanValueProperty {
-	boolean doGetBooleanValue(Object source) {
-		return ((Text) source).getEditable();
+public class TextEditableProperty extends WidgetBooleanValueProperty<Text> {
+	boolean doGetBooleanValue(Text source) {
+		return source.getEditable();
 	}
 
-	void doSetBooleanValue(Object source, boolean value) {
-		((Text) source).setEditable(value);
+	void doSetBooleanValue(Text source, boolean value) {
+		source.setEditable(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextMessageProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextMessageProperty.java
index 042f696..ae8daca 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextMessageProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextMessageProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class TextMessageProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((Text) source).getMessage();
+public class TextMessageProperty extends WidgetStringValueProperty<Text> {
+	protected String doGetValue(Text source) {
+		return source.getMessage();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((Text) source).setMessage(value == null ? "" : value); //$NON-NLS-1$
+	protected void doSetValue(Text source, String value) {
+		source.setMessage(value == null ? "" : value); //$NON-NLS-1$
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextTextProperty.java
index ad7f1ad..6b8a53c 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TextTextProperty.java
@@ -16,13 +16,12 @@
 import org.eclipse.jface.databinding.swt.ISWTObservableValue;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.Widget;
 
 /**
  * @since 3.3
  * 
  */
-public class TextTextProperty extends WidgetStringValueProperty {
+public class TextTextProperty extends WidgetStringValueProperty<Text> {
 	/**
 	 * 
 	 */
@@ -59,20 +58,20 @@
 		return new int[] { SWT.Modify };
 	}
 
-	String doGetStringValue(Object source) {
-		return ((Text) source).getText();
+	protected String doGetValue(Text source) {
+		return source.getText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((Text) source).setText(value == null ? "" : value); //$NON-NLS-1$
+	protected void doSetValue(Text source, String value) {
+		source.setText(value == null ? "" : value); //$NON-NLS-1$
 	}
 
 	public String toString() {
 		return "Text.text <String>"; //$NON-NLS-1$
 	}
 
-	protected ISWTObservableValue wrapObservable(IObservableValue observable,
-			Widget widget) {
-		return new SWTVetoableValueDecorator(widget, this, observable);
+	protected ISWTObservableValue<String> wrapObservable(
+			IObservableValue<String> observable, Text widget) {
+		return new SWTVetoableValueDecorator<Text>(widget, this, observable);
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolItemEnabledProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolItemEnabledProperty.java
index 9a38502..855a04e 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolItemEnabledProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolItemEnabledProperty.java
@@ -16,13 +16,14 @@
 /**
  * 
  */
-public class ToolItemEnabledProperty extends WidgetBooleanValueProperty {
-	public boolean doGetBooleanValue(Object source) {
-		return ((ToolItem) source).getEnabled();
+public class ToolItemEnabledProperty extends
+		WidgetBooleanValueProperty<ToolItem> {
+	public boolean doGetBooleanValue(ToolItem source) {
+		return source.getEnabled();
 	}
 
-	void doSetBooleanValue(Object source, boolean value) {
-		((ToolItem) source).setEnabled(value);
+	void doSetBooleanValue(ToolItem source, boolean value) {
+		source.setEnabled(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolItemTooltipTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolItemTooltipTextProperty.java
index 7b19632..44b64ec 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolItemTooltipTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolItemTooltipTextProperty.java
@@ -18,13 +18,14 @@
  * @since 3.3
  * 
  */
-public class ToolItemTooltipTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((ToolItem) source).getToolTipText();
+public class ToolItemTooltipTextProperty extends
+		WidgetStringValueProperty<ToolItem> {
+	protected String doGetValue(ToolItem source) {
+		return source.getToolTipText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((ToolItem) source).setToolTipText(value);
+	protected void doSetValue(ToolItem source, String value) {
+		source.setToolTipText(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolTipMessageProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolTipMessageProperty.java
index 88dd0ef..da441a1 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolTipMessageProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/ToolTipMessageProperty.java
@@ -17,13 +17,13 @@
  * @since 3.3
  * 
  */
-public class ToolTipMessageProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((ToolTip) source).getMessage();
+public class ToolTipMessageProperty extends WidgetStringValueProperty<ToolTip> {
+	protected String doGetValue(ToolTip source) {
+		return source.getMessage();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((ToolTip) source).setMessage(value == null ? "" : value); //$NON-NLS-1$
+	protected void doSetValue(ToolTip source, String value) {
+		source.setMessage(value == null ? "" : value); //$NON-NLS-1$
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TrayItemTooltipTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TrayItemTooltipTextProperty.java
index 25c3f89..d4501c6 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TrayItemTooltipTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TrayItemTooltipTextProperty.java
@@ -18,13 +18,14 @@
  * @since 3.3
  * 
  */
-public class TrayItemTooltipTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((TrayItem) source).getToolTipText();
+public class TrayItemTooltipTextProperty extends
+		WidgetStringValueProperty<TrayItem> {
+	protected String doGetValue(TrayItem source) {
+		return source.getToolTipText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((TrayItem) source).setToolTipText(value);
+	protected void doSetValue(TrayItem source, String value) {
+		source.setToolTipText(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TreeColumnTooltipTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TreeColumnTooltipTextProperty.java
index 18ab0d1..ec92a15 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TreeColumnTooltipTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/TreeColumnTooltipTextProperty.java
@@ -18,13 +18,14 @@
  * @since 3.3
  * 
  */
-public class TreeColumnTooltipTextProperty extends WidgetStringValueProperty {
-	String doGetStringValue(Object source) {
-		return ((TreeColumn) source).getToolTipText();
+public class TreeColumnTooltipTextProperty extends
+		WidgetStringValueProperty<TreeColumn> {
+	protected String doGetValue(TreeColumn source) {
+		return source.getToolTipText();
 	}
 
-	void doSetStringValue(Object source, String value) {
-		((TreeColumn) source).setToolTipText(value);
+	protected void doSetValue(TreeColumn source, String value) {
+		source.setToolTipText(value);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetBooleanValueProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetBooleanValueProperty.java
index 1036fb2..d9f0e5c 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetBooleanValueProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetBooleanValueProperty.java
@@ -13,12 +13,15 @@
 package org.eclipse.jface.internal.databinding.swt;
 
 import org.eclipse.jface.databinding.swt.WidgetValueProperty;
+import org.eclipse.swt.widgets.Widget;
 
 /**
+ * @param <S>
  * @since 3.3
  * 
  */
-public abstract class WidgetBooleanValueProperty extends WidgetValueProperty {
+public abstract class WidgetBooleanValueProperty<S extends Widget> extends
+		WidgetValueProperty<S, Boolean> {
 	WidgetBooleanValueProperty() {
 		super();
 	}
@@ -35,17 +38,17 @@
 		return Boolean.TYPE;
 	}
 
-	protected Object doGetValue(Object source) {
+	protected Boolean doGetValue(S source) {
 		return doGetBooleanValue(source) ? Boolean.TRUE : Boolean.FALSE;
 	}
 
-	protected void doSetValue(Object source, Object value) {
+	protected void doSetValue(S source, Boolean value) {
 		if (value == null)
 			value = Boolean.FALSE;
-		doSetBooleanValue(source, ((Boolean) value).booleanValue());
+		doSetBooleanValue(source, value.booleanValue());
 	}
 
-	abstract boolean doGetBooleanValue(Object source);
+	abstract boolean doGetBooleanValue(S source);
 
-	abstract void doSetBooleanValue(Object source, boolean value);
+	abstract void doSetBooleanValue(S source, boolean value);
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetDelegatingListProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetDelegatingListProperty.java
index 7024c63..3f303c4 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetDelegatingListProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetDelegatingListProperty.java
@@ -17,8 +17,8 @@
 import org.eclipse.jface.databinding.swt.SWTObservables;
 import org.eclipse.swt.widgets.Widget;
 
-abstract class WidgetDelegatingListProperty extends DelegatingListProperty
-		implements IWidgetListProperty {
+public abstract class WidgetDelegatingListProperty<S extends Widget, E> extends
+		DelegatingListProperty<S, E> implements IWidgetListProperty<S, E> {
 	RuntimeException notSupported(Object source) {
 		return new IllegalArgumentException(
 				"Widget [" + source.getClass().getName() + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
@@ -28,8 +28,8 @@
 		super(elementType);
 	}
 
-	public ISWTObservableList observe(Widget widget) {
-		return (ISWTObservableList) observe(SWTObservables.getRealm(widget
-				.getDisplay()), widget);
+	public ISWTObservableList<E> observe(S widget) {
+		return (ISWTObservableList) observe(
+				SWTObservables.getRealm(widget.getDisplay()), widget);
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetDelegatingValueProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetDelegatingValueProperty.java
index 1b7e82c..04911a0 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetDelegatingValueProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetDelegatingValueProperty.java
@@ -17,8 +17,9 @@
 import org.eclipse.jface.databinding.swt.SWTObservables;
 import org.eclipse.swt.widgets.Widget;
 
-abstract class WidgetDelegatingValueProperty extends DelegatingValueProperty
-		implements IWidgetValueProperty {
+public abstract class WidgetDelegatingValueProperty<S extends Widget, T>
+		extends DelegatingValueProperty<S, T> implements
+		IWidgetValueProperty<S, T> {
 	RuntimeException notSupported(Object source) {
 		return new IllegalArgumentException(
 				"Widget [" + source.getClass().getName() + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
@@ -31,12 +32,12 @@
 		super(valueType);
 	}
 
-	public ISWTObservableValue observe(Widget widget) {
-		return (ISWTObservableValue) observe(SWTObservables.getRealm(widget
-				.getDisplay()), widget);
+	public ISWTObservableValue<T> observe(S widget) {
+		return (ISWTObservableValue<T>) observe(
+				SWTObservables.getRealm(widget.getDisplay()), widget);
 	}
 
-	public ISWTObservableValue observeDelayed(int delay, Widget widget) {
+	public ISWTObservableValue<T> observeDelayed(int delay, S widget) {
 		return SWTObservables.observeDelayedValue(delay, observe(widget));
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetEditableProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetEditableProperty.java
index f1d1a6f..11400a5 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetEditableProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetEditableProperty.java
@@ -19,8 +19,11 @@
 
 /**
  * @since 3.3
- * 
+ * @deprecated use static methods in WidgetProperties instead (the method names
+ *             will start with 'editable')
  */
+// ok to ignore warnings in deprecated class
+@SuppressWarnings("rawtypes")
 public class WidgetEditableProperty extends WidgetDelegatingValueProperty {
 	IValueProperty text;
 	IValueProperty ccombo;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetEnabledProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetEnabledProperty.java
index d49112f..8cd6afb 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetEnabledProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetEnabledProperty.java
@@ -17,16 +17,21 @@
 import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.ScrollBar;
 import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.swt.widgets.Widget;
 
 /**
- * 
+ * @deprecated use static methods in WidgetProperties instead (the method names
+ *             will start with 'enabled')
  */
-public class WidgetEnabledProperty extends WidgetDelegatingValueProperty {
-	IValueProperty control;
-	IValueProperty menu;
-	IValueProperty menuItem;
-	IValueProperty scrollBar;
-	IValueProperty toolItem;
+// ok to ignore warnings in deprecated class
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public class WidgetEnabledProperty extends
+		WidgetDelegatingValueProperty<Widget, Boolean> {
+	IValueProperty<Control, Boolean> control;
+	IValueProperty<Menu, Boolean> menu;
+	IValueProperty<MenuItem, Boolean> menuItem;
+	IValueProperty<ScrollBar, Boolean> scrollBar;
+	IValueProperty<ToolItem, Boolean> toolItem;
 
 	/**
 	 * 
@@ -35,7 +40,7 @@
 		super(Boolean.TYPE);
 	}
 
-	protected IValueProperty doGetDelegate(Object source) {
+	protected IValueProperty doGetDelegate(Widget source) {
 		if (source instanceof Control) {
 			if (control == null)
 				control = new ControlEnabledProperty();
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetImageProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetImageProperty.java
index 2197b08..bd06f46 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetImageProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetImageProperty.java
@@ -21,7 +21,10 @@
 /**
  * @since 3.3
  * 
+ * @deprecated this method is used only by deprecated methods
  */
+// ok to ignore warnings in deprecated class
+@SuppressWarnings("rawtypes")
 public class WidgetImageProperty extends WidgetDelegatingValueProperty {
 	private IValueProperty button;
 	private IValueProperty cLabel;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetImageValueProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetImageValueProperty.java
index 07e0e3f..96f033e 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetImageValueProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetImageValueProperty.java
@@ -14,25 +14,28 @@
 
 import org.eclipse.jface.databinding.swt.WidgetValueProperty;
 import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Widget;
 
 /**
+ * @param <S>
  * @since 3.3
  * 
  */
-public abstract class WidgetImageValueProperty extends WidgetValueProperty {
-	public Object getValueType() {
+public abstract class WidgetImageValueProperty<S extends Widget> extends
+		WidgetValueProperty<S, Image> {
+	public Class<Image> getValueType() {
 		return Image.class;
 	}
 
-	protected Object doGetValue(Object source) {
+	protected Image doGetValue(S source) {
 		return doGetImageValue(source);
 	}
 
-	protected void doSetValue(Object source, Object value) {
-		doSetImageValue(source, (Image) value);
+	protected void doSetValue(S source, Image value) {
+		doSetImageValue(source, value);
 	}
 
-	abstract Image doGetImageValue(Object source);
+	abstract Image doGetImageValue(S source);
 
-	abstract void doSetImageValue(Object source, Image value);
+	abstract void doSetImageValue(S source, Image value);
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetIntValueProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetIntValueProperty.java
index 6134d84..05d1beb 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetIntValueProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetIntValueProperty.java
@@ -13,12 +13,17 @@
 package org.eclipse.jface.internal.databinding.swt;
 
 import org.eclipse.jface.databinding.swt.WidgetValueProperty;
+import org.eclipse.swt.widgets.Widget;
 
 /**
+ * @param <S>
+ *            type of the source control (the control that contains this
+ *            property)
  * @since 3.3
  * 
  */
-public abstract class WidgetIntValueProperty extends WidgetValueProperty {
+public abstract class WidgetIntValueProperty<S extends Widget> extends
+		WidgetValueProperty<S, Integer> {
 	WidgetIntValueProperty() {
 		super();
 	}
@@ -34,16 +39,4 @@
 	public Object getValueType() {
 		return Integer.TYPE;
 	}
-
-	protected Object doGetValue(Object source) {
-		return new Integer(doGetIntValue(source));
-	}
-
-	protected void doSetValue(Object source, Object value) {
-		doSetIntValue(source, ((Integer) value).intValue());
-	}
-
-	abstract int doGetIntValue(Object source);
-
-	abstract void doSetIntValue(Object source, int intValue);
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetItemsProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetItemsProperty.java
index 96567be..2298aa3 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetItemsProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetItemsProperty.java
@@ -18,8 +18,11 @@
 
 /**
  * @since 3.3
- * 
+ * @deprecated use static methods in WidgetProperties instead (the method names
+ *             will start with 'items')
  */
+// ok to ignore warnings in deprecated class
+@SuppressWarnings("rawtypes")
 public class WidgetItemsProperty extends WidgetDelegatingListProperty {
 	private IListProperty cCombo;
 	private IListProperty combo;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetListener.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetListener.java
index 6fb036a..7870690 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetListener.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetListener.java
@@ -13,6 +13,7 @@
 
 package org.eclipse.jface.internal.databinding.swt;
 
+import org.eclipse.core.databinding.observable.IDiff;
 import org.eclipse.core.databinding.property.IProperty;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.NativePropertyListener;
@@ -22,9 +23,12 @@
 import org.eclipse.swt.widgets.Widget;
 
 /**
+ * @param <S>
+ * @param <D>
  * @since 3.3
  */
-public class WidgetListener extends NativePropertyListener implements Listener {
+public class WidgetListener<S, D extends IDiff> extends
+		NativePropertyListener<S, D> implements Listener {
 	private final int[] changeEvents;
 	private final int[] staleEvents;
 
@@ -34,8 +38,9 @@
 	 * @param changeEvents
 	 * @param staleEvents
 	 */
-	public WidgetListener(IProperty property, ISimplePropertyListener listener,
-			int[] changeEvents, int[] staleEvents) {
+	public WidgetListener(IProperty property,
+			ISimplePropertyListener<D> listener, int[] changeEvents,
+			int[] staleEvents) {
 		super(property, listener);
 		this.changeEvents = changeEvents;
 		this.staleEvents = staleEvents;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMaximumProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMaximumProperty.java
index ee1d67e..10d443d 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMaximumProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMaximumProperty.java
@@ -18,8 +18,11 @@
 
 /**
  * @since 3.3
- * 
+ * @deprecated use static methods in WidgetProperties instead (the method names
+ *             will start with 'maximum')
  */
+// ok to ignore warnings in deprecated class
+@SuppressWarnings("rawtypes")
 public class WidgetMaximumProperty extends WidgetDelegatingValueProperty {
 	private IValueProperty scale;
 	private IValueProperty slider;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMessageProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMessageProperty.java
index 1352a61..cc6b4a1 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMessageProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMessageProperty.java
@@ -17,8 +17,11 @@
 
 /**
  * @since 3.3
- * 
+ * @deprecated use static methods in WidgetProperties instead (the method names
+ *             will start with 'message')
  */
+// ok to ignore warnings in deprecated class
+@SuppressWarnings("rawtypes")
 public class WidgetMessageProperty extends WidgetDelegatingValueProperty {
 	private IValueProperty text;
 	private IValueProperty toolTip;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMinimumProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMinimumProperty.java
index efa8539..4640532 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMinimumProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetMinimumProperty.java
@@ -18,8 +18,11 @@
 
 /**
  * @since 3.3
- * 
+ * @deprecated use static methods in WidgetProperties instead (the method names
+ *             will start with 'minimum')
  */
+// ok to ignore warnings in deprecated class
+@SuppressWarnings("rawtypes")
 public class WidgetMinimumProperty extends WidgetDelegatingValueProperty {
 	private IValueProperty scale;
 	private IValueProperty slider;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetSelectionProperty.java
index 7a5ca0d..6d0a42d 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetSelectionProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetSelectionProperty.java
@@ -25,8 +25,11 @@
 
 /**
  * @since 3.3
- * 
+ * @deprecated use static methods in WidgetProperties instead (the method names
+ *             will start with 'selection')
  */
+// ok to ignore warnings in deprecated class
+@SuppressWarnings("rawtypes")
 public final class WidgetSelectionProperty extends
 		WidgetDelegatingValueProperty {
 	private IValueProperty button;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetSingleSelectionIndexProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetSingleSelectionIndexProperty.java
index 22f32e5..5df93cd 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetSingleSelectionIndexProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetSingleSelectionIndexProperty.java
@@ -19,8 +19,11 @@
 
 /**
  * @since 3.3
- * 
+ * @deprecated use static methods in SelectionProviderProperties or
+ *             ViewerProperties instead
  */
+// ok to ignore warnings in deprecated class
+@SuppressWarnings("rawtypes")
 public final class WidgetSingleSelectionIndexProperty extends
 		WidgetDelegatingValueProperty {
 	private IValueProperty cCombo;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetStringValueProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetStringValueProperty.java
index 241256f..4cad0a9 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetStringValueProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetStringValueProperty.java
@@ -13,12 +13,17 @@
 package org.eclipse.jface.internal.databinding.swt;
 
 import org.eclipse.jface.databinding.swt.WidgetValueProperty;
+import org.eclipse.swt.widgets.Widget;
 
 /**
+ * @param <S>
+ *            type of the source control (the control that contains this
+ *            property)
  * @since 3.3
  * 
  */
-public abstract class WidgetStringValueProperty extends WidgetValueProperty {
+public abstract class WidgetStringValueProperty<S extends Widget> extends
+		WidgetValueProperty<S, String> {
 	WidgetStringValueProperty() {
 		super();
 	}
@@ -38,16 +43,4 @@
 	public Object getValueType() {
 		return String.class;
 	}
-
-	protected Object doGetValue(Object source) {
-		return doGetStringValue(source);
-	}
-
-	protected void doSetValue(Object source, Object value) {
-		doSetStringValue(source, (String) value);
-	}
-
-	abstract String doGetStringValue(Object source);
-
-	abstract void doSetStringValue(Object source, String value);
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTextProperty.java
index 51d0189..0211171 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTextProperty.java
@@ -25,8 +25,11 @@
 
 /**
  * @since 3.3
- * 
+ * @deprecated use static methods in WidgetProperties instead (the method names
+ *             will start with 'text')
  */
+// ok to ignore warnings in deprecated class
+@SuppressWarnings("rawtypes")
 public class WidgetTextProperty extends WidgetDelegatingValueProperty {
 	private IValueProperty button;
 	private IValueProperty cCombo;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTextWithEventsProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTextWithEventsProperty.java
index 0dd91df..46e681f 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTextWithEventsProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTextWithEventsProperty.java
@@ -18,8 +18,11 @@
 
 /**
  * @since 3.3
- * 
+ * @deprecated use static methods in WidgetProperties instead (the method names
+ *             will start with 'text')
  */
+// ok to ignore warnings in deprecated class
+@SuppressWarnings("rawtypes")
 public class WidgetTextWithEventsProperty extends WidgetDelegatingValueProperty {
 	private final int[] events;
 
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTooltipTextProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTooltipTextProperty.java
index 6ebb7e0..a2cad24 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTooltipTextProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/swt/WidgetTooltipTextProperty.java
@@ -22,8 +22,11 @@
 
 /**
  * @since 3.3
- * 
+ * @deprecated use static methods in WidgetProperties instead (the method names
+ *             will start with 'tooltip')
  */
+// ok to ignore warnings in deprecated class
+@SuppressWarnings("rawtypes")
 public class WidgetTooltipTextProperty extends WidgetDelegatingValueProperty {
 	private IValueProperty cTabItem;
 	private IValueProperty control;
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/util/JFaceProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/util/JFaceProperty.java
index 3a16be3..803d873 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/util/JFaceProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/util/JFaceProperty.java
@@ -15,6 +15,7 @@
 import java.lang.reflect.Method;
 
 import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.ValueDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.NativePropertyListener;
@@ -26,10 +27,13 @@
  * Class that supports the use of {@link IObservableValue} with objects that
  * follow standard bean method naming conventions but notify an
  * {@link IPropertyChangeListener} when the property changes.
+ * 
+ * @param <S>
+ * @param <T>
  */
-public class JFaceProperty extends SimpleValueProperty {
+public class JFaceProperty<S, T> extends SimpleValueProperty<S, T> {
 
-	private Class returnType;
+	private Class<T> returnType;
 	private Method setterMethod;
 	private Method getterMethod;
 	private final String property;
@@ -56,9 +60,9 @@
 		return fieldName;
 	}
 
-	class Listener extends NativePropertyListener implements
+	class Listener extends NativePropertyListener<S, ValueDiff<T>> implements
 			IPropertyChangeListener {
-		public Listener(ISimplePropertyListener listener) {
+		public Listener(ISimplePropertyListener<ValueDiff<T>> listener) {
 			super(JFaceProperty.this, listener);
 		}
 
@@ -103,7 +107,7 @@
 				String getterName = getBooleanGetterName(fieldName);
 				getterMethod = clazz.getMethod(getterName, new Class[] {});
 			}
-			returnType = getterMethod.getReturnType();
+			returnType = (Class<T>) getterMethod.getReturnType();
 			setterMethod = clazz.getMethod(getSetterName(fieldName),
 					new Class[] { returnType });
 			addPropertyListenerMethod = clazz
@@ -119,14 +123,14 @@
 		}
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<S> adaptListener(
+			ISimplePropertyListener<ValueDiff<T>> listener) {
 		return new Listener(listener);
 	}
 
-	protected Object doGetValue(Object model) {
+	protected T doGetValue(S model) {
 		try {
-			return getterMethod.invoke(model, new Object[] {});
+			return (T) getterMethod.invoke(model, new Object[] {});
 		} catch (InvocationTargetException e) {
 			throw new IllegalStateException(e.getMessage());
 		} catch (IllegalAccessException e) {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CellEditorControlProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CellEditorControlProperty.java
index a56611b..c198a68 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CellEditorControlProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CellEditorControlProperty.java
@@ -11,6 +11,7 @@
 
 package org.eclipse.jface.internal.databinding.viewers;
 
+import org.eclipse.core.databinding.observable.value.ValueDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.value.SimpleValueProperty;
@@ -21,21 +22,22 @@
  * @since 3.3
  * 
  */
-public class CellEditorControlProperty extends SimpleValueProperty {
+public class CellEditorControlProperty extends
+		SimpleValueProperty<CellEditor, Control> {
 	public Object getValueType() {
 		return Control.class;
 	}
 
-	protected Object doGetValue(Object source) {
-		return ((CellEditor) source).getControl();
+	protected Control doGetValue(CellEditor source) {
+		return source.getControl();
 	}
 
-	protected void doSetValue(Object source, Object value) {
+	protected void doSetValue(CellEditor source, Control value) {
 		throw new UnsupportedOperationException();
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<CellEditor> adaptListener(
+			ISimplePropertyListener<ValueDiff<Control>> listener) {
 		return null;
 	}
 
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckableCheckedElementsObservableSet.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckableCheckedElementsObservableSet.java
index 09a29fa..d888f50 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckableCheckedElementsObservableSet.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckableCheckedElementsObservableSet.java
@@ -31,9 +31,9 @@
  * @since 1.2
  */
 public class CheckableCheckedElementsObservableSet extends
-		AbstractObservableSet {
+		AbstractObservableSet<Object> {
 	private ICheckable checkable;
-	private Set wrappedSet;
+	private Set<Object> wrappedSet;
 	private Object elementType;
 	private IElementComparer elementComparer;
 	private ICheckStateListener listener;
@@ -53,7 +53,7 @@
 	 *            the ICheckable to track
 	 */
 	public CheckableCheckedElementsObservableSet(Realm realm,
-			final Set wrappedSet, Object elementType,
+			final Set<Object> wrappedSet, Object elementType,
 			IElementComparer elementComparer, ICheckable checkable) {
 		super(realm);
 		Assert.isNotNull(checkable, "Checkable cannot be null"); //$NON-NLS-1$
@@ -68,24 +68,25 @@
 				Object element = event.getElement();
 				if (event.getChecked()) {
 					if (wrappedSet.add(element))
-						fireSetChange(Diffs.createSetDiff(Collections
-								.singleton(element), Collections.EMPTY_SET));
+						fireSetChange(Diffs.createSetDiff(
+								Collections.singleton(element),
+								Collections.<Object> emptySet()));
 				} else {
 					if (wrappedSet.remove(element))
 						fireSetChange(Diffs.createSetDiff(
-								Collections.EMPTY_SET, Collections
-										.singleton(element)));
+								Collections.<Object> emptySet(),
+								Collections.singleton(element)));
 				}
 			}
 		};
 		checkable.addCheckStateListener(listener);
 	}
 
-	protected Set getWrappedSet() {
+	protected Set<Object> getWrappedSet() {
 		return wrappedSet;
 	}
 
-	Set createDiffSet() {
+	Set<Object> createDiffSet() {
 		return ViewerElementSet.withComparer(elementComparer);
 	}
 
@@ -93,13 +94,17 @@
 		return elementType;
 	}
 
+	public Class<Object> getElementClass() {
+		return Object.class;
+	}
+
 	public boolean add(Object o) {
 		getterCalled();
 		boolean added = wrappedSet.add(o);
 		if (added) {
 			checkable.setChecked(o, true);
 			fireSetChange(Diffs.createSetDiff(Collections.singleton(o),
-					Collections.EMPTY_SET));
+					Collections.<Object> emptySet()));
 		}
 		return added;
 	}
@@ -109,16 +114,17 @@
 		boolean removed = wrappedSet.remove(o);
 		if (removed) {
 			checkable.setChecked(o, false);
-			fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET,
+			fireSetChange(Diffs.createSetDiff(Collections.<Object> emptySet(),
 					Collections.singleton(o)));
 		}
 		return removed;
 	}
 
-	public boolean addAll(Collection c) {
+	public boolean addAll(Collection<? extends Object> c) {
 		getterCalled();
-		Set additions = createDiffSet();
-		for (Iterator iterator = c.iterator(); iterator.hasNext();) {
+		Set<Object> additions = createDiffSet();
+		for (Iterator<? extends Object> iterator = c.iterator(); iterator
+				.hasNext();) {
 			Object element = iterator.next();
 			if (wrappedSet.add(element)) {
 				checkable.setChecked(element, true);
@@ -127,14 +133,15 @@
 		}
 		boolean changed = !additions.isEmpty();
 		if (changed)
-			fireSetChange(Diffs.createSetDiff(additions, Collections.EMPTY_SET));
+			fireSetChange(Diffs
+					.createSetDiff(additions, Collections.emptySet()));
 		return changed;
 	}
 
-	public boolean removeAll(Collection c) {
+	public boolean removeAll(Collection<?> c) {
 		getterCalled();
-		Set removals = createDiffSet();
-		for (Iterator iterator = c.iterator(); iterator.hasNext();) {
+		Set<Object> removals = createDiffSet();
+		for (Iterator<?> iterator = c.iterator(); iterator.hasNext();) {
 			Object element = iterator.next();
 			if (wrappedSet.remove(element)) {
 				checkable.setChecked(element, false);
@@ -143,19 +150,20 @@
 		}
 		boolean changed = !removals.isEmpty();
 		if (changed)
-			fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET, removals));
+			fireSetChange(Diffs.createSetDiff(Collections.emptySet(), removals));
 		return changed;
 	}
 
-	public boolean retainAll(Collection c) {
+	public boolean retainAll(Collection<?> c) {
 		getterCalled();
 
 		// To ensure that elements are compared correctly, e.g. ViewerElementSet
-		Set toRetain = createDiffSet();
+		Set<Object> toRetain = createDiffSet();
 		toRetain.addAll(c);
 
-		Set removals = createDiffSet();
-		for (Iterator iterator = wrappedSet.iterator(); iterator.hasNext();) {
+		Set<Object> removals = createDiffSet();
+		for (Iterator<Object> iterator = wrappedSet.iterator(); iterator
+				.hasNext();) {
 			Object element = iterator.next();
 			if (!toRetain.contains(element)) {
 				iterator.remove();
@@ -165,21 +173,21 @@
 		}
 		boolean changed = !removals.isEmpty();
 		if (changed)
-			fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET, removals));
+			fireSetChange(Diffs.createSetDiff(Collections.emptySet(), removals));
 		return changed;
 	}
 
 	public void clear() {
 		getterCalled();
-		Set removals = createDiffSet();
+		Set<Object> removals = createDiffSet();
 		removals.addAll(wrappedSet);
 		removeAll(removals);
 	}
 
-	public Iterator iterator() {
+	public Iterator<Object> iterator() {
 		getterCalled();
-		final Iterator wrappedIterator = wrappedSet.iterator();
-		return new Iterator() {
+		final Iterator<Object> wrappedIterator = wrappedSet.iterator();
+		return new Iterator<Object>() {
 			private Object last = null;
 
 			public boolean hasNext() {
@@ -196,7 +204,7 @@
 				getterCalled();
 				wrappedIterator.remove();
 				checkable.setChecked(last, false);
-				fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET,
+				fireSetChange(Diffs.createSetDiff(Collections.emptySet(),
 						Collections.singleton(last)));
 			}
 		};
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckableCheckedElementsProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckableCheckedElementsProperty.java
index dedb0c1..264f987 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckableCheckedElementsProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckableCheckedElementsProperty.java
@@ -29,7 +29,8 @@
  * @since 3.3
  * 
  */
-public class CheckableCheckedElementsProperty extends SetProperty {
+public class CheckableCheckedElementsProperty extends
+		SetProperty<ICheckable, Object> {
 	private final Object elementType;
 
 	/**
@@ -43,26 +44,30 @@
 		return elementType;
 	}
 
-	protected Set doGetSet(Object source) {
+	public Class<Object> getElementClass() {
+		return Object.class;
+	}
+
+	protected Set<Object> doGetSet(ICheckable source) {
 		throw new UnsupportedOperationException(
 				"Cannot query the checked elements on an ICheckable"); //$NON-NLS-1$
 	}
 
-	protected void doSetSet(Object source, Set set) {
+	protected void doSetSet(ICheckable source, Set<Object> set) {
 		throw new UnsupportedOperationException(
 				"Cannot batch replace the checked elements on an ICheckable.  " + //$NON-NLS-1$
 						"Use updateSet(SetDiff) instead"); //$NON-NLS-1$
 	}
 
-	protected void doUpdateSet(Object source, SetDiff diff) {
-		ICheckable checkable = (ICheckable) source;
-		for (Iterator it = diff.getAdditions().iterator(); it.hasNext();)
+	protected void doUpdateSet(ICheckable source, SetDiff<Object> diff) {
+		ICheckable checkable = source;
+		for (Iterator<Object> it = diff.getAdditions().iterator(); it.hasNext();)
 			checkable.setChecked(it.next(), true);
-		for (Iterator it = diff.getRemovals().iterator(); it.hasNext();)
+		for (Iterator<Object> it = diff.getRemovals().iterator(); it.hasNext();)
 			checkable.setChecked(it.next(), false);
 	}
 
-	public IObservableSet observe(Object source) {
+	public IObservableSet<Object> observe(ICheckable source) {
 		if (source instanceof Viewer) {
 			return observe(SWTObservables.getRealm(((Viewer) source)
 					.getControl().getDisplay()), source);
@@ -70,16 +75,16 @@
 		return super.observe(source);
 	}
 
-	public IObservableSet observe(Realm realm, Object source) {
+	public IObservableSet<Object> observe(Realm realm, ICheckable source) {
 		IElementComparer comparer = null;
 		if (source instanceof StructuredViewer)
 			comparer = ((StructuredViewer) source).getComparer();
-		Set wrappedSet = ViewerElementSet.withComparer(comparer);
-		IObservableSet observable = new CheckableCheckedElementsObservableSet(
-				realm, wrappedSet, elementType, comparer, (ICheckable) source);
+		Set<Object> wrappedSet = ViewerElementSet.withComparer(comparer);
+		IObservableSet<Object> observable = new CheckableCheckedElementsObservableSet(
+				realm, wrappedSet, elementType, comparer, source);
 		if (source instanceof Viewer)
-			observable = new ViewerObservableSetDecorator(observable,
-					(Viewer) source);
+			observable = new ViewerObservableSetDecorator<Viewer, Object>(
+					observable, (Viewer) source);
 		return observable;
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxTableViewerCheckedElementsProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxTableViewerCheckedElementsProperty.java
index 786fac2..1f90c91 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxTableViewerCheckedElementsProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxTableViewerCheckedElementsProperty.java
@@ -23,7 +23,7 @@
  * 
  */
 public class CheckboxTableViewerCheckedElementsProperty extends
-		CheckboxViewerCheckedElementsProperty {
+		CheckboxViewerCheckedElementsProperty<CheckboxTableViewer> {
 	/**
 	 * @param elementType
 	 */
@@ -31,20 +31,19 @@
 		super(elementType);
 	}
 
-	protected Set doGetSet(Object source) {
-		CheckboxTableViewer viewer = (CheckboxTableViewer) source;
-		Set set = createElementSet(viewer);
-		set.addAll(Arrays.asList(viewer.getCheckedElements()));
+	protected Set<Object> doGetSet(CheckboxTableViewer source) {
+		Set<Object> set = createElementSet(source);
+		set.addAll(Arrays.asList(source.getCheckedElements()));
 		return set;
 	}
 
-	protected void doSetSet(Object source, Set set, SetDiff diff) {
+	protected void doSetSet(CheckboxTableViewer source, Set<Object> set,
+			SetDiff<Object> diff) {
 		doSetSet(source, set);
 	}
 
-	protected void doSetSet(Object source, Set set) {
-		CheckboxTableViewer viewer = (CheckboxTableViewer) source;
-		viewer.setCheckedElements(set.toArray());
+	protected void doSetSet(CheckboxTableViewer source, Set<Object> set) {
+		source.setCheckedElements(set.toArray());
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxTreeViewerCheckedElementsProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxTreeViewerCheckedElementsProperty.java
index c54268c..fe6428f 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxTreeViewerCheckedElementsProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxTreeViewerCheckedElementsProperty.java
@@ -23,7 +23,7 @@
  * 
  */
 public class CheckboxTreeViewerCheckedElementsProperty extends
-		CheckboxViewerCheckedElementsProperty {
+		CheckboxViewerCheckedElementsProperty<CheckboxTreeViewer> {
 	/**
 	 * @param elementType
 	 */
@@ -31,20 +31,19 @@
 		super(elementType);
 	}
 
-	protected Set doGetSet(Object source) {
-		CheckboxTreeViewer viewer = (CheckboxTreeViewer) source;
-		Set set = createElementSet(viewer);
-		set.addAll(Arrays.asList(viewer.getCheckedElements()));
+	protected Set<Object> doGetSet(CheckboxTreeViewer source) {
+		Set<Object> set = createElementSet(source);
+		set.addAll(Arrays.asList(source.getCheckedElements()));
 		return set;
 	}
 
-	protected void doSetSet(Object source, Set set, SetDiff diff) {
+	protected void doSetSet(CheckboxTreeViewer source, Set<Object> set,
+			SetDiff<Object> diff) {
 		doSetSet(source, set);
 	}
 
-	protected void doSetSet(Object source, Set set) {
-		CheckboxTreeViewer viewer = (CheckboxTreeViewer) source;
-		viewer.setCheckedElements(set.toArray());
+	protected void doSetSet(CheckboxTreeViewer source, Set<Object> set) {
+		source.setCheckedElements(set.toArray());
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxViewerCheckedElementsProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxViewerCheckedElementsProperty.java
index afb1c3e..af62f9f 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxViewerCheckedElementsProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/CheckboxViewerCheckedElementsProperty.java
@@ -27,13 +27,15 @@
 import org.eclipse.jface.viewers.ICheckStateListener;
 import org.eclipse.jface.viewers.ICheckable;
 import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
 
 /**
+ * @param <S>
  * @since 3.3
  * 
  */
-public abstract class CheckboxViewerCheckedElementsProperty extends
-		ViewerSetProperty {
+public abstract class CheckboxViewerCheckedElementsProperty<S extends Viewer>
+		extends ViewerSetProperty<S, Object> {
 	private final Object elementType;
 
 	/**
@@ -47,47 +49,54 @@
 		return elementType;
 	}
 
-	protected final Set createElementSet(StructuredViewer viewer) {
+	public Class<Object> getElementClass() {
+		return Object.class;
+	}
+
+	protected final Set<Object> createElementSet(StructuredViewer viewer) {
 		return ViewerElementSet.withComparer(viewer.getComparer());
 	}
 
-	protected void doUpdateSet(Object source, SetDiff diff) {
+	protected void doUpdateSet(S source, SetDiff<Object> diff) {
 		ICheckable checkable = (ICheckable) source;
-		for (Iterator it = diff.getAdditions().iterator(); it.hasNext();)
+		for (Iterator<Object> it = diff.getAdditions().iterator(); it.hasNext();)
 			checkable.setChecked(it.next(), true);
-		for (Iterator it = diff.getRemovals().iterator(); it.hasNext();)
+		for (Iterator<Object> it = diff.getRemovals().iterator(); it.hasNext();)
 			checkable.setChecked(it.next(), false);
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<S> adaptListener(
+			ISimplePropertyListener<SetDiff<Object>> listener) {
 		return new CheckStateListener(this, listener);
 	}
 
-	private class CheckStateListener extends NativePropertyListener implements
+	private class CheckStateListener extends
+			NativePropertyListener<S, SetDiff<Object>> implements
 			ICheckStateListener {
 		private CheckStateListener(IProperty property,
-				ISimplePropertyListener listener) {
+				ISimplePropertyListener<SetDiff<Object>> listener) {
 			super(property, listener);
 		}
 
 		public void checkStateChanged(CheckStateChangedEvent event) {
 			Object element = event.getElement();
 			boolean checked = event.getChecked();
-			Set elementSet = createElementSet((StructuredViewer) event
+			Set<Object> elementSet = createElementSet((StructuredViewer) event
 					.getCheckable());
 			elementSet.add(element);
-			Set additions = checked ? elementSet : Collections.EMPTY_SET;
-			Set removals = checked ? Collections.EMPTY_SET : elementSet;
-			SetDiff diff = Diffs.createSetDiff(additions, removals);
+			Set<Object> additions = checked ? elementSet : Collections
+					.emptySet();
+			Set<Object> removals = checked ? Collections.emptySet()
+					: elementSet;
+			SetDiff<Object> diff = Diffs.createSetDiff(additions, removals);
 			fireChange(event.getSource(), diff);
 		}
 
-		public void doAddTo(Object source) {
+		public void doAddTo(S source) {
 			((ICheckable) source).addCheckStateListener(this);
 		}
 
-		public void doRemoveFrom(Object source) {
+		public void doRemoveFrom(S source) {
 			((ICheckable) source).removeCheckStateListener(this);
 		}
 	}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableCollectionContentProvider.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableCollectionContentProvider.java
index a98b17b..4089632 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableCollectionContentProvider.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableCollectionContentProvider.java
@@ -13,7 +13,6 @@
 
 package org.eclipse.jface.internal.databinding.viewers;
 
-import org.eclipse.core.databinding.observable.IObservable;
 import org.eclipse.core.databinding.observable.IObservableCollection;
 import org.eclipse.core.databinding.observable.Observables;
 import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
@@ -43,14 +42,14 @@
 		IStructuredContentProvider {
 	private Display display;
 
-	private IObservableValue viewerObservable;
+	private IObservableValue<Viewer> viewerObservable;
 
 	/**
 	 * Element comparer used by the viewer (may be null).
 	 */
 	protected IElementComparer comparer;
 
-	private IObservableFactory elementSetFactory;
+	private IObservableFactory<Viewer, IObservableSet<Object>> elementSetFactory;
 
 	private final IViewerUpdater explicitViewerUpdater;
 
@@ -65,8 +64,8 @@
 	 * viewer, and must remove old elements from this set <b>after</b> removing
 	 * them from the viewer.
 	 */
-	protected IObservableSet knownElements;
-	private IObservableSet unmodifiableKnownElements;
+	protected IObservableSet<Object> knownElements;
+	private IObservableSet<Object> unmodifiableKnownElements;
 
 	/**
 	 * Observable set of known elements which have been realized in the viewer.
@@ -74,10 +73,10 @@
 	 * the viewer, and must remove old elements from this set <b>before</b>
 	 * removing them from the viewer.
 	 */
-	protected IObservableSet realizedElements;
-	private IObservableSet unmodifiableRealizedElements;
+	protected IObservableSet<Object> realizedElements;
+	private IObservableSet<Object> unmodifiableRealizedElements;
 
-	private IObservableCollection observableCollection;
+	private IObservableCollection<?> observableCollection;
 
 	/**
 	 * Constructs an ObservableCollectionContentProvider
@@ -89,16 +88,17 @@
 		this.explicitViewerUpdater = explicitViewerUpdater;
 
 		display = Display.getDefault();
-		viewerObservable = new WritableValue(SWTObservables.getRealm(display));
+		viewerObservable = new WritableValue<Viewer>(
+				SWTObservables.getRealm(display));
 		viewerUpdater = null;
 
-		elementSetFactory = new IObservableFactory() {
-			public IObservable createObservable(Object target) {
+		elementSetFactory = new IObservableFactory<Viewer, IObservableSet<Object>>() {
+			public IObservableSet<Object> createObservable(Viewer target) {
 				IElementComparer comparer = null;
 				if (target instanceof StructuredViewer)
 					comparer = ((StructuredViewer) target).getComparer();
-				return ObservableViewerElementSet.withComparer(SWTObservables
-						.getRealm(display), null, comparer);
+				return ObservableViewerElementSet.<Object> withComparer(
+						SWTObservables.getRealm(display), null, comparer);
 			}
 		};
 		knownElements = MasterDetailObservables.detailSet(viewerObservable,
@@ -195,7 +195,7 @@
 			checkInput(input);
 			Assert.isTrue(input instanceof IObservableCollection,
 					"Input must be an IObservableCollection"); //$NON-NLS-1$
-			observableCollection = (IObservableCollection) input;
+			observableCollection = (IObservableCollection<?>) input;
 			addCollectionChangeListener(observableCollection);
 		}
 	}
@@ -215,7 +215,7 @@
 	 *            observable collection to listen to
 	 */
 	protected abstract void addCollectionChangeListener(
-			IObservableCollection collection);
+			IObservableCollection<?> collection);
 
 	/**
 	 * Deregisters from change events notification on the given collection.
@@ -224,7 +224,7 @@
 	 *            observable collection to stop listening to
 	 */
 	protected abstract void removeCollectionChangeListener(
-			IObservableCollection collection);
+			IObservableCollection<?> collection);
 
 	/**
 	 * Returns whether the viewer is disposed. Collection change listeners in
@@ -234,7 +234,7 @@
 	 * @return whether the viewer is disposed.
 	 */
 	protected final boolean isViewerDisposed() {
-		Viewer viewer = (Viewer) viewerObservable.getValue();
+		Viewer viewer = viewerObservable.getValue();
 		return viewer == null || viewer.getControl() == null
 				|| viewer.getControl().isDisposed();
 	}
@@ -248,7 +248,7 @@
 	 * 
 	 * @return unmodifiable observable set of items that will need labels
 	 */
-	public IObservableSet getKnownElements() {
+	public IObservableSet<Object> getKnownElements() {
 		return unmodifiableKnownElements;
 	}
 
@@ -260,7 +260,7 @@
 	 * @return the set of known elements which have been realized in the viewer.
 	 * @since 1.3
 	 */
-	public IObservableSet getRealizedElements() {
+	public IObservableSet<Object> getRealizedElements() {
 		if (realizedElements == null) {
 			realizedElements = MasterDetailObservables.detailSet(
 					viewerObservable, elementSetFactory, null);
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableCollectionTreeContentProvider.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableCollectionTreeContentProvider.java
index aea0b53..384a7a8 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableCollectionTreeContentProvider.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableCollectionTreeContentProvider.java
@@ -19,7 +19,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.eclipse.core.databinding.observable.IObservable;
 import org.eclipse.core.databinding.observable.IObservableCollection;
 import org.eclipse.core.databinding.observable.IObservablesListener;
 import org.eclipse.core.databinding.observable.Observables;
@@ -55,14 +54,14 @@
 
 	private Display display;
 
-	private IObservableValue viewerObservable;
+	private IObservableValue<Viewer> viewerObservable;
 
 	/**
 	 * Element comparer used by the viewer (may be null).
 	 */
 	protected IElementComparer comparer;
 
-	private IObservableFactory elementSetFactory;
+	private IObservableFactory<Object, IObservableSet<Object>> elementSetFactory;
 
 	/**
 	 * Interfaces for sending updates to the viewer.
@@ -75,8 +74,8 @@
 	 * viewer, and must remove old elements from this set <b>after</b> removing
 	 * them from the viewer.
 	 */
-	protected IObservableSet knownElements;
-	private IObservableSet unmodifiableKnownElements;
+	protected IObservableSet<Object> knownElements;
+	private IObservableSet<Object> unmodifiableKnownElements;
 
 	/**
 	 * Observable set of known elements which have been realized in the viewer.
@@ -84,12 +83,12 @@
 	 * the viewer, and must remove old elements from this set <b>before</b>
 	 * removing them from the viewer.
 	 */
-	protected IObservableSet realizedElements;
-	private IObservableSet unmodifiableRealizedElements;
+	protected IObservableSet<Object> realizedElements;
+	private IObservableSet<Object> unmodifiableRealizedElements;
 
-	private IObservableFactory /* <IObservableCollection> */collectionFactory;
+	private IObservableFactory<Object, ? extends IObservableCollection<Object>> collectionFactory;
 
-	private Map /* <Object element, TreeNode node> */elementNodes;
+	private Map<Object, TreeNode> elementNodes;
 
 	private TreeStructureAdvisor structureAdvisor;
 
@@ -103,16 +102,16 @@
 	 * @param structureAdvisor
 	 */
 	protected ObservableCollectionTreeContentProvider(
-			IObservableFactory collectionFactory,
+			IObservableFactory<Object, ? extends IObservableCollection<Object>> collectionFactory,
 			TreeStructureAdvisor structureAdvisor) {
 		this.structureAdvisor = structureAdvisor;
 		display = Display.getDefault();
 		realm = SWTObservables.getRealm(display);
-		viewerObservable = new WritableValue(realm);
+		viewerObservable = new WritableValue<Viewer>(realm);
 		viewerUpdater = null;
 
-		elementSetFactory = new IObservableFactory() {
-			public IObservable createObservable(Object target) {
+		elementSetFactory = new IObservableFactory<Object, IObservableSet<Object>>() {
+			public IObservableSet<Object> createObservable(Object target) {
 				return ObservableViewerElementSet.withComparer(realm, null,
 						getElementComparer((Viewer) target));
 			}
@@ -122,9 +121,7 @@
 		unmodifiableKnownElements = Observables
 				.unmodifiableObservableSet(knownElements);
 
-		Assert
-				.isNotNull(collectionFactory,
-						"Collection factory cannot be null"); //$NON-NLS-1$
+		Assert.isNotNull(collectionFactory, "Collection factory cannot be null"); //$NON-NLS-1$
 		this.collectionFactory = collectionFactory;
 	}
 
@@ -149,7 +146,7 @@
 	private void setViewer(Viewer viewer) {
 		viewerUpdater = createViewerUpdater(viewer);
 		comparer = getElementComparer(viewer);
-		elementNodes = ViewerElementMap.withComparer(comparer);
+		elementNodes = ViewerElementMap.<Object> withComparer(comparer);
 		viewerObservable.setValue(viewer); // (clears knownElements)
 	}
 
@@ -250,12 +247,12 @@
 	}
 
 	protected TreeNode getExistingNode(Object element) {
-		TreeNode node = (TreeNode) elementNodes.get(element);
+		TreeNode node = elementNodes.get(element);
 		return node;
 	}
 
 	protected boolean isViewerDisposed() {
-		Viewer viewer = (Viewer) viewerObservable.getValue();
+		Viewer viewer = viewerObservable.getValue();
 		return viewer == null || viewer.getControl() == null
 				|| viewer.getControl().isDisposed();
 	}
@@ -293,7 +290,7 @@
 	 * 
 	 * @return unmodifiable observable set of items that will need labels
 	 */
-	public IObservableSet getKnownElements() {
+	public IObservableSet<Object> getKnownElements() {
 		return unmodifiableKnownElements;
 	}
 
@@ -305,7 +302,7 @@
 	 * @return the set of known elements which have been realized in the viewer.
 	 * @since 1.3
 	 */
-	public IObservableSet getRealizedElements() {
+	public IObservableSet<Object> getRealizedElements() {
 		if (realizedElements == null) {
 			realizedElements = MasterDetailObservables.detailSet(
 					viewerObservable, elementSetFactory, null);
@@ -328,25 +325,25 @@
 	 * @return the set of all elements that would be removed from the known
 	 *         elements set
 	 */
-	protected Set findPendingRemovals(Object parent,
-			Collection elementsToBeRemoved) {
-		Set result = ViewerElementSet.withComparer(comparer);
-		Set parents = ViewerElementSet.withComparer(comparer);
+	protected Set<Object> findPendingRemovals(Object parent,
+			Collection<Object> elementsToBeRemoved) {
+		Set<Object> result = ViewerElementSet.withComparer(comparer);
+		Set<Object> parents = ViewerElementSet.withComparer(comparer);
 		parents.add(parent);
 		accumulatePendingRemovals(result, parents, elementsToBeRemoved);
 		return result;
 	}
 
-	private void accumulatePendingRemovals(Set removals, Set parents,
-			Collection elementsToRemove) {
-		for (Iterator it = elementsToRemove.iterator(); it.hasNext();) {
+	private void accumulatePendingRemovals(Set<Object> removals,
+			Set<Object> parents, Collection<Object> elementsToRemove) {
+		for (Iterator<Object> it = elementsToRemove.iterator(); it.hasNext();) {
 			Object element = it.next();
 			TreeNode node = getExistingNode(element);
 			if (node != null) {
 				if (parents.containsAll(node.getParents())) {
 					removals.add(element);
 					parents.add(element);
-					Collection children = node.getChildren();
+					Collection<Object> children = node.getChildren();
 					accumulatePendingRemovals(removals, parents, children);
 				}
 			}
@@ -376,7 +373,8 @@
 	 *            the listener that will receive collection change events.
 	 */
 	protected abstract void addCollectionChangeListener(
-			IObservableCollection collection, IObservablesListener listener);
+			IObservableCollection<Object> collection,
+			IObservablesListener listener);
 
 	/**
 	 * Unregisters the change listener from receving change events for the
@@ -388,7 +386,8 @@
 	 *            the listener to remove
 	 */
 	protected abstract void removeCollectionChangeListener(
-			IObservableCollection collection, IObservablesListener listener);
+			IObservableCollection<Object> collection,
+			IObservablesListener listener);
 
 	protected boolean equal(Object left, Object right) {
 		if (comparer == null)
@@ -400,9 +399,9 @@
 		private Object element;
 
 		private Object parent;
-		private Set parentSet;
+		private Set<Object> parentSet;
 
-		private IObservableCollection children;
+		private IObservableCollection<Object> children;
 
 		private IObservablesListener listener;
 
@@ -451,25 +450,23 @@
 			return parent;
 		}
 
-		public Set getParents() {
+		public Set<Object> getParents() {
 			if (parentSet != null)
 				return parentSet;
 			if (parent != null)
 				return Collections.singleton(parent);
-			return Collections.EMPTY_SET;
+			return Collections.emptySet();
 		}
 
 		private void initChildren() {
 			if (children == null) {
-				children = (IObservableCollection) collectionFactory
-						.createObservable(element);
+				children = collectionFactory.createObservable(element);
 				if (children == null) {
 					listener = null;
 					children = Observables.emptyObservableSet(realm);
 				} else {
-					Assert
-							.isTrue(Util.equals(realm, children.getRealm()),
-									"Children observable collection must be on the Display realm"); //$NON-NLS-1$
+					Assert.isTrue(Util.equals(realm, children.getRealm()),
+							"Children observable collection must be on the Display realm"); //$NON-NLS-1$
 					listener = createCollectionChangeListener(element);
 					addCollectionChangeListener(children, listener);
 				}
@@ -481,7 +478,7 @@
 			return !children.isEmpty();
 		}
 
-		public Collection getChildren() {
+		public Collection<Object> getChildren() {
 			initChildren();
 			return children;
 		}
@@ -491,7 +488,7 @@
 				elementNodes.remove(element);
 			}
 			if (children != null && !children.isDisposed()) {
-				for (Iterator iterator = children.iterator(); iterator
+				for (Iterator<Object> iterator = children.iterator(); iterator
 						.hasNext();) {
 					TreeNode child = getExistingNode(iterator.next());
 					if (child != null)
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableViewerElementSet.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableViewerElementSet.java
index 2f8b197..0db7b71 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableViewerElementSet.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ObservableViewerElementSet.java
@@ -27,8 +27,8 @@
 import org.eclipse.jface.viewers.StructuredViewer;
 
 /**
- * An {@link IObservableSet} of elements in a {@link StructuredViewer}.
- * Elements of the set are compared using an {@link IElementComparer} instead of
+ * An {@link IObservableSet} of elements in a {@link StructuredViewer}. Elements
+ * of the set are compared using an {@link IElementComparer} instead of
  * {@link #equals(Object)}.
  * <p>
  * This class is <i>not</i> a strict implementation the {@link IObservableSet}
@@ -37,12 +37,15 @@
  * designed for use with {@link StructuredViewer} which uses
  * {@link IElementComparer} for element comparisons.
  * 
+ * @param <E>
+ * 
  * 
  * @since 1.2
  */
-public class ObservableViewerElementSet extends AbstractObservableSet {
-	private Set wrappedSet;
-	private Object elementType;
+public class ObservableViewerElementSet<E> extends AbstractObservableSet<E> {
+	private Set<E> wrappedSet;
+	private Object elementTypeAsObject;
+	private Class<E> elementType;
 	private IElementComparer comparer;
 
 	/**
@@ -55,37 +58,66 @@
 	 *            the element type of the constructed set.
 	 * @param comparer
 	 *            the {@link IElementComparer} used to compare elements.
+	 * @deprecated use the form of the constructor that takes a Class object as
+	 *             the elementType parameter
 	 */
 	public ObservableViewerElementSet(Realm realm, Object elementType,
 			IElementComparer comparer) {
 		super(realm);
 
 		Assert.isNotNull(comparer);
-		this.wrappedSet = new ViewerElementSet(comparer);
+		this.wrappedSet = new ViewerElementSet<E>(comparer);
+		this.elementTypeAsObject = elementType;
+		this.elementType = null;
+		this.comparer = comparer;
+	}
+
+	/**
+	 * Constructs an ObservableViewerElementSet on the given {@link Realm} which
+	 * uses the given {@link IElementComparer} to compare elements.
+	 * 
+	 * @param realm
+	 *            the realm of the constructed set.
+	 * @param elementType
+	 *            the element type of the constructed set.
+	 * @param comparer
+	 *            the {@link IElementComparer} used to compare elements.
+	 */
+	public ObservableViewerElementSet(Realm realm, Class<E> elementType,
+			IElementComparer comparer) {
+		super(realm);
+
+		Assert.isNotNull(comparer);
+		this.wrappedSet = new ViewerElementSet<E>(comparer);
+		this.elementTypeAsObject = elementType;
 		this.elementType = elementType;
 		this.comparer = comparer;
 	}
 
-	protected Set getWrappedSet() {
+	protected Set<E> getWrappedSet() {
 		return wrappedSet;
 	}
 
 	public Object getElementType() {
+		return elementTypeAsObject;
+	}
+
+	public Class<E> getElementClass() {
 		return elementType;
 	}
 
-	public Iterator iterator() {
+	public Iterator<E> iterator() {
 		getterCalled();
-		final Iterator wrappedIterator = wrappedSet.iterator();
-		return new Iterator() {
-			Object last;
+		final Iterator<E> wrappedIterator = wrappedSet.iterator();
+		return new Iterator<E>() {
+			E last;
 
 			public boolean hasNext() {
 				getterCalled();
 				return wrappedIterator.hasNext();
 			}
 
-			public Object next() {
+			public E next() {
 				getterCalled();
 				return last = wrappedIterator.next();
 			}
@@ -93,32 +125,33 @@
 			public void remove() {
 				getterCalled();
 				wrappedIterator.remove();
-				fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET,
+				fireSetChange(Diffs.createSetDiff(Collections.<E> emptySet(),
 						Collections.singleton(last)));
 			}
 		};
 	}
 
-	public boolean add(Object o) {
+	public boolean add(E o) {
 		getterCalled();
 		boolean changed = wrappedSet.add(o);
 		if (changed)
 			fireSetChange(Diffs.createSetDiff(Collections.singleton(o),
-					Collections.EMPTY_SET));
+					Collections.<E> emptySet()));
 		return changed;
 	}
 
-	public boolean addAll(Collection c) {
+	public boolean addAll(Collection<? extends E> c) {
 		getterCalled();
-		Set additions = new ViewerElementSet(comparer);
-		for (Iterator iterator = c.iterator(); iterator.hasNext();) {
-			Object element = iterator.next();
+		Set<E> additions = new ViewerElementSet<E>(comparer);
+		for (Iterator<? extends E> iterator = c.iterator(); iterator.hasNext();) {
+			E element = iterator.next();
 			if (wrappedSet.add(element))
 				additions.add(element);
 		}
 		boolean changed = !additions.isEmpty();
 		if (changed)
-			fireSetChange(Diffs.createSetDiff(additions, Collections.EMPTY_SET));
+			fireSetChange(Diffs.createSetDiff(additions,
+					Collections.<E> emptySet()));
 		return changed;
 	}
 
@@ -126,32 +159,33 @@
 		getterCalled();
 		boolean changed = wrappedSet.remove(o);
 		if (changed)
-			fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET,
-					Collections.singleton(o)));
+			fireSetChange(Diffs.createSetDiff(Collections.<E> emptySet(),
+					Collections.singleton((E) o)));
 		return changed;
 	}
 
-	public boolean removeAll(Collection c) {
+	public boolean removeAll(Collection<?> c) {
 		getterCalled();
-		Set removals = new ViewerElementSet(comparer);
-		for (Iterator iterator = c.iterator(); iterator.hasNext();) {
+		Set<E> removals = new ViewerElementSet<E>(comparer);
+		for (Iterator<?> iterator = c.iterator(); iterator.hasNext();) {
 			Object element = iterator.next();
 			if (wrappedSet.remove(element))
-				removals.add(element);
+				removals.add((E) element);
 		}
 		boolean changed = !removals.isEmpty();
 		if (changed)
-			fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET, removals));
+			fireSetChange(Diffs.createSetDiff(Collections.<E> emptySet(),
+					removals));
 		return changed;
 	}
 
-	public boolean retainAll(Collection c) {
+	public boolean retainAll(Collection<?> c) {
 		getterCalled();
-		Set removals = new ViewerElementSet(comparer);
+		Set<E> removals = new ViewerElementSet<E>(comparer);
 		Object[] toRetain = c.toArray();
-		outer: for (Iterator iterator = wrappedSet.iterator(); iterator
+		outer: for (Iterator<E> iterator = wrappedSet.iterator(); iterator
 				.hasNext();) {
-			Object element = iterator.next();
+			E element = iterator.next();
 			// Cannot rely on c.contains(element) because we must compare
 			// elements using IElementComparer.
 			for (int i = 0; i < toRetain.length; i++) {
@@ -163,16 +197,18 @@
 		}
 		boolean changed = !removals.isEmpty();
 		if (changed)
-			fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET, removals));
+			fireSetChange(Diffs.createSetDiff(Collections.<E> emptySet(),
+					removals));
 		return changed;
 	}
 
 	public void clear() {
 		getterCalled();
 		if (!wrappedSet.isEmpty()) {
-			Set removals = wrappedSet;
-			wrappedSet = new ViewerElementSet(comparer);
-			fireSetChange(Diffs.createSetDiff(Collections.EMPTY_SET, removals));
+			Set<E> removals = wrappedSet;
+			wrappedSet = new ViewerElementSet<E>(comparer);
+			fireSetChange(Diffs.createSetDiff(Collections.<E> emptySet(),
+					removals));
 		}
 	}
 
@@ -192,10 +228,11 @@
 	 * @return a Set for holding viewer elements, using the given
 	 *         {@link IElementComparer} for comparisons.
 	 */
-	public static IObservableSet withComparer(Realm realm, Object elementType,
-			IElementComparer comparer) {
+	public static <E2> IObservableSet<E2> withComparer(Realm realm,
+			Object elementType, IElementComparer comparer) {
 		if (comparer == null)
-			return new WritableSet(realm, Collections.EMPTY_SET, elementType);
-		return new ObservableViewerElementSet(realm, elementType, comparer);
+			return new WritableSet<E2>(realm, Collections.<E2> emptySet(),
+					elementType);
+		return new ObservableViewerElementSet<E2>(realm, elementType, comparer);
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionChangedListener.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionChangedListener.java
index 3c2d21b..b806951 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionChangedListener.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionChangedListener.java
@@ -12,6 +12,7 @@
 
 package org.eclipse.jface.internal.databinding.viewers;
 
+import org.eclipse.core.databinding.observable.IDiff;
 import org.eclipse.core.databinding.property.IProperty;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.core.databinding.property.NativePropertyListener;
@@ -20,13 +21,14 @@
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.SelectionChangedEvent;
 
-class SelectionChangedListener extends NativePropertyListener implements
+class SelectionChangedListener<S extends ISelectionProvider, D extends IDiff>
+		extends NativePropertyListener<S, D> implements
 		ISelectionChangedListener {
 
 	private final boolean isPostSelection;
 
 	SelectionChangedListener(IProperty property,
-			ISimplePropertyListener listener, boolean isPostSelection) {
+			ISimplePropertyListener<D> listener, boolean isPostSelection) {
 		super(property, listener);
 		this.isPostSelection = isPostSelection;
 	}
@@ -35,21 +37,21 @@
 		fireChange(event.getSource(), null);
 	}
 
-	public void doAddTo(Object source) {
+	public void doAddTo(ISelectionProvider source) {
 		if (isPostSelection) {
 			((IPostSelectionProvider) source)
 					.addPostSelectionChangedListener(this);
 		} else {
-			((ISelectionProvider) source).addSelectionChangedListener(this);
+			source.addSelectionChangedListener(this);
 		}
 	}
 
-	public void doRemoveFrom(Object source) {
+	public void doRemoveFrom(ISelectionProvider source) {
 		if (isPostSelection) {
 			((IPostSelectionProvider) source)
 					.removePostSelectionChangedListener(this);
 		} else {
-			((ISelectionProvider) source).removeSelectionChangedListener(this);
+			source.removeSelectionChangedListener(this);
 		}
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderMultipleSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderMultipleSelectionProperty.java
index 88cbb41..56d852b 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderMultipleSelectionProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderMultipleSelectionProperty.java
@@ -13,24 +13,26 @@
 
 package org.eclipse.jface.internal.databinding.viewers;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
 import org.eclipse.core.databinding.observable.list.ListDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
-import org.eclipse.jface.databinding.viewers.ViewerListProperty;
+import org.eclipse.core.databinding.property.list.SimpleListProperty;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
 
 /**
+ * @param <S>
  * @since 3.3
  * 
  */
-public class SelectionProviderMultipleSelectionProperty extends
-		ViewerListProperty {
+public class SelectionProviderMultipleSelectionProperty<S extends ISelectionProvider>
+		extends SimpleListProperty<S, Object> {
 
 	private final boolean isPostSelection;
 
@@ -49,26 +51,34 @@
 		return Object.class;
 	}
 
-	protected List doGetList(Object source) {
-		ISelection selection = ((ISelectionProvider) source).getSelection();
-		if (selection instanceof IStructuredSelection) {
-			return ((IStructuredSelection) selection).toList();
-		}
-		return Collections.EMPTY_LIST;
+	public Class<Object> getElementClass() {
+		return Object.class;
 	}
 
-	protected void doSetList(Object source, List list, ListDiff diff) {
+	protected List<Object> doGetList(S source) {
+		ISelection selection = source.getSelection();
+		if (selection instanceof IStructuredSelection) {
+			ArrayList<Object> result = new ArrayList<Object>();
+			for (Object element : ((IStructuredSelection) selection).toList()) {
+				result.add(element);
+			}
+			return result;
+		}
+		return Collections.emptyList();
+	}
+
+	protected void doSetList(S source, List<Object> list, ListDiff<Object> diff) {
 		doSetList(source, list);
 	}
 
-	protected void doSetList(Object source, List list) {
-		((ISelectionProvider) source)
-				.setSelection(new StructuredSelection(list));
+	protected void doSetList(S source, List<Object> list) {
+		source.setSelection(new StructuredSelection(list));
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
-		return new SelectionChangedListener(this, listener, isPostSelection);
+	public INativePropertyListener<S> adaptListener(
+			ISimplePropertyListener<ListDiff<Object>> listener) {
+		return new SelectionChangedListener<S, ListDiff<Object>>(this,
+				listener, isPostSelection);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderMultipleViewerSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderMultipleViewerSelectionProperty.java
new file mode 100644
index 0000000..8335266
--- /dev/null
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderMultipleViewerSelectionProperty.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Matthew Hall and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Matthew Hall - initial API and implementation (bug 194734)
+ *     Matthew Hall - bugs 195222, 263413, 265561
+ *     Ovidio Mallo - bug 270494
+ ******************************************************************************/
+
+package org.eclipse.jface.internal.databinding.viewers;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.list.ListDiff;
+import org.eclipse.core.databinding.property.INativePropertyListener;
+import org.eclipse.core.databinding.property.ISimplePropertyListener;
+import org.eclipse.jface.databinding.viewers.ViewerListProperty;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Use this when the source is a viewer. If the source is a ISelectionProvider
+ * but not a viewer then use SelectionProviderMultipleSelectionProperty.
+ * 
+ * @param <S>
+ * @since 3.3
+ * 
+ */
+public class SelectionProviderMultipleViewerSelectionProperty<S extends ISelectionProvider>
+		extends ViewerListProperty<Viewer> {
+
+	private final boolean isPostSelection;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param isPostSelection
+	 *            Whether the post selection or the normal selection is to be
+	 *            observed.
+	 */
+	public SelectionProviderMultipleViewerSelectionProperty(
+			boolean isPostSelection) {
+		this.isPostSelection = isPostSelection;
+	}
+
+	public Object getElementType() {
+		return Object.class;
+	}
+
+	public Class<Object> getElementClass() {
+		return Object.class;
+	}
+
+	protected List<Object> doGetList(Viewer source) {
+		ISelection selection = source.getSelection();
+		if (selection instanceof IStructuredSelection) {
+			ArrayList<Object> result = new ArrayList<Object>();
+			for (Object element : ((IStructuredSelection) selection).toList()) {
+				result.add(element);
+			}
+			return result;
+		}
+		return Collections.emptyList();
+	}
+
+	protected void doSetList(Viewer source, List<Object> list,
+			ListDiff<Object> diff) {
+		doSetList(source, list);
+	}
+
+	protected void doSetList(Viewer source, List<Object> list) {
+		source.setSelection(new StructuredSelection(list));
+	}
+
+	public INativePropertyListener<Viewer> adaptListener(
+			ISimplePropertyListener<ListDiff<Object>> listener) {
+		return new SelectionChangedListener<Viewer, ListDiff<Object>>(this,
+				listener, isPostSelection);
+	}
+
+	public String toString() {
+		return isPostSelection ? "IPostSelectionProvider.postSelection[]" //$NON-NLS-1$
+				: "ISelectionProvider.selection[]"; //$NON-NLS-1$
+	}
+}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderSingleSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderSingleSelectionProperty.java
index 758fa2d..97839b9 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderSingleSelectionProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderSingleSelectionProperty.java
@@ -13,21 +13,25 @@
 
 package org.eclipse.jface.internal.databinding.viewers;
 
+import org.eclipse.core.databinding.observable.value.ValueDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
-import org.eclipse.jface.databinding.viewers.ViewerValueProperty;
+import org.eclipse.core.databinding.property.value.SimpleValueProperty;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.Viewer;
 
 /**
+ * Use this only when the source is not a viewer.
+ * 
+ * @param <S>
+ * 
  * @since 3.3
  * 
  */
-public class SelectionProviderSingleSelectionProperty extends
-		ViewerValueProperty {
+public class SelectionProviderSingleSelectionProperty<S extends ISelectionProvider>
+		extends SimpleValueProperty<S, Object> {
 
 	private final boolean isPostSelection;
 
@@ -46,27 +50,24 @@
 		return null;
 	}
 
-	protected Object doGetValue(Object source) {
-		ISelection selection = ((ISelectionProvider) source).getSelection();
+	protected Object doGetValue(S source) {
+		ISelection selection = source.getSelection();
 		if (selection instanceof IStructuredSelection) {
 			return ((IStructuredSelection) selection).getFirstElement();
 		}
 		return null;
 	}
 
-	protected void doSetValue(Object source, Object value) {
+	protected void doSetValue(S source, Object value) {
 		IStructuredSelection selection = value == null ? StructuredSelection.EMPTY
 				: new StructuredSelection(value);
-		if (source instanceof Viewer) {
-			((Viewer) source).setSelection(selection, true);
-		} else {
-			((ISelectionProvider) source).setSelection(selection);
-		}
+		source.setSelection(selection);
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
-		return new SelectionChangedListener(this, listener, isPostSelection);
+	public INativePropertyListener<S> adaptListener(
+			ISimplePropertyListener<ValueDiff<Object>> listener) {
+		return new SelectionChangedListener<S, ValueDiff<Object>>(this,
+				listener, isPostSelection);
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderSingleViewerSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderSingleViewerSelectionProperty.java
new file mode 100644
index 0000000..24f6cb3
--- /dev/null
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/SelectionProviderSingleViewerSelectionProperty.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Matthew Hall and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Matthew Hall - initial API and implementation (bug 194734)
+ *     Matthew Hall - bugs 195222, 263413, 265561, 271080
+ *     Ovidio Mallo - bug 270494
+ ******************************************************************************/
+
+package org.eclipse.jface.internal.databinding.viewers;
+
+import org.eclipse.core.databinding.observable.value.ValueDiff;
+import org.eclipse.core.databinding.property.INativePropertyListener;
+import org.eclipse.core.databinding.property.ISimplePropertyListener;
+import org.eclipse.jface.databinding.viewers.ViewerValueProperty;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * @since 3.3
+ * 
+ */
+public class SelectionProviderSingleViewerSelectionProperty extends
+		ViewerValueProperty<Viewer> {
+
+	private final boolean isPostSelection;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param isPostSelection
+	 *            Whether the post selection or the normal selection is to be
+	 *            observed.
+	 */
+	public SelectionProviderSingleViewerSelectionProperty(
+			boolean isPostSelection) {
+		this.isPostSelection = isPostSelection;
+	}
+
+	public Object getValueType() {
+		return null;
+	}
+
+	protected Object doGetValue(Viewer source) {
+		ISelection selection = source.getSelection();
+		if (selection instanceof IStructuredSelection) {
+			return ((IStructuredSelection) selection).getFirstElement();
+		}
+		return null;
+	}
+
+	protected void doSetValue(Viewer source, Object value) {
+		IStructuredSelection selection = value == null ? StructuredSelection.EMPTY
+				: new StructuredSelection(value);
+		source.setSelection(selection, true);
+	}
+
+	public INativePropertyListener<Viewer> adaptListener(
+			ISimplePropertyListener<ValueDiff<Object>> listener) {
+		return new SelectionChangedListener<Viewer, ValueDiff<Object>>(this,
+				listener, isPostSelection);
+	}
+
+	public String toString() {
+		return isPostSelection ? "IPostSelectionProvider.postSelection" //$NON-NLS-1$
+				: "ISelectionProvider.selection"; //$NON-NLS-1$
+	}
+}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/StructuredViewerFiltersProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/StructuredViewerFiltersProperty.java
index 731ea43..71e7e3e 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/StructuredViewerFiltersProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/StructuredViewerFiltersProperty.java
@@ -27,33 +27,37 @@
  * @since 3.3
  * 
  */
-public class StructuredViewerFiltersProperty extends ViewerSetProperty {
+public class StructuredViewerFiltersProperty extends
+		ViewerSetProperty<StructuredViewer, ViewerFilter> {
 	public Object getElementType() {
 		return ViewerFilter.class;
 	}
 
-	protected Set doGetSet(Object source) {
-		return new HashSet(Arrays.asList(((StructuredViewer) source)
-				.getFilters()));
+	public Class<ViewerFilter> getElementClass() {
+		return ViewerFilter.class;
 	}
 
-	public void doSetSet(Object source, Set set, SetDiff diff) {
+	protected Set<ViewerFilter> doGetSet(StructuredViewer source) {
+		return new HashSet<ViewerFilter>(Arrays.asList(source.getFilters()));
+	}
+
+	public void doSetSet(StructuredViewer source, Set<ViewerFilter> set,
+			SetDiff<ViewerFilter> diff) {
 		doSetSet(source, set);
 	}
 
-	protected void doSetSet(Object source, Set set) {
-		StructuredViewer viewer = (StructuredViewer) source;
+	protected void doSetSet(StructuredViewer source, Set<ViewerFilter> set) {
+		StructuredViewer viewer = source;
 		viewer.getControl().setRedraw(false);
 		try {
-			viewer.setFilters((ViewerFilter[]) set.toArray(new ViewerFilter[set
-					.size()]));
+			viewer.setFilters(set.toArray(new ViewerFilter[set.size()]));
 		} finally {
 			viewer.getControl().setRedraw(true);
 		}
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<StructuredViewer> adaptListener(
+			ISimplePropertyListener<SetDiff<ViewerFilter>> listener) {
 		return null;
 	}
 
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerCheckedElementsProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerCheckedElementsProperty.java
index 956e9c0..99db62e 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerCheckedElementsProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerCheckedElementsProperty.java
@@ -22,8 +22,13 @@
 
 /**
  * @since 3.3
- * 
+ * @deprecated use CheckboxTableViewerCheckedElementsProperty for
+ *             CheckboxTableViewer, CheckboxTreeViewerCheckedElementsProperty
+ *             for CheckboxTreeViewer, and CheckableElementsProperty for all
+ *             other ICheckable sources.
  */
+@SuppressWarnings({ "rawtypes", "unchecked" })
+// ok to ignore warnings on deprecated class
 public class ViewerCheckedElementsProperty extends DelegatingSetProperty
 		implements IViewerSetProperty {
 	ISetProperty checkable;
@@ -51,7 +56,8 @@
 	}
 
 	public IViewerObservableSet observe(Viewer viewer) {
-		return (IViewerObservableSet) observe(SWTObservables.getRealm(viewer
-				.getControl().getDisplay()), viewer);
+		return (IViewerObservableSet) observe(
+				SWTObservables.getRealm(viewer.getControl().getDisplay()),
+				viewer);
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementMap.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementMap.java
index 6a8a03b..9262dd9 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementMap.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementMap.java
@@ -12,7 +12,6 @@
 
 package org.eclipse.jface.internal.databinding.viewers;
 
-import java.lang.reflect.Array;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -20,13 +19,14 @@
 import java.util.Set;
 
 import org.eclipse.core.runtime.Assert;
-import org.eclipse.jface.util.Util;
+import org.eclipse.jface.databinding.util.Util;
+import org.eclipse.jface.internal.databinding.viewers.ObservableCollectionTreeContentProvider.TreeNode;
 import org.eclipse.jface.viewers.IElementComparer;
 import org.eclipse.jface.viewers.StructuredViewer;
 
 /**
- * A {@link Map} whose keys are elements in a {@link StructuredViewer}. The
- * keys in the map are compared using an {@link IElementComparer} instead of
+ * A {@link Map} whose keys are elements in a {@link StructuredViewer}. The keys
+ * in the map are compared using an {@link IElementComparer} instead of
  * {@link #equals(Object)}.
  * <p>
  * This class is <i>not</i> a strict implementation the {@link Map} interface.
@@ -35,10 +35,13 @@
  * with {@link StructuredViewer} which uses {@link IElementComparer} for element
  * comparisons.
  * 
+ * @param <K>
+ * @param <V>
+ * 
  * @since 1.2
  */
-public class ViewerElementMap implements Map { 
-	private Map wrappedMap;
+public class ViewerElementMap<K, V> implements Map<K, V> {
+	private Map<ViewerElementWrapper<K>, V> wrappedMap;
 	private IElementComparer comparer;
 
 	/**
@@ -49,7 +52,7 @@
 	 */
 	public ViewerElementMap(IElementComparer comparer) {
 		Assert.isNotNull(comparer);
-		this.wrappedMap = new HashMap();
+		this.wrappedMap = new HashMap<ViewerElementWrapper<K>, V>();
 		this.comparer = comparer;
 	}
 
@@ -62,7 +65,8 @@
 	 * @param comparer
 	 *            the {@link IElementComparer} used for comparing keys.
 	 */
-	public ViewerElementMap(Map map, IElementComparer comparer) {
+	public ViewerElementMap(Map<? extends K, ? extends V> map,
+			IElementComparer comparer) {
 		this(comparer);
 		Assert.isNotNull(map);
 		putAll(map);
@@ -73,21 +77,23 @@
 	}
 
 	public boolean containsKey(Object key) {
-		return wrappedMap.containsKey(new ViewerElementWrapper(key, comparer));
+		return wrappedMap.containsKey(new ViewerElementWrapper<Object>(key,
+				comparer));
 	}
 
 	public boolean containsValue(Object value) {
 		return wrappedMap.containsValue(value);
 	}
 
-	public Set entrySet() {
-		final Set wrappedEntrySet = wrappedMap.entrySet();
-		return new Set() {
-			public boolean add(Object o) {
+	public Set<Entry<K, V>> entrySet() {
+		final Set<Entry<ViewerElementWrapper<K>, V>> wrappedEntrySet = wrappedMap
+				.entrySet();
+		return new Set<Entry<K, V>>() {
+			public boolean add(Entry<K, V> o) {
 				throw new UnsupportedOperationException();
 			}
 
-			public boolean addAll(Collection c) {
+			public boolean addAll(Collection<? extends Entry<K, V>> c) {
 				throw new UnsupportedOperationException();
 			}
 
@@ -96,14 +102,15 @@
 			}
 
 			public boolean contains(Object o) {
-				for (Iterator iterator = iterator(); iterator.hasNext();)
+				for (Iterator<Entry<K, V>> iterator = iterator(); iterator
+						.hasNext();)
 					if (iterator.next().equals(o))
 						return true;
 				return false;
 			}
 
-			public boolean containsAll(Collection c) {
-				for (Iterator iterator = c.iterator(); iterator.hasNext();)
+			public boolean containsAll(Collection<?> c) {
+				for (Iterator<?> iterator = c.iterator(); iterator.hasNext();)
 					if (!contains(iterator.next()))
 						return false;
 				return true;
@@ -113,27 +120,27 @@
 				return wrappedEntrySet.isEmpty();
 			}
 
-			public Iterator iterator() {
-				final Iterator wrappedIterator = wrappedEntrySet.iterator();
-				return new Iterator() {
+			public Iterator<Entry<K, V>> iterator() {
+				final Iterator<Entry<ViewerElementWrapper<K>, V>> wrappedIterator = wrappedEntrySet
+						.iterator();
+				return new Iterator<Entry<K, V>>() {
 					public boolean hasNext() {
 						return wrappedIterator.hasNext();
 					}
 
-					public Object next() {
-						final Map.Entry wrappedEntry = (Map.Entry) wrappedIterator
+					public Entry<K, V> next() {
+						final Entry<ViewerElementWrapper<K>, V> wrappedEntry = wrappedIterator
 								.next();
-						return new Map.Entry() {
-							public Object getKey() {
-								return ((ViewerElementWrapper) wrappedEntry.getKey())
-										.unwrap();
+						return new Map.Entry<K, V>() {
+							public K getKey() {
+								return wrappedEntry.getKey().unwrap();
 							}
 
-							public Object getValue() {
+							public V getValue() {
 								return wrappedEntry.getValue();
 							}
 
-							public Object setValue(Object value) {
+							public V setValue(V value) {
 								return wrappedEntry.setValue(value);
 							}
 
@@ -142,11 +149,11 @@
 									return true;
 								if (obj == null || !(obj instanceof Map.Entry))
 									return false;
-								Map.Entry that = (Map.Entry) obj;
-								return comparer.equals(this.getKey(), that
-										.getKey())
-										&& Util.equals(this.getValue(), that
-												.getValue());
+								Map.Entry<?, ?> that = (Map.Entry<?, ?>) obj;
+								return comparer.equals(this.getKey(),
+										that.getKey())
+										&& Util.equals(this.getValue(),
+												that.getValue());
 							}
 
 							public int hashCode() {
@@ -162,10 +169,10 @@
 			}
 
 			public boolean remove(Object o) {
-				final Map.Entry unwrappedEntry = (Map.Entry) o;
-				final ViewerElementWrapper wrappedKey = new ViewerElementWrapper(
+				final Map.Entry<?, ?> unwrappedEntry = (Map.Entry<?, ?>) o;
+				final ViewerElementWrapper<?> wrappedKey = new ViewerElementWrapper<Object>(
 						unwrappedEntry.getKey(), comparer);
-				Map.Entry wrappedEntry = new Map.Entry() {
+				Map.Entry<?, ?> wrappedEntry = new Map.Entry<Object, Object>() {
 					public Object getKey() {
 						return wrappedKey;
 					}
@@ -183,11 +190,9 @@
 							return true;
 						if (obj == null || !(obj instanceof Map.Entry))
 							return false;
-						Map.Entry that = (Map.Entry) obj;
+						Map.Entry<?, ?> that = (Map.Entry<?, ?>) obj;
 						return Util.equals(wrappedKey, that.getKey())
-								&& Util
-										.equals(this.getValue(), that
-												.getValue());
+								&& Util.equals(this.getValue(), that.getValue());
 					}
 
 					public int hashCode() {
@@ -199,17 +204,18 @@
 				return wrappedEntrySet.remove(wrappedEntry);
 			}
 
-			public boolean removeAll(Collection c) {
+			public boolean removeAll(Collection<?> c) {
 				boolean changed = false;
-				for (Iterator iterator = c.iterator(); iterator.hasNext();)
+				for (Iterator<?> iterator = c.iterator(); iterator.hasNext();)
 					changed |= remove(iterator.next());
 				return changed;
 			}
 
-			public boolean retainAll(Collection c) {
+			public boolean retainAll(Collection<?> c) {
 				boolean changed = false;
 				Object[] toRetain = c.toArray();
-				outer: for (Iterator iterator = iterator(); iterator.hasNext();) {
+				outer: for (Iterator<?> iterator = iterator(); iterator
+						.hasNext();) {
 					Object entry = iterator.next();
 					for (int i = 0; i < toRetain.length; i++)
 						if (entry.equals(toRetain[i]))
@@ -228,18 +234,21 @@
 				return toArray(new Object[size()]);
 			}
 
-			public Object[] toArray(Object[] a) {
+			public <E2> E2[] toArray(E2[] a) {
 				int size = size();
+				Class<E2> componentType = Util.getComponentType(a);
+
+				E2[] result = a;
 				if (a.length < size) {
-					a = (Object[]) Array.newInstance(a.getClass()
-							.getComponentType(), size);
+					result = Util.createArrayInstance(componentType, size);
 				}
+
 				int i = 0;
-				for (Iterator iterator = iterator(); iterator.hasNext();) {
-					a[i] = iterator.next();
-					i++;
+				for (Object element : this) {
+					result[i] = componentType.cast(element);
 				}
-				return a;
+
+				return result;
 			}
 
 			public boolean equals(Object obj) {
@@ -247,7 +256,7 @@
 					return true;
 				if (obj == null || !(obj instanceof Set))
 					return false;
-				Set that = (Set) obj;
+				Set<?> that = (Set<?>) obj;
 				return this.size() == that.size() && containsAll(that);
 			}
 
@@ -257,22 +266,22 @@
 		};
 	}
 
-	public Object get(Object key) {
-		return wrappedMap.get(new ViewerElementWrapper(key, comparer));
+	public V get(Object key) {
+		return wrappedMap.get(new ViewerElementWrapper<Object>(key, comparer));
 	}
 
 	public boolean isEmpty() {
 		return wrappedMap.isEmpty();
 	}
 
-	public Set keySet() {
-		final Set wrappedKeySet = wrappedMap.keySet();
-		return new Set() {
-			public boolean add(Object o) {
+	public Set<K> keySet() {
+		final Set<ViewerElementWrapper<K>> wrappedKeySet = wrappedMap.keySet();
+		return new Set<K>() {
+			public boolean add(K o) {
 				throw new UnsupportedOperationException();
 			}
 
-			public boolean addAll(Collection c) {
+			public boolean addAll(Collection<? extends K> c) {
 				throw new UnsupportedOperationException();
 			}
 
@@ -281,12 +290,15 @@
 			}
 
 			public boolean contains(Object o) {
-				return wrappedKeySet.contains(new ViewerElementWrapper(o, comparer));
+				return wrappedKeySet.contains(new ViewerElementWrapper<Object>(
+						o, comparer));
 			}
 
-			public boolean containsAll(Collection c) {
-				for (Iterator iterator = c.iterator(); iterator.hasNext();)
-					if (!wrappedKeySet.contains(new ViewerElementWrapper(iterator.next(), comparer)))
+			public boolean containsAll(Collection<?> c) {
+				for (Iterator<?> iterator = c.iterator(); iterator.hasNext();)
+					if (!wrappedKeySet
+							.contains(new ViewerElementWrapper<Object>(iterator
+									.next(), comparer)))
 						return false;
 				return true;
 			}
@@ -295,15 +307,16 @@
 				return wrappedKeySet.isEmpty();
 			}
 
-			public Iterator iterator() {
-				final Iterator wrappedIterator = wrappedKeySet.iterator();
-				return new Iterator() {
+			public Iterator<K> iterator() {
+				final Iterator<ViewerElementWrapper<K>> wrappedIterator = wrappedKeySet
+						.iterator();
+				return new Iterator<K>() {
 					public boolean hasNext() {
 						return wrappedIterator.hasNext();
 					}
 
-					public Object next() {
-						return ((ViewerElementWrapper) wrappedIterator.next()).unwrap();
+					public K next() {
+						return wrappedIterator.next().unwrap();
 					}
 
 					public void remove() {
@@ -313,22 +326,25 @@
 			}
 
 			public boolean remove(Object o) {
-				return wrappedKeySet.remove(new ViewerElementWrapper(o, comparer));
+				return wrappedKeySet.remove(new ViewerElementWrapper<Object>(o,
+						comparer));
 			}
 
-			public boolean removeAll(Collection c) {
+			public boolean removeAll(Collection<?> c) {
 				boolean changed = false;
-				for (Iterator iterator = c.iterator(); iterator.hasNext();)
+				for (Iterator<?> iterator = c.iterator(); iterator.hasNext();)
 					changed |= wrappedKeySet
-							.remove(new ViewerElementWrapper(iterator.next(), comparer));
+							.remove(new ViewerElementWrapper<Object>(iterator
+									.next(), comparer));
 				return changed;
 			}
 
-			public boolean retainAll(Collection c) {
+			public boolean retainAll(Collection<?> c) {
 				boolean changed = false;
 				Object[] toRetain = c.toArray();
-				outer: for (Iterator iterator = iterator(); iterator.hasNext();) {
-					Object element = iterator.next();
+				outer: for (Iterator<K> iterator = iterator(); iterator
+						.hasNext();) {
+					K element = iterator.next();
 					for (int i = 0; i < toRetain.length; i++)
 						if (comparer.equals(element, toRetain[i]))
 							continue outer;
@@ -347,17 +363,20 @@
 				return toArray(new Object[wrappedKeySet.size()]);
 			}
 
-			public Object[] toArray(Object[] a) {
+			public <E2> E2[] toArray(E2[] a) {
 				int size = wrappedKeySet.size();
-				ViewerElementWrapper[] wrappedArray = (ViewerElementWrapper[]) wrappedKeySet
-						.toArray(new ViewerElementWrapper[size]);
-				Object[] result = a;
+				Class<E2> componentType = Util.getComponentType(a);
+
+				E2[] result = a;
 				if (a.length < size) {
-					result = (Object[]) Array.newInstance(a.getClass()
-							.getComponentType(), size);
+					result = Util.createArrayInstance(componentType, size);
 				}
-				for (int i = 0; i < size; i++)
-					result[i] = wrappedArray[i].unwrap();
+
+				int i = 0;
+				for (ViewerElementWrapper<K> element : wrappedKeySet) {
+					result[i] = componentType.cast(element.unwrap());
+				}
+
 				return result;
 			}
 
@@ -366,7 +385,7 @@
 					return true;
 				if (obj == null || !(obj instanceof Set))
 					return false;
-				Set that = (Set) obj;
+				Set<?> that = (Set<?>) obj;
 				return this.size() == that.size() && containsAll(that);
 			}
 
@@ -376,27 +395,29 @@
 		};
 	}
 
-	public Object put(Object key, Object value) {
-		return wrappedMap.put(new ViewerElementWrapper(key, comparer), value);
+	public V put(K key, V value) {
+		return wrappedMap
+				.put(new ViewerElementWrapper<K>(key, comparer), value);
 	}
 
-	public void putAll(Map other) {
-		for (Iterator iterator = other.entrySet().iterator(); iterator
-				.hasNext();) {
-			Map.Entry entry = (Map.Entry) iterator.next();
-			wrappedMap.put(new ViewerElementWrapper(entry.getKey(), comparer), entry.getValue());
+	public void putAll(Map<? extends K, ? extends V> other) {
+		for (Map.Entry<? extends K, ? extends V> entry : other.entrySet()) {
+			wrappedMap.put(
+					new ViewerElementWrapper<K>(entry.getKey(), comparer),
+					entry.getValue());
 		}
 	}
 
-	public Object remove(Object key) {
-		return wrappedMap.remove(new ViewerElementWrapper(key, comparer));
+	public V remove(Object key) {
+		return wrappedMap
+				.remove(new ViewerElementWrapper<Object>(key, comparer));
 	}
 
 	public int size() {
 		return wrappedMap.size();
 	}
 
-	public Collection values() {
+	public Collection<V> values() {
 		return wrappedMap.values();
 	}
 
@@ -405,7 +426,7 @@
 			return true;
 		if (obj == null || !(obj instanceof Map))
 			return false;
-		Map that = (Map) obj;
+		Map<?, ?> that = (Map<?, ?>) obj;
 		return this.entrySet().equals(that.entrySet());
 	}
 
@@ -424,9 +445,9 @@
 	 * @return a Map for mapping viewer elements as keys to values, using the
 	 *         given {@link IElementComparer} for key comparisons.
 	 */
-	public static Map withComparer(IElementComparer comparer) {
+	public static <K> Map<K, TreeNode> withComparer(IElementComparer comparer) {
 		if (comparer == null)
-			return new HashMap();
-		return new ViewerElementMap(comparer);
+			return new HashMap<K, TreeNode>();
+		return new ViewerElementMap<K, TreeNode>(comparer);
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementSet.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementSet.java
index b9a0b1e..99a605e 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementSet.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementSet.java
@@ -33,10 +33,12 @@
  * use with {@link StructuredViewer} which uses {@link IElementComparer} for
  * element comparisons.
  * 
+ * @param <E>
+ * 
  * @since 1.2
  */
-public class ViewerElementSet implements Set {
-	private final Set wrappedSet;
+public class ViewerElementSet<E> implements Set<E> {
+	private final Set<ViewerElementWrapper<E>> wrappedSet;
 	private final IElementComparer comparer;
 
 	/**
@@ -47,7 +49,7 @@
 	 */
 	public ViewerElementSet(IElementComparer comparer) {
 		Assert.isNotNull(comparer);
-		this.wrappedSet = new HashSet();
+		this.wrappedSet = new HashSet<ViewerElementWrapper<E>>();
 		this.comparer = comparer;
 	}
 
@@ -60,20 +62,21 @@
 	 * @param comparer
 	 *            the {@link IElementComparer} used for comparing elements.
 	 */
-	public ViewerElementSet(Collection collection, IElementComparer comparer) {
+	public ViewerElementSet(Collection<? extends E> collection,
+			IElementComparer comparer) {
 		this(comparer);
 		addAll(collection);
 	}
 
-	public boolean add(Object o) {
-		return wrappedSet.add(new ViewerElementWrapper(o, comparer));
+	public boolean add(E o) {
+		return wrappedSet.add(new ViewerElementWrapper<E>(o, comparer));
 	}
 
-	public boolean addAll(Collection c) {
+	public boolean addAll(Collection<? extends E> c) {
 		boolean changed = false;
-		for (Iterator iterator = c.iterator(); iterator.hasNext();)
-			changed |= wrappedSet.add(new ViewerElementWrapper(iterator.next(),
-					comparer));
+		for (Iterator<? extends E> iterator = c.iterator(); iterator.hasNext();)
+			changed |= wrappedSet.add(new ViewerElementWrapper<E>(iterator
+					.next(), comparer));
 		return changed;
 	}
 
@@ -82,13 +85,14 @@
 	}
 
 	public boolean contains(Object o) {
-		return wrappedSet.contains(new ViewerElementWrapper(o, comparer));
+		return wrappedSet
+				.contains(new ViewerElementWrapper<Object>(o, comparer));
 	}
 
-	public boolean containsAll(Collection c) {
-		for (Iterator iterator = c.iterator(); iterator.hasNext();)
-			if (!wrappedSet.contains(new ViewerElementWrapper(iterator.next(),
-					comparer)))
+	public boolean containsAll(Collection<?> c) {
+		for (Iterator<?> iterator = c.iterator(); iterator.hasNext();)
+			if (!wrappedSet.contains(new ViewerElementWrapper<Object>(iterator
+					.next(), comparer)))
 				return false;
 		return true;
 	}
@@ -97,15 +101,16 @@
 		return wrappedSet.isEmpty();
 	}
 
-	public Iterator iterator() {
-		final Iterator wrappedIterator = wrappedSet.iterator();
-		return new Iterator() {
+	public Iterator<E> iterator() {
+		final Iterator<ViewerElementWrapper<E>> wrappedIterator = wrappedSet
+				.iterator();
+		return new Iterator<E>() {
 			public boolean hasNext() {
 				return wrappedIterator.hasNext();
 			}
 
-			public Object next() {
-				return ((ViewerElementWrapper) wrappedIterator.next()).unwrap();
+			public E next() {
+				return wrappedIterator.next().unwrap();
 			}
 
 			public void remove() {
@@ -115,23 +120,23 @@
 	}
 
 	public boolean remove(Object o) {
-		return wrappedSet.remove(new ViewerElementWrapper(o, comparer));
+		return wrappedSet.remove(new ViewerElementWrapper<Object>(o, comparer));
 	}
 
-	public boolean removeAll(Collection c) {
+	public boolean removeAll(Collection<?> c) {
 		boolean changed = false;
-		for (Iterator iterator = c.iterator(); iterator.hasNext();)
+		for (Iterator<?> iterator = c.iterator(); iterator.hasNext();)
 			changed |= remove(iterator.next());
 		return changed;
 	}
 
-	public boolean retainAll(Collection c) {
+	public boolean retainAll(Collection<?> c) {
 		// Have to do this the slow way to ensure correct comparisons. i.e.
 		// cannot delegate to c.contains(it) since we can't be sure will
 		// compare elements the way we want.
 		boolean changed = false;
 		Object[] retainAll = c.toArray();
-		outer: for (Iterator iterator = iterator(); iterator.hasNext();) {
+		outer: for (Iterator<?> iterator = iterator(); iterator.hasNext();) {
 			Object element = iterator.next();
 			for (int i = 0; i < retainAll.length; i++) {
 				if (comparer.equals(element, retainAll[i])) {
@@ -171,14 +176,14 @@
 			return true;
 		if (!(obj instanceof Set))
 			return false;
-		Set that = (Set) obj;
+		Set<?> that = (Set<?>) obj;
 		return size() == that.size() && containsAll(that);
 	}
 
 	public int hashCode() {
 		int hash = 0;
-		for (Iterator iterator = iterator(); iterator.hasNext();) {
-			Object element = iterator.next();
+		for (Iterator<E> iterator = iterator(); iterator.hasNext();) {
+			E element = iterator.next();
 			hash += element == null ? 0 : element.hashCode();
 		}
 		return hash;
@@ -195,9 +200,9 @@
 	 * @return a Set for holding viewer elements, using the given
 	 *         {@link IElementComparer} for comparisons.
 	 */
-	public static Set withComparer(IElementComparer comparer) {
+	public static Set<Object> withComparer(IElementComparer comparer) {
 		if (comparer == null)
-			return new HashSet();
+			return new HashSet<Object>();
 		return new ViewerElementSet(comparer);
 	}
 }
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementWrapper.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementWrapper.java
index c2645ae..67ea137 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementWrapper.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerElementWrapper.java
@@ -18,10 +18,12 @@
  * for computing {@link Object#equals(Object) equality} and
  * {@link Object#hashCode() hashes}.
  * 
+ * @param <E>
+ * 
  * @since 1.2
  */
-public class ViewerElementWrapper {
-	private final Object element;
+public class ViewerElementWrapper<E> {
+	private final E element;
 	private final IElementComparer comparer;
 
 	/**
@@ -32,7 +34,7 @@
 	 * @param comparer
 	 *            the comparer to use for computing equality and hash codes.
 	 */
-	public ViewerElementWrapper(Object element, IElementComparer comparer) {
+	public ViewerElementWrapper(E element, IElementComparer comparer) {
 		if (comparer == null)
 			throw new NullPointerException();
 		this.element = element;
@@ -43,14 +45,15 @@
 		if (!(obj instanceof ViewerElementWrapper)) {
 			return false;
 		}
-		return comparer.equals(element, ((ViewerElementWrapper) obj).element);
+		return comparer
+				.equals(element, ((ViewerElementWrapper<?>) obj).element);
 	}
 
 	public int hashCode() {
 		return comparer.hashCode(element);
 	}
 
-	Object unwrap() {
+	E unwrap() {
 		return element;
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerInputProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerInputProperty.java
index 55baadf..47b0528 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerInputProperty.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerInputProperty.java
@@ -12,6 +12,7 @@
 
 package org.eclipse.jface.internal.databinding.viewers;
 
+import org.eclipse.core.databinding.observable.value.ValueDiff;
 import org.eclipse.core.databinding.property.INativePropertyListener;
 import org.eclipse.core.databinding.property.ISimplePropertyListener;
 import org.eclipse.jface.databinding.viewers.ViewerValueProperty;
@@ -21,29 +22,30 @@
  * @since 3.3
  * 
  */
-public class ViewerInputProperty extends ViewerValueProperty {
+public class ViewerInputProperty extends ViewerValueProperty<Viewer> {
 	public Object getValueType() {
 		return null;
 	}
 
-	protected Object doGetValue(Object source) {
-		return ((Viewer) source).getInput();
+	protected Object doGetValue(Viewer source) {
+		return source.getInput();
 	}
 
-	protected void doSetValue(Object source, Object value) {
-		((Viewer) source).setInput(value);
+	protected void doSetValue(Viewer source, Object value) {
+		source.setInput(value);
 	}
 
-	public INativePropertyListener adaptListener(
-			ISimplePropertyListener listener) {
+	public INativePropertyListener<Viewer> adaptListener(
+			ISimplePropertyListener<ValueDiff<Object>> listener) {
 		return null;
 	}
 
-	protected void doAddListener(Object source, INativePropertyListener listener) {
+	protected void doAddListener(Viewer source,
+			INativePropertyListener<Viewer> listener) {
 	}
 
-	protected void doRemoveListener(Object source,
-			INativePropertyListener listener) {
+	protected void doRemoveListener(Viewer source,
+			INativePropertyListener<Viewer> listener) {
 	}
 
 	public String toString() {
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerMultipleSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerMultipleSelectionProperty.java
new file mode 100644
index 0000000..f134fd8
--- /dev/null
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerMultipleSelectionProperty.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Matthew Hall and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Matthew Hall - initial API and implementation (bug 194734)
+ *     Matthew Hall - bugs 195222, 263413, 265561
+ *     Ovidio Mallo - bug 270494
+ ******************************************************************************/
+
+package org.eclipse.jface.internal.databinding.viewers;
+
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.jface.databinding.viewers.IViewerListProperty;
+import org.eclipse.jface.databinding.viewers.IViewerObservableList;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * @param <S>
+ * @since 3.3
+ * 
+ */
+public class ViewerMultipleSelectionProperty<S extends Viewer> extends
+		SelectionProviderMultipleSelectionProperty<S> implements
+		IViewerListProperty<S> {
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param isPostSelection
+	 *            Whether the post selection or the normal selection is to be
+	 *            observed.
+	 */
+	public ViewerMultipleSelectionProperty(boolean isPostSelection) {
+		super(isPostSelection);
+	}
+
+	public IViewerObservableList<S> observe(S source) {
+		return observe(
+				SWTObservables.getRealm(source.getControl().getDisplay()),
+				source);
+	}
+
+	public IViewerObservableList<S> observe(Realm realm, S source) {
+		IObservableList<Object> observable = super.observe(realm, source);
+		return new ViewerObservableListDecorator<S>(observable, source);
+	}
+}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableListDecorator.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableListDecorator.java
index 91463b6..5d66614 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableListDecorator.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableListDecorator.java
@@ -17,24 +17,25 @@
 import org.eclipse.jface.viewers.Viewer;
 
 /**
+ * @param <S>
  * @since 3.3
  * 
  */
-public class ViewerObservableListDecorator extends DecoratingObservableList
-		implements IViewerObservableList {
-	private final Viewer viewer;
+public class ViewerObservableListDecorator<S extends Viewer> extends
+		DecoratingObservableList<Object> implements IViewerObservableList<S> {
+	private final S viewer;
 
 	/**
 	 * @param decorated
 	 * @param viewer
 	 */
-	public ViewerObservableListDecorator(IObservableList decorated,
-			Viewer viewer) {
+	public ViewerObservableListDecorator(IObservableList<Object> decorated,
+			S viewer) {
 		super(decorated, true);
 		this.viewer = viewer;
 	}
 
-	public Viewer getViewer() {
+	public S getViewer() {
 		return viewer;
 	}
 
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableSetDecorator.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableSetDecorator.java
index 3062b0b..b591555 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableSetDecorator.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableSetDecorator.java
@@ -17,23 +17,25 @@
 import org.eclipse.jface.viewers.Viewer;
 
 /**
+ * @param <S>
+ * @param <E>
  * @since 3.3
  * 
  */
-public class ViewerObservableSetDecorator extends DecoratingObservableSet
-		implements IViewerObservableSet {
-	private final Viewer viewer;
+public class ViewerObservableSetDecorator<S extends Viewer, E> extends
+		DecoratingObservableSet<E> implements IViewerObservableSet<S, E> {
+	private final S viewer;
 
 	/**
 	 * @param decorated
 	 * @param viewer
 	 */
-	public ViewerObservableSetDecorator(IObservableSet decorated, Viewer viewer) {
+	public ViewerObservableSetDecorator(IObservableSet<E> decorated, S viewer) {
 		super(decorated, true);
 		this.viewer = viewer;
 	}
 
-	public Viewer getViewer() {
+	public S getViewer() {
 		return viewer;
 	}
 
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableValueDecorator.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableValueDecorator.java
index f14c351..cad4de9 100644
--- a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableValueDecorator.java
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerObservableValueDecorator.java
@@ -21,22 +21,24 @@
 import org.eclipse.swt.widgets.Listener;
 
 /**
+ * @param <S>
  * @since 3.3
  * 
  */
-public class ViewerObservableValueDecorator extends DecoratingObservableValue
-		implements IViewerObservableValue, Listener {
-	private Viewer viewer;
+public class ViewerObservableValueDecorator<S extends Viewer> extends
+		DecoratingObservableValue<Object> implements IViewerObservableValue<S>,
+		Listener {
+	private S viewer;
 
 	/**
 	 * @param decorated
 	 * @param viewer
 	 */
-	public ViewerObservableValueDecorator(IObservableValue decorated,
-			Viewer viewer) {
+	public ViewerObservableValueDecorator(IObservableValue<Object> decorated,
+			S viewer) {
 		super(decorated, true);
 		this.viewer = viewer;
-		viewer.getControl().addListener(SWT.Dispose, this);
+		((Viewer) viewer).getControl().addListener(SWT.Dispose, this);
 	}
 
 	public void handleEvent(Event event) {
@@ -44,13 +46,13 @@
 			dispose();
 	}
 
-	public Viewer getViewer() {
+	public S getViewer() {
 		return viewer;
 	}
 
 	public synchronized void dispose() {
 		if (viewer != null) {
-			Control control = viewer.getControl();
+			Control control = ((Viewer) viewer).getControl();
 			if (control != null && !control.isDisposed()) {
 				control.removeListener(SWT.Dispose, this);
 			}
diff --git a/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerSingleSelectionProperty.java b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerSingleSelectionProperty.java
new file mode 100644
index 0000000..b199a4f
--- /dev/null
+++ b/bundles/org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/viewers/ViewerSingleSelectionProperty.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Matthew Hall and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Matthew Hall - initial API and implementation (bug 194734)
+ *     Matthew Hall - bugs 195222, 263413, 265561, 271080
+ *     Ovidio Mallo - bug 270494
+ ******************************************************************************/
+
+package org.eclipse.jface.internal.databinding.viewers;
+
+import org.eclipse.core.databinding.observable.value.ValueDiff;
+import org.eclipse.core.databinding.property.INativePropertyListener;
+import org.eclipse.core.databinding.property.ISimplePropertyListener;
+import org.eclipse.jface.databinding.viewers.IViewerValueProperty;
+import org.eclipse.jface.databinding.viewers.ViewerValueProperty;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Use this only when the source is not a viewer.
+ * 
+ * @param <S>
+ * 
+ * @since 3.3
+ * 
+ */
+public class ViewerSingleSelectionProperty<S extends Viewer> extends
+		ViewerValueProperty<S> implements IViewerValueProperty<S> {
+
+	private final boolean isPostSelection;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param isPostSelection
+	 *            Whether the post selection or the normal selection is to be
+	 *            observed.
+	 */
+	public ViewerSingleSelectionProperty(boolean isPostSelection) {
+		this.isPostSelection = isPostSelection;
+	}
+
+	public Object getValueType() {
+		return null;
+	}
+
+	protected Object doGetValue(S source) {
+		ISelection selection = source.getSelection();
+		if (selection instanceof IStructuredSelection) {
+			return ((IStructuredSelection) selection).getFirstElement();
+		}
+		return null;
+	}
+
+	protected void doSetValue(S source, Object value) {
+		IStructuredSelection selection = value == null ? StructuredSelection.EMPTY
+				: new StructuredSelection(value);
+		source.setSelection(selection);
+	}
+
+	public INativePropertyListener<S> adaptListener(
+			ISimplePropertyListener<ValueDiff<Object>> listener) {
+		return new SelectionChangedListener<S, ValueDiff<Object>>(this,
+				listener, isPostSelection);
+	}
+
+	public String toString() {
+		return isPostSelection ? "IPostSelectionProvider.postSelection" //$NON-NLS-1$
+				: "ISelectionProvider.selection"; //$NON-NLS-1$
+	}
+}
diff --git a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/list/DecoratingObservableListTest.java b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/list/DecoratingObservableListTest.java
index ca361d5..634fea2 100644
--- a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/list/DecoratingObservableListTest.java
+++ b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/list/DecoratingObservableListTest.java
@@ -34,14 +34,14 @@
  */
 public class DecoratingObservableListTest {
 	public static Test suite() {
-		TestSuite suite = new TestSuite(DecoratingObservableListTest.class
-				.getName());
+		TestSuite suite = new TestSuite(
+				DecoratingObservableListTest.class.getName());
 		suite.addTest(MutableObservableListContractTest.suite(new Delegate()));
 		return suite;
 	}
 
 	static class Delegate extends AbstractObservableCollectionContractDelegate {
-		private Object elementType = Object.class;
+		private Class elementType = Object.class;
 
 		public IObservableCollection createObservableCollection(Realm realm,
 				int elementCount) {
@@ -53,10 +53,15 @@
 		}
 
 		public Object createElement(IObservableCollection collection) {
-			return new Object();
+			Class elementType = getElementType(collection);
+			try {
+				return elementType.getConstructor().newInstance();
+			} catch (Exception e) {
+				return new Object();
+			}
 		}
 
-		public Object getElementType(IObservableCollection collection) {
+		public Class getElementType(IObservableCollection collection) {
 			return elementType;
 		}
 
diff --git a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/set/ComputedSetTest.java b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/set/ComputedSetTest.java
index ead335c..a630d1b 100644
--- a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/set/ComputedSetTest.java
+++ b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/databinding/observable/set/ComputedSetTest.java
@@ -77,8 +77,8 @@
 
 		set.dependency.fireChange();
 		assertEquals(
-				"ComputedSet should not fire set change events when dirty",
-				1, tracker.count);
+				"ComputedSet should not fire set change events when dirty", 1,
+				tracker.count);
 
 		set.size(); // Force set to recompute.
 		set.dependency.fireChange();
@@ -151,7 +151,16 @@
 		}
 
 		public Object createElement(IObservableCollection collection) {
-			return new Object();
+			Class elementType = getElementType(collection);
+			try {
+				return elementType.getConstructor().newInstance();
+			} catch (Exception e) {
+				return new Object();
+			}
+		}
+
+		public Class getElementType(IObservableCollection collection) {
+			return Object.class;
 		}
 
 		public void setStale(IObservable observable, boolean stale) {
diff --git a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableArrayBasedListTest.java b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableArrayBasedListTest.java
index f40ef0e..a4c6da7 100644
--- a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableArrayBasedListTest.java
+++ b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableArrayBasedListTest.java
@@ -29,6 +29,7 @@
 import org.eclipse.core.databinding.beans.BeansObservables;
 import org.eclipse.core.databinding.beans.IBeanObservable;
 import org.eclipse.core.databinding.beans.IBeanProperty;
+import org.eclipse.core.databinding.observable.DecoratingObservableCollection;
 import org.eclipse.core.databinding.observable.IObservable;
 import org.eclipse.core.databinding.observable.IObservableCollection;
 import org.eclipse.core.databinding.observable.Realm;
@@ -70,8 +71,9 @@
 				propertyName)).getPropertyDescriptor();
 		bean = new Bean(new Object[0]);
 
-		list = BeansObservables.observeList(SWTObservables.getRealm(Display
-				.getDefault()), bean, propertyName);
+		list = BeansObservables.observeList(
+				SWTObservables.getRealm(Display.getDefault()), bean,
+				propertyName);
 		beanObservable = (IBeanObservable) list;
 	}
 
@@ -132,8 +134,8 @@
 		ListChangeEvent event = listener.event;
 
 		assertSame(list, event.getObservableList());
-		assertDiff(event.diff, Collections.EMPTY_LIST, Collections
-				.singletonList("1"));
+		assertDiff(event.diff, Collections.EMPTY_LIST,
+				Collections.singletonList("1"));
 	}
 
 	public void testAdd_FiresPropertyChangeEvent() throws Exception {
@@ -162,8 +164,8 @@
 		list.add(0, element);
 
 		ListChangeEvent event = listener.event;
-		assertDiff(event.diff, Collections.EMPTY_LIST, Collections
-				.singletonList("1"));
+		assertDiff(event.diff, Collections.EMPTY_LIST,
+				Collections.singletonList("1"));
 	}
 
 	public void testAddAtIndexPropertyChangeEvent() throws Exception {
@@ -271,8 +273,8 @@
 		ListChangeEvent event = listener.event;
 		assertSame(list, event.getObservableList());
 
-		assertDiff(event.diff, Collections.EMPTY_LIST, Arrays
-				.asList(new String[] { "1", "2" }));
+		assertDiff(event.diff, Collections.EMPTY_LIST,
+				Arrays.asList(new String[] { "1", "2" }));
 	}
 
 	public void testAddAllPropertyChangeEvent() throws Exception {
@@ -311,8 +313,8 @@
 		ListChangeEvent event = listener.event;
 		assertSame(list, event.getObservableList());
 
-		assertDiff(event.diff, Arrays.asList(new Object[] { "1", "2" }), Arrays
-				.asList(new Object[] { "1", "2", "1", "2" }));
+		assertDiff(event.diff, Arrays.asList(new Object[] { "1", "2" }),
+				Arrays.asList(new Object[] { "1", "2", "1", "2" }));
 	}
 
 	public void testAddAllAtIndexPropertyChangeEvent() throws Exception {
@@ -348,8 +350,8 @@
 		ListChangeEvent event = listener.event;
 		assertSame(list, event.getObservableList());
 
-		assertDiff(event.diff, Arrays
-				.asList(new Object[] { "1", "2", "1", "2" }),
+		assertDiff(event.diff,
+				Arrays.asList(new Object[] { "1", "2", "1", "2" }),
 				Collections.EMPTY_LIST);
 	}
 
@@ -389,9 +391,9 @@
 		ListChangeEvent event = listener.event;
 		assertSame(list, event.getObservableList());
 
-		assertDiff(event.diff, Arrays
-				.asList(new Object[] { "0", "1", "2", "3" }), Arrays
-				.asList(new Object[] { "0", "1" }));
+		assertDiff(event.diff,
+				Arrays.asList(new Object[] { "0", "1", "2", "3" }),
+				Arrays.asList(new Object[] { "0", "1" }));
 	}
 
 	public void testRetainAllPropertyChangeEvent() throws Exception {
@@ -522,8 +524,8 @@
 
 		realm.setCurrent(true);
 		assertEquals(1, tracker.count);
-		assertDiff(tracker.event.diff, Collections.EMPTY_LIST, Collections
-				.singletonList("element"));
+		assertDiff(tracker.event.diff, Collections.EMPTY_LIST,
+				Collections.singletonList("element"));
 	}
 
 	private static void assertDiff(ListDiff diff, List oldList, List newList) {
@@ -546,10 +548,10 @@
 		PropertyChangeEvent event = listener.evt;
 		assertEquals("event did not fire", 1, listener.count);
 		assertEquals("array", event.getPropertyName());
-		assertTrue("old value", Arrays.equals(old, (Object[]) event
-				.getOldValue()));
-		assertTrue("new value", Arrays.equals(bean.getArray(), (Object[]) event
-				.getNewValue()));
+		assertTrue("old value",
+				Arrays.equals(old, (Object[]) event.getOldValue()));
+		assertTrue("new value",
+				Arrays.equals(bean.getArray(), (Object[]) event.getNewValue()));
 		assertFalse("lists are equal", Arrays.equals(bean.getArray(), old));
 	}
 
@@ -587,10 +589,22 @@
 		}
 
 		public Object createElement(IObservableCollection collection) {
-			return new Object();
+			Class elementType = getElementType(collection);
+			try {
+				return elementType.getConstructor().newInstance();
+			} catch (Exception e) {
+				return new Object();
+			}
 		}
 
-		public Object getElementType(IObservableCollection collection) {
+		public Class getElementType(IObservableCollection collection) {
+			if (collection instanceof DecoratingObservableCollection) {
+				DecoratingObservableCollection x = (DecoratingObservableCollection) collection;
+				if (x.getElementClass() != null) {
+					return x.getElementClass();
+				}
+			}
+
 			return String.class;
 		}
 
diff --git a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableArrayBasedSetTest.java b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableArrayBasedSetTest.java
index 22e88ee..3e0005b 100644
--- a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableArrayBasedSetTest.java
+++ b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableArrayBasedSetTest.java
@@ -29,6 +29,7 @@
 import org.eclipse.core.databinding.beans.BeansObservables;
 import org.eclipse.core.databinding.beans.IBeanObservable;
 import org.eclipse.core.databinding.beans.IBeanProperty;
+import org.eclipse.core.databinding.observable.DecoratingObservableCollection;
 import org.eclipse.core.databinding.observable.IObservable;
 import org.eclipse.core.databinding.observable.IObservableCollection;
 import org.eclipse.core.databinding.observable.Realm;
@@ -65,8 +66,9 @@
 				propertyName)).getPropertyDescriptor();
 		bean = new Bean(new HashSet());
 
-		set = BeansObservables.observeSet(SWTObservables.getRealm(Display
-				.getDefault()), bean, propertyName);
+		set = BeansObservables.observeSet(
+				SWTObservables.getRealm(Display.getDefault()), bean,
+				propertyName);
 		beanObservable = (IBeanObservable) set;
 	}
 
@@ -302,10 +304,10 @@
 				.observe(observable);
 		bean.setArray(new Object[] { "new" });
 		assertEquals(1, tracker.count);
-		assertEquals(Collections.singleton("old"), tracker.event.diff
-				.getRemovals());
-		assertEquals(Collections.singleton("new"), tracker.event.diff
-				.getAdditions());
+		assertEquals(Collections.singleton("old"),
+				tracker.event.diff.getRemovals());
+		assertEquals(Collections.singleton("new"),
+				tracker.event.diff.getAdditions());
 	}
 
 	public void testModifyObservableSet_FiresSetChange() {
@@ -317,8 +319,8 @@
 		observable.add("new");
 
 		assertEquals(1, tracker.count);
-		assertDiff(tracker.event.diff, Collections.EMPTY_SET, Collections
-				.singleton("new"));
+		assertDiff(tracker.event.diff, Collections.EMPTY_SET,
+				Collections.singleton("new"));
 	}
 
 	public void testSetBeanPropertyOutsideRealm_FiresEventInsideRealm() {
@@ -335,8 +337,8 @@
 
 		realm.setCurrent(true);
 		assertEquals(1, tracker.count);
-		assertDiff(tracker.event.diff, Collections.EMPTY_SET, Collections
-				.singleton("element"));
+		assertDiff(tracker.event.diff, Collections.EMPTY_SET,
+				Collections.singleton("element"));
 	}
 
 	private static void assertDiff(SetDiff diff, Set oldSet, Set newSet) {
@@ -359,10 +361,10 @@
 		PropertyChangeEvent event = listener.evt;
 		assertEquals("event did not fire", 1, listener.count);
 		assertEquals("array", event.getPropertyName());
-		assertTrue("old value", Arrays.equals(old, (Object[]) event
-				.getOldValue()));
-		assertTrue("new value", Arrays.equals(bean.getArray(), (Object[]) event
-				.getNewValue()));
+		assertTrue("old value",
+				Arrays.equals(old, (Object[]) event.getOldValue()));
+		assertTrue("new value",
+				Arrays.equals(bean.getArray(), (Object[]) event.getNewValue()));
 		assertFalse("sets are equal", Arrays.equals(bean.getArray(), old));
 	}
 
@@ -400,10 +402,22 @@
 		}
 
 		public Object createElement(IObservableCollection collection) {
-			return new Object().toString();
+			Class elementType = getElementType(collection);
+			try {
+				return elementType.getConstructor().newInstance();
+			} catch (Exception e) {
+				return new Object();
+			}
 		}
 
-		public Object getElementType(IObservableCollection collection) {
+		public Class getElementType(IObservableCollection collection) {
+			if (collection instanceof DecoratingObservableCollection) {
+				DecoratingObservableCollection x = (DecoratingObservableCollection) collection;
+				if (x.getElementClass() != null) {
+					return x.getElementClass();
+				}
+			}
+
 			return String.class;
 		}
 
diff --git a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableListTest.java b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableListTest.java
index 9fcb2a9..6338059 100644
--- a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableListTest.java
+++ b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableListTest.java
@@ -30,6 +30,7 @@
 import org.eclipse.core.databinding.beans.IBeanObservable;
 import org.eclipse.core.databinding.beans.IBeanProperty;
 import org.eclipse.core.databinding.beans.PojoObservables;
+import org.eclipse.core.databinding.observable.DecoratingObservableCollection;
 import org.eclipse.core.databinding.observable.IObservable;
 import org.eclipse.core.databinding.observable.IObservableCollection;
 import org.eclipse.core.databinding.observable.Realm;
@@ -71,8 +72,9 @@
 				propertyName)).getPropertyDescriptor();
 		bean = new Bean(new ArrayList());
 
-		list = BeansObservables.observeList(SWTObservables.getRealm(Display
-				.getDefault()), bean, propertyName);
+		list = BeansObservables.observeList(
+				SWTObservables.getRealm(Display.getDefault()), bean,
+				propertyName);
 		beanObservable = (IBeanObservable) list;
 	}
 
@@ -133,8 +135,8 @@
 		ListChangeEvent event = listener.event;
 
 		assertSame(list, event.getObservableList());
-		assertDiff(event.diff, Collections.EMPTY_LIST, Collections
-				.singletonList("1"));
+		assertDiff(event.diff, Collections.EMPTY_LIST,
+				Collections.singletonList("1"));
 	}
 
 	public void testAddFiresPropertyChangeEvent() throws Exception {
@@ -163,8 +165,8 @@
 		list.add(0, element);
 
 		ListChangeEvent event = listener.event;
-		assertDiff(event.diff, Collections.EMPTY_LIST, Collections
-				.singletonList("1"));
+		assertDiff(event.diff, Collections.EMPTY_LIST,
+				Collections.singletonList("1"));
 	}
 
 	public void testAddAtIndexPropertyChangeEvent() throws Exception {
@@ -285,8 +287,8 @@
 		ListChangeEvent event = listener.event;
 		assertSame(list, event.getObservableList());
 
-		assertDiff(event.diff, Collections.EMPTY_LIST, Arrays
-				.asList(new String[] { "1", "2" }));
+		assertDiff(event.diff, Collections.EMPTY_LIST,
+				Arrays.asList(new String[] { "1", "2" }));
 	}
 
 	public void testAddAllPropertyChangeEvent() throws Exception {
@@ -325,8 +327,8 @@
 		ListChangeEvent event = listener.event;
 		assertSame(list, event.getObservableList());
 
-		assertDiff(event.diff, Arrays.asList(new Object[] { "1", "2" }), Arrays
-				.asList(new Object[] { "1", "2", "1", "2" }));
+		assertDiff(event.diff, Arrays.asList(new Object[] { "1", "2" }),
+				Arrays.asList(new Object[] { "1", "2", "1", "2" }));
 	}
 
 	public void testAddAllAtIndexPropertyChangeEvent() throws Exception {
@@ -363,8 +365,8 @@
 		assertEquals(list, event.getObservableList());
 		assertSame(list, event.getObservableList());
 
-		assertDiff(event.diff, Arrays
-				.asList(new Object[] { "1", "2", "1", "2" }),
+		assertDiff(event.diff,
+				Arrays.asList(new Object[] { "1", "2", "1", "2" }),
 				Collections.EMPTY_LIST);
 	}
 
@@ -404,9 +406,9 @@
 		ListChangeEvent event = listener.event;
 		assertSame(list, event.getObservableList());
 
-		assertDiff(event.diff, Arrays
-				.asList(new Object[] { "0", "1", "2", "3" }), Arrays
-				.asList(new Object[] { "0", "1" }));
+		assertDiff(event.diff,
+				Arrays.asList(new Object[] { "0", "1", "2", "3" }),
+				Arrays.asList(new Object[] { "0", "1" }));
 	}
 
 	public void testRetainAllPropertyChangeEvent() throws Exception {
@@ -487,8 +489,8 @@
 
 	public void testConstructor_RegistersListener() throws Exception {
 		Bean bean = new Bean();
-		IObservableList observable = BeansObservables.observeList(Realm
-				.getDefault(), bean, "list");
+		IObservableList observable = BeansObservables.observeList(
+				Realm.getDefault(), bean, "list");
 
 		assertFalse(bean.hasListeners("list"));
 		ChangeEventTracker.observe(observable);
@@ -497,8 +499,8 @@
 
 	public void testConstructor_SkipsRegisterListener() throws Exception {
 		Bean bean = new Bean();
-		IObservableList observable = PojoObservables.observeList(Realm
-				.getDefault(), bean, "list");
+		IObservableList observable = PojoObservables.observeList(
+				Realm.getDefault(), bean, "list");
 
 		assertFalse(bean.hasListeners("list"));
 		ChangeEventTracker.observe(observable);
@@ -539,8 +541,8 @@
 		observable.add(element);
 
 		assertEquals(1, tracker.count);
-		assertDiff(tracker.event.diff, Collections.EMPTY_LIST, Collections
-				.singletonList(element));
+		assertDiff(tracker.event.diff, Collections.EMPTY_LIST,
+				Collections.singletonList(element));
 	}
 
 	public void testSetBeanPropertyOutsideRealm_FiresEventInsideRealm() {
@@ -557,8 +559,8 @@
 
 		realm.setCurrent(true);
 		assertEquals(1, tracker.count);
-		assertDiff(tracker.event.diff, Collections.EMPTY_LIST, Collections
-				.singletonList("element"));
+		assertDiff(tracker.event.diff, Collections.EMPTY_LIST,
+				Collections.singletonList("element"));
 	}
 
 	/**
@@ -623,8 +625,8 @@
 	}
 
 	public static Test suite() {
-		TestSuite suite = new TestSuite(JavaBeanObservableListTest.class
-				.getName());
+		TestSuite suite = new TestSuite(
+				JavaBeanObservableListTest.class.getName());
 		suite.addTestSuite(JavaBeanObservableListTest.class);
 		suite.addTest(MutableObservableListContractTest.suite(new Delegate()));
 		return suite;
@@ -644,10 +646,22 @@
 		}
 
 		public Object createElement(IObservableCollection collection) {
-			return new Object().toString();
+			Class elementType = getElementType(collection);
+			try {
+				return elementType.getConstructor().newInstance();
+			} catch (Exception e) {
+				return new Object();
+			}
 		}
 
-		public Object getElementType(IObservableCollection collection) {
+		public Class getElementType(IObservableCollection collection) {
+			if (collection instanceof DecoratingObservableCollection) {
+				DecoratingObservableCollection x = (DecoratingObservableCollection) collection;
+				if (x.getElementClass() != null) {
+					return x.getElementClass();
+				}
+			}
+
 			return String.class;
 		}
 
diff --git a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableSetTest.java b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableSetTest.java
index cf0aec5..06270e7 100644
--- a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableSetTest.java
+++ b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/beans/JavaBeanObservableSetTest.java
@@ -28,6 +28,7 @@
 import org.eclipse.core.databinding.beans.IBeanObservable;
 import org.eclipse.core.databinding.beans.IBeanProperty;
 import org.eclipse.core.databinding.beans.PojoObservables;
+import org.eclipse.core.databinding.observable.DecoratingObservableCollection;
 import org.eclipse.core.databinding.observable.IObservable;
 import org.eclipse.core.databinding.observable.IObservableCollection;
 import org.eclipse.core.databinding.observable.Realm;
@@ -61,9 +62,9 @@
 		propertyDescriptor = ((IBeanProperty) BeanProperties.set(Bean.class,
 				propertyName)).getPropertyDescriptor();
 
-		observableSet = BeansObservables
-				.observeSet(SWTObservables.getRealm(Display.getDefault()),
-						bean, propertyName, Bean.class);
+		observableSet = BeansObservables.observeSet(
+				SWTObservables.getRealm(Display.getDefault()), bean,
+				propertyName, Bean.class);
 		beanObservable = (IBeanObservable) observableSet;
 		listener = new SetChangeEventTracker();
 	}
@@ -99,7 +100,7 @@
 	public void testFiresChangeEvents() throws Exception {
 		observableSet.addSetChangeListener(listener);
 		assertEquals(0, listener.count);
-		bean.setSet(new HashSet(Arrays.asList(new String[] { "1" })));
+		bean.setSet(new HashSet(Arrays.asList(new Bean[] { new Bean() })));
 		assertEquals(1, listener.count);
 	}
 
@@ -138,10 +139,10 @@
 				.observe(observable);
 		bean.setSet(Collections.singleton("new"));
 		assertEquals(1, tracker.count);
-		assertEquals(Collections.singleton("old"), tracker.event.diff
-				.getRemovals());
-		assertEquals(Collections.singleton("new"), tracker.event.diff
-				.getAdditions());
+		assertEquals(Collections.singleton("old"),
+				tracker.event.diff.getRemovals());
+		assertEquals(Collections.singleton("new"),
+				tracker.event.diff.getAdditions());
 	}
 
 	public void testModifyObservableSet_FiresSetChange() {
@@ -154,8 +155,8 @@
 		observable.add(element);
 
 		assertEquals(1, tracker.count);
-		assertDiff(tracker.event.diff, Collections.EMPTY_SET, Collections
-				.singleton(element));
+		assertDiff(tracker.event.diff, Collections.EMPTY_SET,
+				Collections.singleton(element));
 	}
 
 	public void testSetBeanPropertyOutsideRealm_FiresEventInsideRealm() {
@@ -172,8 +173,8 @@
 
 		realm.setCurrent(true);
 		assertEquals(1, tracker.count);
-		assertDiff(tracker.event.diff, Collections.EMPTY_SET, Collections
-				.singleton("element"));
+		assertDiff(tracker.event.diff, Collections.EMPTY_SET,
+				Collections.singleton("element"));
 	}
 
 	/**
@@ -209,8 +210,8 @@
 	}
 
 	public static Test suite() {
-		TestSuite suite = new TestSuite(JavaBeanObservableSetTest.class
-				.getName());
+		TestSuite suite = new TestSuite(
+				JavaBeanObservableSetTest.class.getName());
 		suite.addTestSuite(JavaBeanObservableSetTest.class);
 		suite.addTest(MutableObservableSetContractTest.suite(new Delegate()));
 		return suite;
@@ -231,10 +232,22 @@
 		}
 
 		public Object createElement(IObservableCollection collection) {
-			return new Object();
+			Class elementType = getElementType(collection);
+			try {
+				return elementType.getConstructor().newInstance();
+			} catch (Exception e) {
+				return new Object();
+			}
 		}
 
-		public Object getElementType(IObservableCollection collection) {
+		public Class getElementType(IObservableCollection collection) {
+			if (collection instanceof DecoratingObservableCollection) {
+				DecoratingObservableCollection x = (DecoratingObservableCollection) collection;
+				if (x.getElementClass() != null) {
+					return x.getElementClass();
+				}
+			}
+
 			return String.class;
 		}
 
diff --git a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/observable/masterdetail/DetailObservableListTest.java b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/observable/masterdetail/DetailObservableListTest.java
index e37dc7d..9b1f1c9 100644
--- a/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/observable/masterdetail/DetailObservableListTest.java
+++ b/tests/org.eclipse.jface.tests.databinding/src/org/eclipse/core/tests/internal/databinding/observable/masterdetail/DetailObservableListTest.java
@@ -156,15 +156,15 @@
 	}
 
 	public static Test suite() {
-		TestSuite suite = new TestSuite(DetailObservableListTest.class
-				.getName());
+		TestSuite suite = new TestSuite(
+				DetailObservableListTest.class.getName());
 		suite.addTestSuite(DetailObservableListTest.class);
 		suite.addTest(MutableObservableListContractTest.suite(new Delegate()));
 		return suite;
 	}
 
 	static class Delegate extends AbstractObservableCollectionContractDelegate {
-		Object elementType = Object.class;
+		Class elementType = Object.class;
 
 		public IObservableCollection createObservableCollection(
 				final Realm realm, final int elementCount) {
@@ -176,10 +176,15 @@
 		}
 
 		public Object createElement(IObservableCollection collection) {
-			return new Object();
+			Class elementType = getElementType(collection);
+			try {
+				return elementType.getConstructor().newInstance();
+			} catch (Exception e) {
+				return new Object();
+			}
 		}
 
-		public Object getElementType(IObservableCollection collection) {
+		public Class getElementType(IObservableCollection collection) {
 			return elementType;
 		}