commit 7f5882da24a3341e6bce2ab1b2a7c281b999a64b
Author: Panagiotis Kanavos <pkanavos@gmail.com>
Date:   Thu Mar 1 18:57:15 2012 +0200

    Fixed loop limit bug in Task.TryRemove for the ObservableConcurrentCollection.
    Fixes #2131

diff --git a/trunk/Pithos.Client.WPF/Shell/ShellViewModel.cs b/trunk/Pithos.Client.WPF/Shell/ShellViewModel.cs
index f5c1ddb..d6a1e79 100644
--- a/trunk/Pithos.Client.WPF/Shell/ShellViewModel.cs
+++ b/trunk/Pithos.Client.WPF/Shell/ShellViewModel.cs
@@ -55,7 +55,6 @@ using Hardcodet.Wpf.TaskbarNotification;
 using Pithos.Client.WPF.Configuration;
 using Pithos.Client.WPF.FileProperties;
 using Pithos.Client.WPF.Preferences;
-using Pithos.Client.WPF.Properties;
 using Pithos.Client.WPF.SelectiveSynch;
 using Pithos.Client.WPF.Services;
 using Pithos.Client.WPF.Shell;
@@ -122,9 +121,9 @@ namespace Pithos.Client.WPF {
 		private static readonly log4net.ILog Log = log4net.LogManager.GetLogger("Pithos");
 
 		//Lazily initialized File Version info. This is done once and lazily to avoid blocking the UI
-		private Lazy<FileVersionInfo> _fileVersion;
+		private readonly Lazy<FileVersionInfo> _fileVersion;
 
-	    private PollAgent _pollAgent;
+	    private readonly PollAgent _pollAgent;
 
 		///<summary>
 		/// The Shell depends on MEF to provide implementations for windowManager, events, the status checker service and the settings
@@ -408,12 +407,22 @@ namespace Pithos.Client.WPF {
 
 		public void GoToSite(AccountInfo account)
 		{
-			/*var site = String.Format("{0}/ui/?token={1}&user={2}",
-				account.SiteUri,account.Token,
-				account.UserName);*/
 			Process.Start(account.SiteUri);
 		}
 
+        /// <summary>
+        /// Open an explorer window to the target path's directory
+        /// and select the file
+        /// </summary>
+        /// <param name="entry"></param>
+        public void GoToFile(FileEntry entry)
+        {
+            var fullPath = entry.FullPath;
+            if (!File.Exists(fullPath) && !Directory.Exists(fullPath))
+                return;
+            Process.Start("explorer.exe","/select, " + fullPath);
+        }
+
 		public void ShowFileProperties()
 		{
 			var account = Settings.Accounts.First(acc => acc.IsActive);            
@@ -623,7 +632,7 @@ namespace Pithos.Client.WPF {
 			Execute.OnUIThread(() =>
 								   {                                       
 									   var proxyAccount = IoC.Get<ProxyAccountViewModel>();
-										proxyAccount.Settings = this.Settings;
+										proxyAccount.Settings = Settings;
 									   if (true != _windowManager.ShowDialog(proxyAccount)) 
 										   return;
 									   StartMonitor(monitor, retries);
@@ -645,20 +654,7 @@ namespace Pithos.Client.WPF {
 		}
 
 
-
-		private static bool IsUnauthorized(WebException exc)
-		{
-			if (exc==null)
-				throw new ArgumentNullException("exc");
-			Contract.EndContractBlock();
-
-			var response = exc.Response as HttpWebResponse;
-			if (response == null)
-				return false;
-			return (response.StatusCode == HttpStatusCode.Unauthorized);
-		}
-
-		private void TryLater(PithosMonitor monitor, Exception exc,int retries)
+	    private void TryLater(PithosMonitor monitor, Exception exc,int retries)
 		{
 			var message = String.Format("An exception occured. Can't start monitoring\nWill retry in 10 seconds");
 			Task.Factory.StartNewDelayed(10000, () => StartMonitor(monitor,retries+1));
@@ -677,11 +673,14 @@ namespace Pithos.Client.WPF {
 
 		public void NotifyChangedFile(string filePath)
 		{
-			var entry = new FileEntry {FullPath=filePath};
+            if (RecentFiles.Any(e => e.FullPath == filePath))
+                return;
+            
 			IProducerConsumerCollection<FileEntry> files=RecentFiles;
 			FileEntry popped;
 			while (files.Count > 5)
 				files.TryTake(out popped);
+            var entry = new FileEntry { FullPath = filePath };
 			files.TryAdd(entry);
 		}
 
@@ -703,12 +702,14 @@ namespace Pithos.Client.WPF {
 		{
 			if (conflictFiles == null)
 				return;
-			if (!conflictFiles.Any())
+		    //Convert to list to avoid multiple iterations
+            var files = conflictFiles.ToList();
+			if (files.Count==0)
 				return;
 
 			UpdateStatus();
 			//TODO: Create a more specific message. For now, just show a warning
-			NotifyForFiles(conflictFiles,message,TraceLevel.Warning);
+			NotifyForFiles(files,message,TraceLevel.Warning);
 
 		}
 
@@ -743,6 +744,8 @@ namespace Pithos.Client.WPF {
 			if (Monitors.TryRemove(accountName, out monitor))
 			{
 				monitor.Stop();
+                //TODO: Also remove any pending actions for this account
+                //from the network queue                
 			}
 		}
 
@@ -790,7 +793,7 @@ namespace Pithos.Client.WPF {
 		}
 
 
-		private bool _pollStarted = false;
+		private bool _pollStarted;
 
 		//SMELL: Doing so much work for notifications in the shell is wrong
 		//The notifications should be moved to their own view/viewmodel pair
