Bug 372181 - Working set support for Expressions View

- Fixed growth of working sets cache.
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ViewerStateTracker.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ViewerStateTracker.java
index 2ee05ca..cef8874 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ViewerStateTracker.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ViewerStateTracker.java
@@ -218,13 +218,17 @@
     void dispose() {
         Assert.isTrue( fContentProvider.getViewer().getDisplay().getThread() == Thread.currentThread() );        
 
-        for (Iterator itr = fPendingStateSaves.iterator(); itr.hasNext(); ) {
-            ((IElementMementoCollector)itr.next()).cancel();
+        IElementMementoCollector[] savesToCancel =  (IElementMementoCollector[])
+            fPendingStateSaves.toArray(new IElementMementoCollector[fPendingStateSaves.size()]);
+        for (int i = 0; i < savesToCancel.length; i++) {
+            savesToCancel[i].cancel();
         }
         fStateUpdateListeners.clear();
         
-        for (Iterator itr =  fCompareRequestsInProgress.values().iterator(); itr.hasNext();) {
-            ((ElementCompareRequest)itr.next()).cancel();
+        ElementCompareRequest[] requestsToCancel = (ElementCompareRequest[])
+            fCompareRequestsInProgress.values().toArray(new ElementCompareRequest[fCompareRequestsInProgress.size()]);
+        for (int i = 0; i < requestsToCancel.length; i++) {
+            requestsToCancel[i].cancel();
         }
         fCompareRequestsInProgress.clear();
         
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionView.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionView.java
index f5896f6..40f0470 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionView.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionView.java
@@ -14,10 +14,9 @@
 
  
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
+import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -108,6 +107,48 @@
     
 	private boolean fAutoSelectnWorkingSets = true;
 
+	/**
+     * Object used for comparing xml mementos in a map.
+     */
+    private static class XMLMementoKey {
+        final XMLMemento fMemento;
+        private String fKeyString;
+        
+        XMLMementoKey(XMLMemento memento) {
+            fMemento = memento;
+        }
+        
+        String getMementoString() {
+            if (fKeyString == null) {
+                StringWriter writer = new StringWriter();
+            
+                try {
+                    fMemento.save(writer);
+                    fKeyString = writer.toString();
+                } catch (IOException e) {
+                } finally {
+                }
+                fKeyString = fMemento.toString();
+            }
+            return fKeyString;
+        }
+        
+        public boolean equals(Object obj) {
+            if (obj instanceof XMLMementoKey) {
+                return getMementoString().equals(((XMLMementoKey)obj).getMementoString());
+            }
+            return false;
+        }
+        
+        public int hashCode() {
+            return getMementoString().hashCode();
+        }
+        
+        public String toString() {
+            return getMementoString();
+        }
+    }
+    
 	private Map fWorkingSetMementos = new LinkedHashMap(16, (float)0.75, true) {
 		private static final long serialVersionUID = 1L;
 
@@ -115,7 +156,7 @@
 			return size() > MAX_WORKING_SETS_MEMENTOS;
 		}
 	};
-    
+	
 	private Set fPendingCompareRequests;
 	
 	private ExpressionElementMementoRequest fPendingMementoRequest;
@@ -386,7 +427,7 @@
 		            InputStreamReader reader = new InputStreamReader(bin);
 		            try {
 		                XMLMemento workingSetsKey = XMLMemento.createReadRoot(reader);
-		                fWorkingSetMementos.put(workingSetsKey, workingSetNames);
+		                fWorkingSetMementos.put( new XMLMementoKey(workingSetsKey), workingSetNames );
 		            } catch (WorkbenchException e) {
 		            } finally {
 		                try {
@@ -418,30 +459,12 @@
     private void saveWorkingSetMementos(IMemento memento) {
     	for (Iterator itr = fWorkingSetMementos.entrySet().iterator(); itr.hasNext();) {
     		Map.Entry entry = (Map.Entry)itr.next();
-    		String keyMementoString = getMenentoString((XMLMemento)entry.getKey());
+    		String keyMementoString =  ((XMLMementoKey)entry.getKey()).getMementoString();
             IMemento workingSetsForElementMemento = memento.createChild(PREF_ELEMENT_WORKINGSET_MEMENTOS, keyMementoString);
             saveWorkingSets(workingSetsForElementMemento, (String[])entry.getValue());
     	}
     }
     
-    private String getMenentoString(XMLMemento memento) {
-		ByteArrayOutputStream bout = new ByteArrayOutputStream();
-		OutputStreamWriter writer = new OutputStreamWriter(bout);
-	
-		try {
-			memento.save(writer);
-			return bout.toString();
-		} catch (IOException e) {
-		} finally {
-			try {
-				writer.close();
-				bout.close();
-			} catch (IOException e) {
-			}
-		}
-		return null;
-    }
-    
     public void applyWorkingSets(IWorkingSet[] selectedWorkingSets) {
     	doApplyWorkingSets(selectedWorkingSets);
 		saveWorkingSetsForInput();
@@ -471,7 +494,7 @@
     
     void mementoRequestFinished(ExpressionElementMementoRequest request) {
 		if (!request.isCanceled()) {
-			fWorkingSetMementos.put(request.getMemento(), request.getWorkingSets());
+			fWorkingSetMementos.put(new XMLMementoKey((XMLMemento)request.getMemento()), request.getWorkingSets());
 		}    	
     }
     
@@ -528,7 +551,8 @@
 	        for (Iterator itr = fWorkingSetMementos.entrySet().iterator(); itr.hasNext();) {
 	        	Map.Entry entry = (Map.Entry)itr.next();
 	        	requests.add( new  ExpressionElementCompareRequest(
-	        			this, getPresentationContext(), source, (IMemento)entry.getKey(), (String[])entry.getValue()) );
+	        			this, getPresentationContext(), source, ((XMLMementoKey)entry.getKey()).fMemento, 
+	        			(String[])entry.getValue()) );
 	        }
 	
 			// cancel any pending update
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionWorkingSetMessages.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionWorkingSetMessages.java
index 93eceae..05aad78 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionWorkingSetMessages.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionWorkingSetMessages.java
@@ -16,7 +16,7 @@
 {
 	static
 	{
-		initializeMessages("org.eclipse.debug.internal.ui.expression.workingset.ExpressionWorkingSetMessages", //$NON-NLS-1$
+		initializeMessages("org.eclipse.debug.internal.ui.views.expression.ExpressionWorkingSetMessages", //$NON-NLS-1$
 				ExpressionWorkingSetMessages.class);
 	}