FIXED - bug 332367: [DataBinding] Performance of (WritableList|SimplePropertyObservableMap)#clear()
https://bugs.eclipse.org/bugs/show_bug.cgi?id=332367
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java
index 8302f6e..7d447a5 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java
@@ -12,6 +12,7 @@
  *     Brad Reynolds - bug 147515
  *     Sebastian Fuchs <spacehorst@gmail.com> - bug 243848
  *     Matthew Hall - bugs 208858, 213145, 243848
+ *     Ovidio Mallo - bug 332367
  *******************************************************************************/
 package org.eclipse.core.databinding.observable.list;
 
@@ -19,6 +20,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
 
 import org.eclipse.core.databinding.observable.Diffs;
 import org.eclipse.core.databinding.observable.Realm;
@@ -125,9 +127,9 @@
 	public Object set(int index, Object element) {
 		checkRealm();
 		Object oldElement = wrappedList.set(index, element);
-		fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(index,
-				false, oldElement), Diffs.createListDiffEntry(index, true,
-				element)));
+		fireListChange(Diffs.createListDiff(
+				Diffs.createListDiffEntry(index, false, oldElement),
+				Diffs.createListDiffEntry(index, true, element)));
 		return oldElement;
 	}
 
@@ -147,9 +149,9 @@
 			return wrappedList.get(oldIndex);
 		Object element = wrappedList.remove(oldIndex);
 		wrappedList.add(newIndex, element);
-		fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(oldIndex,
-				false, element), Diffs.createListDiffEntry(newIndex, true,
-				element)));
+		fireListChange(Diffs.createListDiff(
+				Diffs.createListDiffEntry(oldIndex, false, element),
+				Diffs.createListDiffEntry(newIndex, true, element)));
 		return element;
 	}
 
@@ -259,15 +261,19 @@
 
 	public void clear() {
 		checkRealm();
-		List entries = new ArrayList();
-		for (Iterator it = wrappedList.iterator(); it.hasNext();) {
-			Object element = it.next();
-			// always report 0 as the remove index
-			entries.add(Diffs.createListDiffEntry(0, false, element));
-			it.remove();
+		// We remove the elements from back to front which is typically much
+		// faster on common list implementations like ArrayList.
+		ListDiffEntry[] entries = new ListDiffEntry[wrappedList.size()];
+		int entryIndex = 0;
+		for (ListIterator it = wrappedList.listIterator(wrappedList.size()); it
+				.hasPrevious();) {
+			int elementIndex = it.previousIndex();
+			Object element = it.previous();
+			entries[entryIndex++] = Diffs.createListDiffEntry(elementIndex,
+					false, element);
 		}
-		fireListChange(Diffs.createListDiff((ListDiffEntry[]) entries
-				.toArray(new ListDiffEntry[entries.size()])));
+		wrappedList.clear();
+		fireListChange(Diffs.createListDiff(entries));
 	}
 
 	/**
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SimplePropertyObservableMap.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SimplePropertyObservableMap.java
index ee1e56e..df7fd0d 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SimplePropertyObservableMap.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SimplePropertyObservableMap.java
@@ -8,6 +8,7 @@
  * Contributors:
  *     Matthew Hall - initial API and implementation (bug 194734)
  *     Matthew Hall - bugs 265561, 262287, 268203, 268688, 301774, 303847
+ *     Ovidio Mallo - bug 332367
  ******************************************************************************/
 
 package org.eclipse.core.internal.databinding.property.map;
@@ -184,8 +185,8 @@
 			getterCalled();
 			checkForComodification();
 
-			MapDiff diff = Diffs.createMapDiffSingleRemove(last.getKey(), last
-					.getValue());
+			MapDiff diff = Diffs.createMapDiffSingleRemove(last.getKey(),
+					last.getValue());
 			updateMap(map, diff);
 
 			iterator.remove(); // stay in sync
@@ -281,6 +282,17 @@
 		return oldValue;
 	}
 
+	public void clear() {
+		getterCalled();
+
+		Map map = getMap();
+		if (map.isEmpty())
+			return;
+
+		MapDiff diff = Diffs.createMapDiffRemoveAll(new HashMap(map));
+		updateMap(map, diff);
+	}
+
 	public Collection values() {
 		getterCalled();
 		// AbstractMap depends on entrySet() to fulfil values() API, so all