Disabled batch filtering
authorPanagiotis Kanavos <pkanavos@gmail.com>
Mon, 18 Jun 2012 11:01:30 +0000 (14:01 +0300)
committerPanagiotis Kanavos <pkanavos@gmail.com>
Mon, 18 Jun 2012 11:01:30 +0000 (14:01 +0300)
trunk/Pithos.Core/Agents/FileAgent.cs
trunk/Pithos.Core/Agents/PollAgent.cs
trunk/Pithos.Core/PithosMonitor.cs

index 978ace2..20ef84e 100644 (file)
@@ -85,7 +85,7 @@ namespace Pithos.Core.Agents
         {
             var paths = fileEvents.Keys;
 
-            PollAgent.SynchNow(paths);
+            PollAgent.SynchNow(/*paths*/);
         }
 
 /*
index 875606e..33691ef 100644 (file)
@@ -206,7 +206,7 @@ namespace Pithos.Core.Agents
         /// </summary>\r
         public void SynchNow(IEnumerable<string> paths=null)\r
         {            \r
-            _batchQueue.Enqueue(paths);\r
+            //_batchQueue.Enqueue(paths);\r
             _syncEvent.Set();\r
         }\r
 \r
index 284e5ed..58f556d 100644 (file)
-#region
-/* -----------------------------------------------------------------------
- * <copyright file="PithosMonitor.cs" company="GRNet">
- * 
- * Copyright 2011-2012 GRNET S.A. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- *   1. Redistributions of source code must retain the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials
- *      provided with the distribution.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and
- * documentation are those of the authors and should not be
- * interpreted as representing official policies, either expressed
- * or implied, of GRNET S.A.
- * </copyright>
- * -----------------------------------------------------------------------
- */
-#endregion
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.Diagnostics.Contracts;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
-using Pithos.Core.Agents;
-using Pithos.Interfaces;
-using Pithos.Network;
-using log4net;
-
-namespace Pithos.Core
-{
-    [Export(typeof(PithosMonitor))]
-    public class PithosMonitor:IDisposable
-    {
-        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
-        private int _blockSize;
-        private string _blockHash;
-
-        [Import]
-        public IPithosSettings Settings{get;set;}
-
-        private IStatusKeeper _statusKeeper;
-
-        [Import]
-        public IStatusKeeper StatusKeeper
-        {
-            get { return _statusKeeper; }
-            set
-            {
-                _statusKeeper = value;
-                FileAgent.StatusKeeper = value;
-            }
-        }
-
-
-
-
-        private IPithosWorkflow _workflow;
-
-        [Import]
-        public IPithosWorkflow Workflow
-        {
-            get { return _workflow; }
-            set
-            {
-                _workflow = value;
-                FileAgent.Workflow = value;
-            }
-        }
-
-        public ICloudClient CloudClient { get; set; }
-
-        public IStatusNotification StatusNotification { get; set; }
-
-        //[Import]
-        public FileAgent FileAgent { get; private set; }
-
-/*
-        private WorkflowAgent _workflowAgent;
-
-        [Import]
-        public WorkflowAgent WorkflowAgent
-        {
-            get { return _workflowAgent; }
-            set
-            {
-                _workflowAgent = value;
-                //FileAgent.WorkflowAgent = value;
-            }
-        }
-*/
-        
-        [Import]
-        public NetworkAgent NetworkAgent { get; set; }
-
-        private PollAgent _pollAgent;
-
-        [Import]
-        public PollAgent PollAgent
-        {
-            get { return _pollAgent; }
-            set
-            {
-                _pollAgent = value;
-                FileAgent.PollAgent = value;
-            }
-        }
-
-        private Selectives _selectives;
-
-        [Import]
-        public Selectives Selectives
-        {
-            get { return _selectives; }
-            set
-            {
-                _selectives = value;
-                FileAgent.Selectives = value;
-            }
-        }
-
-        public string UserName { get; set; }
-        private string _apiKey;
-        public string ApiKey
-        {
-            get { return _apiKey; }
-            set
-            {
-                _apiKey = value;
-                if (_accountInfo != null)
-                    _accountInfo.Token = value;
-            }
-        }
-
-        private AccountInfo _accountInfo;
-
-        public AccountInfo Account
-        {
-            get { return _accountInfo; }
-        }
-
-
-
-
-
-        public bool Pause { get; set; }       
-        /*public bool Pause
-        {
-            get { return FileAgent.Pause; }
-            set
-            {
-                FileAgent.Pause = value;
-            }
-        }*/
-
-        private string _rootPath;
-        public string RootPath
-        {
-            get { return _rootPath; }
-            set 
-            {
-                _rootPath = String.IsNullOrWhiteSpace(value) 
-                    ? String.Empty 
-                    : value.ToLower();
-            }
-        }
-
-
-        CancellationTokenSource _cancellationSource;
-
-        public PithosMonitor()
-        {
-            FileAgent = new FileAgent();            
-        }
-        private bool _started;
-
-        public void Start()
-        {            
-            if (String.IsNullOrWhiteSpace(ApiKey))
-                throw new InvalidOperationException("The ApiKey is empty");
-            if (String.IsNullOrWhiteSpace(UserName))
-                throw new InvalidOperationException("The UserName is empty");
-            if (String.IsNullOrWhiteSpace(AuthenticationUrl))
-                throw new InvalidOperationException("The Authentication url is empty");
-            Contract.EndContractBlock();
-
-            //If the account doesn't have a valid path, don't start monitoring but don't throw either
-            if (String.IsNullOrWhiteSpace(RootPath))
-                //TODO; Warn user?
-                return;
-
-            //WorkflowAgent.StatusNotification = StatusNotification;
-
-            StatusNotification.NotifyChange("Starting");
-            if (_started)
-            {
-                if (!_cancellationSource.IsCancellationRequested)
-                    return;
-            }
-            _cancellationSource = new CancellationTokenSource();
-
-            lock (this)
-            {
-                CloudClient = new CloudFilesClient(UserName, ApiKey)
-                                  {UsePithos = true, AuthenticationUrl = AuthenticationUrl};
-                _accountInfo = CloudClient.Authenticate();
-            }
-            _accountInfo.SiteUri = AuthenticationUrl;
-            _accountInfo.AccountPath = RootPath;
-
-
-            var pithosFolder = Path.Combine(RootPath, FolderConstants.PithosContainer);
-            if (!Directory.Exists(pithosFolder))
-                Directory.CreateDirectory(pithosFolder);
-            //Create the cache folder and ensure it is hidden
-            CreateHiddenFolder(RootPath, FolderConstants.CacheFolder);
-
-            var policy=CloudClient.GetAccountPolicies(_accountInfo);
-
-            StatusNotification.NotifyAccount(policy);
-            EnsurePithosContainers();
-            
-            StatusKeeper.BlockHash = _blockHash;
-            StatusKeeper.BlockSize = _blockSize;
-            
-            StatusKeeper.StartProcessing(_cancellationSource.Token);
-            CleanupUnselectedStates();
-            IndexLocalFiles();
-            //Extract the URIs from the string collection
-            var settings = Settings.Accounts.First(s => s.AccountKey == _accountInfo.AccountKey );
-                            
-            var selectiveUrls=settings.SelectiveFolders.Cast<string>().Select(url => new Uri(url,UriKind.RelativeOrAbsolute))
-                .Where(uri=>uri.IsAbsoluteUri).ToArray();
-
-            SetSelectivePaths(selectiveUrls,null,null);
-            
-            StartWatcherAgent();
-
-            StartNetworkAgent();
-            
-            //WorkflowAgent.RestartInterruptedFiles(_accountInfo);
-            _started = true;
-        }
-
-        private void EnsurePithosContainers()
-        {
-
-            //Create the two default containers if they are missing
-            var pithosContainers = new List<string>{ FolderConstants.TrashContainer,FolderConstants.PithosContainer};
-            foreach (var container in pithosContainers)
-            {                
-                var info=CloudClient.GetContainerInfo(UserName, container);
-                if (info == ContainerInfo.Empty)
-                {
-                    CloudClient.CreateContainer(UserName, container);
-                    info = CloudClient.GetContainerInfo(UserName, container);
-                }
-                _blockSize = info.BlockSize;
-                _blockHash = info.BlockHash;
-                _accountInfo.BlockSize = _blockSize;
-                _accountInfo.BlockHash = _blockHash;
-            }
-        }
-
-        public string AuthenticationUrl { get; set; }
-
-        private void IndexLocalFiles()
-        {
-            using (ThreadContext.Stacks["Operation"].Push("Indexing local files"))
-            {
-                
-                try
-                {
-                    //StatusNotification.NotifyChange("Indexing Local Files");
-                    Log.Info("Start local indexing");
-                    StatusNotification.SetPithosStatus(PithosStatus.LocalSyncing,"Indexing Local Files");                    
-
-                    var cachePath = Path.Combine(RootPath, FolderConstants.CacheFolder);
-                    var directory = new DirectoryInfo(RootPath);
-                    var files =
-                        from file in directory.EnumerateFiles("*", SearchOption.AllDirectories)
-                        where !file.FullName.StartsWith(cachePath, StringComparison.InvariantCultureIgnoreCase) &&
-                              !file.Extension.Equals("ignore", StringComparison.InvariantCultureIgnoreCase)
-                        select file;
-                    StatusKeeper.ProcessExistingFiles(files);
-
-                }
-                catch (Exception exc)
-                {
-                    Log.Error("[ERROR]", exc);
-                }
-                finally
-                {
-                    Log.Info("[END]");
-                }
-                StatusNotification.SetPithosStatus(PithosStatus.LocalComplete,"Indexing Completed");
-            }
-        }
-
-        
-  
-
-
-       /* private void StartWorkflowAgent()
-        {
-            WorkflowAgent.StatusNotification = StatusNotification;
-
-/*            //On Vista and up we can check for a network connection
-            bool connected=Environment.OSVersion.Version.Major < 6 || NetworkListManager.IsConnectedToInternet;
-            //If we are not connected retry later
-            if (!connected)
-            {
-                Task.Factory.StartNewDelayed(10000, StartWorkflowAgent);
-                return;
-            }#1#
-
-            try
-            {
-                WorkflowAgent.Start();                
-            }
-            catch (Exception)
-            {
-                //Faild to authenticate due to network or account error
-                //Retry after a while
-                Task.Factory.StartNewDelayed(10000, StartWorkflowAgent);
-            }
-        }*/
-
-
-        private void StartNetworkAgent()
-        {
-            NetworkAgent.StatusNotification = StatusNotification;
-
-            //TODO: The Network and Poll agents are not account specific
-            //They should be moved outside PithosMonitor
-/*
-            NetworkAgent.Start();
-*/
-
-            PollAgent.AddAccount(_accountInfo);
-
-            PollAgent.StatusNotification = StatusNotification;
-
-            PollAgent.PollRemoteFiles();
-        }
-
-        //Make sure a hidden cache folder exists to store partial downloads
-        private static void CreateHiddenFolder(string rootPath, string folderName)
-        {
-            if (String.IsNullOrWhiteSpace(rootPath))
-                throw new ArgumentNullException("rootPath");
-            if (!Path.IsPathRooted(rootPath))
-                throw new ArgumentException("rootPath");
-            if (String.IsNullOrWhiteSpace(folderName))
-                throw new ArgumentNullException("folderName");
-            Contract.EndContractBlock();
-
-            var folder = Path.Combine(rootPath, folderName);
-            if (!Directory.Exists(folder))
-            {
-                var info = Directory.CreateDirectory(folder);
-                info.Attributes |= FileAttributes.Hidden;
-
-                Log.InfoFormat("Created cache Folder: {0}", folder);
-            }
-            else
-            {
-                var info = new DirectoryInfo(folder);
-                if ((info.Attributes & FileAttributes.Hidden) == 0)
-                {
-                    info.Attributes |= FileAttributes.Hidden;
-                    Log.InfoFormat("Reset cache folder to hidden: {0}", folder);
-                }                                
-            }
-        }
-
-       
-
-
-        private void StartWatcherAgent()
-        {
-            if (Log.IsDebugEnabled)
-                Log.DebugFormat("Start Folder Monitoring [{0}]",RootPath);
-
-            AgentLocator<FileAgent>.Register(FileAgent,RootPath);
-            
-            FileAgent.IdleTimeout = Settings.FileIdleTimeout;
-            FileAgent.StatusKeeper = StatusKeeper;
-            FileAgent.StatusNotification = StatusNotification;
-            FileAgent.Workflow = Workflow;
-            FileAgent.CachePath = Path.Combine(RootPath, FolderConstants.CacheFolder);
-            FileAgent.Start(_accountInfo, RootPath);
-        }
-
-        public void Stop()
-        {
-/*
-            AgentLocator<FileAgent>.Remove(RootPath);
-
-            if (FileAgent!=null)
-                FileAgent.Stop();
-            FileAgent = null;
-*/
-        }
-
-
-        ~PithosMonitor()
-        {
-            Dispose(false);
-        }
-
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                Stop();
-            }
-        }
-
-
-        public void MoveFileStates(string oldPath, string newPath)
-        {
-            if (String.IsNullOrWhiteSpace(oldPath))
-                throw new ArgumentNullException("oldPath");
-            if (!Path.IsPathRooted(oldPath))
-                throw new ArgumentException("oldPath must be an absolute path","oldPath");
-            if (string.IsNullOrWhiteSpace(newPath))
-                throw new ArgumentNullException("newPath");
-            if (!Path.IsPathRooted(newPath))
-                throw new ArgumentException("newPath must be an absolute path","newPath");
-            Contract.EndContractBlock();
-
-            StatusKeeper.ChangeRoots(oldPath, newPath);
-        }
-
-        private void CleanupUnselectedStates()
-        {
-            //var settings = Settings.Accounts.First(s => s.AccountKey == _accountInfo.AccountKey);
-            if (!Selectives.IsSelectiveEnabled(_accountInfo.AccountKey)) return;
-
-            List<string> selectivePaths;
-            if (Selectives.SelectivePaths.TryGetValue(_accountInfo.AccountKey, out selectivePaths))
+#region\r
+/* -----------------------------------------------------------------------\r
+ * <copyright file="PithosMonitor.cs" company="GRNet">\r
+ * \r
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ *   1. Redistributions of source code must retain the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer.\r
+ *\r
+ *   2. Redistributions in binary form must reproduce the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer in the documentation and/or other materials\r
+ *      provided with the distribution.\r
+ *\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS\r
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\r
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * The views and conclusions contained in the software and\r
+ * documentation are those of the authors and should not be\r
+ * interpreted as representing official policies, either expressed\r
+ * or implied, of GRNET S.A.\r
+ * </copyright>\r
+ * -----------------------------------------------------------------------\r
+ */\r
+#endregion\r
+using System;\r
+using System.Collections.Generic;\r
+using System.ComponentModel.Composition;\r
+using System.Diagnostics.Contracts;\r
+using System.IO;\r
+using System.Linq;\r
+using System.Reflection;\r
+using System.Threading;\r
+using System.Threading.Tasks;\r
+using Pithos.Core.Agents;\r
+using Pithos.Interfaces;\r
+using Pithos.Network;\r
+using log4net;\r
+\r
+namespace Pithos.Core\r
+{\r
+    [Export(typeof(PithosMonitor))]\r
+    public class PithosMonitor:IDisposable\r
+    {\r
+        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);\r
+\r
+        private int _blockSize;\r
+        private string _blockHash;\r
+\r
+        [Import]\r
+        public IPithosSettings Settings{get;set;}\r
+\r
+        private IStatusKeeper _statusKeeper;\r
+\r
+        [Import]\r
+        public IStatusKeeper StatusKeeper\r
+        {\r
+            get { return _statusKeeper; }\r
+            set\r
+            {\r
+                _statusKeeper = value;\r
+                FileAgent.StatusKeeper = value;\r
+            }\r
+        }\r
+\r
+\r
+\r
+\r
+        private IPithosWorkflow _workflow;\r
+\r
+        [Import]\r
+        public IPithosWorkflow Workflow\r
+        {\r
+            get { return _workflow; }\r
+            set\r
+            {\r
+                _workflow = value;\r
+                FileAgent.Workflow = value;\r
+            }\r
+        }\r
+\r
+        public ICloudClient CloudClient { get; set; }\r
+\r
+        public IStatusNotification StatusNotification { get; set; }\r
+\r
+        //[Import]\r
+        public FileAgent FileAgent { get; private set; }\r
+\r
+/*\r
+        private WorkflowAgent _workflowAgent;\r
+\r
+        [Import]\r
+        public WorkflowAgent WorkflowAgent\r
+        {\r
+            get { return _workflowAgent; }\r
+            set\r
+            {\r
+                _workflowAgent = value;\r
+                //FileAgent.WorkflowAgent = value;\r
+            }\r
+        }\r
+*/\r
+        \r
+        [Import]\r
+        public NetworkAgent NetworkAgent { get; set; }\r
+\r
+        private PollAgent _pollAgent;\r
+\r
+        [Import]\r
+        public PollAgent PollAgent\r
+        {\r
+            get { return _pollAgent; }\r
+            set\r
+            {\r
+                _pollAgent = value;\r
+                FileAgent.PollAgent = value;\r
+            }\r
+        }\r
+\r
+        private Selectives _selectives;\r
+\r
+        [Import]\r
+        public Selectives Selectives\r
+        {\r
+            get { return _selectives; }\r
+            set\r
+            {\r
+                _selectives = value;\r
+                FileAgent.Selectives = value;\r
+            }\r
+        }\r
+\r
+        public string UserName { get; set; }\r
+        private string _apiKey;\r
+        public string ApiKey\r
+        {\r
+            get { return _apiKey; }\r
+            set\r
+            {\r
+                _apiKey = value;\r
+                if (_accountInfo != null)\r
+                    _accountInfo.Token = value;\r
+            }\r
+        }\r
+\r
+        private AccountInfo _accountInfo;\r
+\r
+        public AccountInfo Account\r
+        {\r
+            get { return _accountInfo; }\r
+        }\r
+\r
+\r
+\r
+\r
+\r
+        public bool Pause { get; set; }       \r
+        /*public bool Pause\r
+        {\r
+            get { return FileAgent.Pause; }\r
+            set\r
+            {\r
+                FileAgent.Pause = value;\r
+            }\r
+        }*/\r
+\r
+        private string _rootPath;\r
+        public string RootPath\r
+        {\r
+            get { return _rootPath; }\r
+            set \r
+            {\r
+                _rootPath = String.IsNullOrWhiteSpace(value) \r
+                    ? String.Empty \r
+                    : value.ToLower();\r
+            }\r
+        }\r
+\r
+\r
+        CancellationTokenSource _cancellationSource;\r
+\r
+        public PithosMonitor()\r
+        {\r
+            FileAgent = new FileAgent();            \r
+        }\r
+        private bool _started;\r
+\r
+        public void Start()\r
+        {            \r
+            if (String.IsNullOrWhiteSpace(ApiKey))\r
+                throw new InvalidOperationException("The ApiKey is empty");\r
+            if (String.IsNullOrWhiteSpace(UserName))\r
+                throw new InvalidOperationException("The UserName is empty");\r
+            if (String.IsNullOrWhiteSpace(AuthenticationUrl))\r
+                throw new InvalidOperationException("The Authentication url is empty");\r
+            Contract.EndContractBlock();\r
+\r
+            //If the account doesn't have a valid path, don't start monitoring but don't throw either\r
+            if (String.IsNullOrWhiteSpace(RootPath))\r
+                //TODO; Warn user?\r
+                return;\r
+\r
+            //WorkflowAgent.StatusNotification = StatusNotification;\r
+\r
+            StatusNotification.NotifyChange("Starting");\r
+            if (_started)\r
+            {\r
+                if (!_cancellationSource.IsCancellationRequested)\r
+                    return;\r
+            }\r
+            _cancellationSource = new CancellationTokenSource();\r
+\r
+            lock (this)\r
+            {\r
+                CloudClient = new CloudFilesClient(UserName, ApiKey)\r
+                                  {UsePithos = true, AuthenticationUrl = AuthenticationUrl};\r
+                _accountInfo = CloudClient.Authenticate();\r
+            }\r
+            _accountInfo.SiteUri = AuthenticationUrl;\r
+            _accountInfo.AccountPath = RootPath;\r
+\r
+\r
+            var pithosFolder = Path.Combine(RootPath, FolderConstants.PithosContainer);\r
+            if (!Directory.Exists(pithosFolder))\r
+                Directory.CreateDirectory(pithosFolder);\r
+            //Create the cache folder and ensure it is hidden\r
+            CreateHiddenFolder(RootPath, FolderConstants.CacheFolder);\r
+\r
+            var policy=CloudClient.GetAccountPolicies(_accountInfo);\r
+\r
+            StatusNotification.NotifyAccount(policy);\r
+            EnsurePithosContainers();\r
+            \r
+            StatusKeeper.BlockHash = _blockHash;\r
+            StatusKeeper.BlockSize = _blockSize;\r
+            \r
+            StatusKeeper.StartProcessing(_cancellationSource.Token);\r
+            CleanupUnselectedStates();\r
+            IndexLocalFiles();\r
+            //Extract the URIs from the string collection\r
+            var settings = Settings.Accounts.First(s => s.AccountKey == _accountInfo.AccountKey );\r
+                            \r
+            var selectiveUrls=settings.SelectiveFolders.Cast<string>().Select(url => new Uri(url,UriKind.RelativeOrAbsolute))\r
+                .Where(uri=>uri.IsAbsoluteUri).ToArray();\r
+\r
+            SetSelectivePaths(selectiveUrls,null,null);\r
+            \r
+            StartWatcherAgent();\r
+\r
+            StartNetworkAgent();\r
+            \r
+            //WorkflowAgent.RestartInterruptedFiles(_accountInfo);\r
+            _started = true;\r
+        }\r
+\r
+        private void EnsurePithosContainers()\r
+        {\r
+\r
+            //Create the two default containers if they are missing\r
+            var pithosContainers = new List<string>{ FolderConstants.TrashContainer,FolderConstants.PithosContainer};\r
+            foreach (var container in pithosContainers)\r
+            {                \r
+                var info=CloudClient.GetContainerInfo(UserName, container);\r
+                if (info == ContainerInfo.Empty)\r
+                {\r
+                    CloudClient.CreateContainer(UserName, container);\r
+                    info = CloudClient.GetContainerInfo(UserName, container);\r
+                }\r
+                _blockSize = info.BlockSize;\r
+                _blockHash = info.BlockHash;\r
+                _accountInfo.BlockSize = _blockSize;\r
+                _accountInfo.BlockHash = _blockHash;\r
+            }\r
+        }\r
+\r
+        public string AuthenticationUrl { get; set; }\r
+\r
+        private void IndexLocalFiles()\r
+        {\r
+            using (ThreadContext.Stacks["Operation"].Push("Indexing local files"))\r
+            {\r
+                \r
+                try\r
+                {\r
+                    //StatusNotification.NotifyChange("Indexing Local Files");\r
+                    Log.Info("Start local indexing");\r
+                    StatusNotification.SetPithosStatus(PithosStatus.LocalSyncing,"Indexing Local Files");                    \r
+\r
+                    var cachePath = Path.Combine(RootPath, FolderConstants.CacheFolder);\r
+                    var directory = new DirectoryInfo(RootPath);\r
+                    var files =\r
+                        from file in directory.EnumerateFiles("*", SearchOption.AllDirectories)\r
+                        where !file.FullName.StartsWith(cachePath, StringComparison.InvariantCultureIgnoreCase) &&\r
+                              !file.Extension.Equals("ignore", StringComparison.InvariantCultureIgnoreCase)\r
+                        select file;\r
+                    StatusKeeper.ProcessExistingFiles(files);\r
+\r
+                }\r
+                catch (Exception exc)\r
+                {\r
+                    Log.Error("[ERROR]", exc);\r
+                }\r
+                finally\r
+                {\r
+                    Log.Info("[END]");\r
+                }\r
+                StatusNotification.SetPithosStatus(PithosStatus.LocalComplete,"Indexing Completed");\r
+            }\r
+        }\r
+\r
+        \r
+  \r
+\r
+\r
+       /* private void StartWorkflowAgent()\r
+        {\r
+            WorkflowAgent.StatusNotification = StatusNotification;\r
+\r
+/*            //On Vista and up we can check for a network connection\r
+            bool connected=Environment.OSVersion.Version.Major < 6 || NetworkListManager.IsConnectedToInternet;\r
+            //If we are not connected retry later\r
+            if (!connected)\r
+            {\r
+                Task.Factory.StartNewDelayed(10000, StartWorkflowAgent);\r
+                return;\r
+            }#1#\r
+\r
+            try\r
+            {\r
+                WorkflowAgent.Start();                \r
+            }\r
+            catch (Exception)\r
+            {\r
+                //Faild to authenticate due to network or account error\r
+                //Retry after a while\r
+                Task.Factory.StartNewDelayed(10000, StartWorkflowAgent);\r
+            }\r
+        }*/\r
+\r
+\r
+        private void StartNetworkAgent()\r
+        {\r
+            NetworkAgent.StatusNotification = StatusNotification;\r
+\r
+            //TODO: The Network and Poll agents are not account specific\r
+            //They should be moved outside PithosMonitor\r
+/*\r
+            NetworkAgent.Start();\r
+*/\r
+\r
+            PollAgent.AddAccount(_accountInfo);\r
+\r
+            PollAgent.StatusNotification = StatusNotification;\r
+\r
+            PollAgent.PollRemoteFiles();\r
+        }\r
+\r
+        //Make sure a hidden cache folder exists to store partial downloads\r
+        private static void CreateHiddenFolder(string rootPath, string folderName)\r
+        {\r
+            if (String.IsNullOrWhiteSpace(rootPath))\r
+                throw new ArgumentNullException("rootPath");\r
+            if (!Path.IsPathRooted(rootPath))\r
+                throw new ArgumentException("rootPath");\r
+            if (String.IsNullOrWhiteSpace(folderName))\r
+                throw new ArgumentNullException("folderName");\r
+            Contract.EndContractBlock();\r
+\r
+            var folder = Path.Combine(rootPath, folderName);\r
+            if (!Directory.Exists(folder))\r
+            {\r
+                var info = Directory.CreateDirectory(folder);\r
+                info.Attributes |= FileAttributes.Hidden;\r
+\r
+                Log.InfoFormat("Created cache Folder: {0}", folder);\r
+            }\r
+            else\r
+            {\r
+                var info = new DirectoryInfo(folder);\r
+                if ((info.Attributes & FileAttributes.Hidden) == 0)\r
+                {\r
+                    info.Attributes |= FileAttributes.Hidden;\r
+                    Log.InfoFormat("Reset cache folder to hidden: {0}", folder);\r
+                }                                \r
+            }\r
+        }\r
+\r
+       \r
+\r
+\r
+        private void StartWatcherAgent()\r
+        {\r
+            if (Log.IsDebugEnabled)\r
+                Log.DebugFormat("Start Folder Monitoring [{0}]",RootPath);\r
+\r
+            AgentLocator<FileAgent>.Register(FileAgent,RootPath);\r
+            \r
+            FileAgent.IdleTimeout = Settings.FileIdleTimeout;\r
+            FileAgent.StatusKeeper = StatusKeeper;\r
+            FileAgent.StatusNotification = StatusNotification;\r
+            FileAgent.Workflow = Workflow;\r
+            FileAgent.CachePath = Path.Combine(RootPath, FolderConstants.CacheFolder);\r
+            FileAgent.Start(_accountInfo, RootPath);\r
+        }\r
+\r
+        public void Stop()\r
+        {\r
+/*\r
+            AgentLocator<FileAgent>.Remove(RootPath);\r
+\r
+            if (FileAgent!=null)\r
+                FileAgent.Stop();\r
+            FileAgent = null;\r
+*/\r
+        }\r
+\r
+\r
+        ~PithosMonitor()\r
+        {\r
+            Dispose(false);\r
+        }\r
+\r
+        public void Dispose()\r
+        {\r
+            Dispose(true);\r
+            GC.SuppressFinalize(this);\r
+        }\r
+\r
+        protected virtual void Dispose(bool disposing)\r
+        {\r
+            if (disposing)\r
+            {\r
+                Stop();\r
+            }\r
+        }\r
+\r
+\r
+        public void MoveFileStates(string oldPath, string newPath)\r
+        {\r
+            if (String.IsNullOrWhiteSpace(oldPath))\r
+                throw new ArgumentNullException("oldPath");\r
+            if (!Path.IsPathRooted(oldPath))\r
+                throw new ArgumentException("oldPath must be an absolute path","oldPath");\r
+            if (string.IsNullOrWhiteSpace(newPath))\r
+                throw new ArgumentNullException("newPath");\r
+            if (!Path.IsPathRooted(newPath))\r
+                throw new ArgumentException("newPath must be an absolute path","newPath");\r
+            Contract.EndContractBlock();\r
+\r
+            StatusKeeper.ChangeRoots(oldPath, newPath);\r
+        }\r
+\r
+        private void CleanupUnselectedStates()\r
+        {\r
+            //var settings = Settings.Accounts.First(s => s.AccountKey == _accountInfo.AccountKey);\r
+            if (!Selectives.IsSelectiveEnabled(_accountInfo.AccountKey)) return;\r
+\r
+            List<string> selectivePaths;\r
+            if (Selectives.SelectivePaths.TryGetValue(_accountInfo.AccountKey, out selectivePaths))\r
             {\r
                 var statePaths= FileState.Queryable.Select(state => state.FilePath).ToList();\r
-                var removedPaths = statePaths.Where(sp => !selectivePaths.Any(sp.IsAtOrBelow));
-
-                UnversionSelectivePaths(removedPaths.ToList());
-            }
-            else
-            {
-                StatusKeeper.ClearFolderStatus(Account.AccountPath);
-            }
-        }
-
-        public void SetSelectivePaths(Uri[] uris,Uri[] added, Uri[] removed)
-        {
-            //Convert the uris to paths
-            //var selectivePaths = UrisToFilePaths(uris);
-            
-            var selectiveUri = uris.ToList();
-            this.Selectives.SetSelectedUris(_accountInfo,selectiveUri);
-
-            var removedPaths = UrisToFilePaths(removed);
-            UnversionSelectivePaths(removedPaths);
-
-        }
-
-        /// <summary>
-        /// Mark all unselected paths as Unversioned
-        /// </summary>
-        /// <param name="removed"></param>
-        private void UnversionSelectivePaths(List<string> removed)
-        {
-            if (removed == null)
-                return;
-
-            //Ensure we remove any file state below the deleted folders
-            FileState.UnversionPaths(removed);
-        }
-
-
-        /// <summary>
-        /// Return a list of absolute filepaths from a list of Uris
-        /// </summary>
-        /// <param name="uris"></param>
-        /// <returns></returns>
-        public List<string> UrisToFilePaths(IEnumerable<Uri> uris)
-        {
-            if (uris == null)
-                return new List<string>();
-
-            var own = (from uri in uris
-                       where uri.ToString().StartsWith(_accountInfo.StorageUri.ToString())
-                                   let relativePath = _accountInfo.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()
-                                   //Trim the account name
-                                   select Path.Combine(RootPath, relativePath.After(_accountInfo.UserName + '\\'))).ToList();
-            var others= (from uri in uris
-                         where !uri.ToString().StartsWith(_accountInfo.StorageUri.ToString())
-                                   let relativePath = _accountInfo.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()
-                                   //Trim the account name
-                                   select Path.Combine(RootPath,"others-shared", relativePath)).ToList();
-            return own.Union(others).ToList();            
-        }
-
-
-        public ObjectInfo GetObjectInfo(string filePath)
-        {
-            if (String.IsNullOrWhiteSpace(filePath))
-                throw new ArgumentNullException("filePath");
-            Contract.EndContractBlock();
-
-            var file=new FileInfo(filePath);
-            string relativeUrl;//=file.AsRelativeUrlTo(this.RootPath);
-            var relativePath = file.AsRelativeTo(RootPath);
-            
-            string accountName,container;
-            
-            var parts=relativePath.Split('\\');
-
-            var accountInfo = _accountInfo;
-            if (relativePath.StartsWith(FolderConstants.OthersFolder))
-            {                
-                accountName = parts[1];
-                container = parts[2];
-                relativeUrl = String.Join("/", parts.Splice(3));
-                //Create the root URL for the target account
-                var oldName = UserName;
-                var absoluteUri =  _accountInfo.StorageUri.AbsoluteUri;
-                var nameIndex=absoluteUri.IndexOf(oldName, StringComparison.Ordinal);
-                var root=absoluteUri.Substring(0, nameIndex);
-
-                accountInfo = new AccountInfo
-                {
-                    UserName = accountName,
-                    AccountPath = Path.Combine(accountInfo.AccountPath, parts[0], parts[1]),
-                    StorageUri = new Uri(root + accountName),
-                    BlockHash=accountInfo.BlockHash,
-                    BlockSize=accountInfo.BlockSize,
-                    Token=accountInfo.Token
-                };
-            }
-            else
-            {
-                accountName = UserName;
-                container = parts[0];
-                relativeUrl = String.Join("/", parts.Splice(1));
-            }
-            
-            var client = new CloudFilesClient(accountInfo);
-            var objectInfo=client.GetObjectInfo(accountName, container, relativeUrl);
-            return objectInfo;
-        }
-        
-        public Task<ContainerInfo> GetContainerInfo(string filePath)
-        {
-            if (String.IsNullOrWhiteSpace(filePath))
-                throw new ArgumentNullException("filePath");
-            Contract.EndContractBlock();
-
-            var file=new FileInfo(filePath);
-            var relativePath = file.AsRelativeTo(RootPath);
-            
-            string accountName,container;
-            
-            var parts=relativePath.Split('\\');
-
-            var accountInfo = _accountInfo;
-            if (relativePath.StartsWith(FolderConstants.OthersFolder))
-            {                
-                accountName = parts[1];
-                container = parts[2];                
-                //Create the root URL for the target account
-                var oldName = UserName;
-                var absoluteUri =  _accountInfo.StorageUri.AbsoluteUri;
-                var nameIndex=absoluteUri.IndexOf(oldName, StringComparison.Ordinal);
-                var root=absoluteUri.Substring(0, nameIndex);
-
-                accountInfo = new AccountInfo
-                {
-                    UserName = accountName,
-                    AccountPath = Path.Combine(accountInfo.AccountPath, parts[0], parts[1]),
-                    StorageUri = new Uri(root + accountName),
-                    BlockHash=accountInfo.BlockHash,
-                    BlockSize=accountInfo.BlockSize,
-                    Token=accountInfo.Token
-                };
-            }
-            else
-            {
-                accountName = UserName;
-                container = parts[0];                
-            }
-
-            return Task.Factory.StartNew(() =>
-            {
-                var client = new CloudFilesClient(accountInfo);
-                var containerInfo = client.GetContainerInfo(accountName, container);
-                return containerInfo;
-            });
-        }
-    }
-}
+                var removedPaths = statePaths.Where(sp => !selectivePaths.Any(sp.IsAtOrBelow));\r
+\r
+                UnversionSelectivePaths(removedPaths.ToList());\r
+            }\r
+            else\r
+            {\r
+                StatusKeeper.ClearFolderStatus(Account.AccountPath);\r
+            }\r
+        }\r
+\r
+        public void SetSelectivePaths(Uri[] uris,Uri[] added, Uri[] removed)\r
+        {\r
+            //Convert the uris to paths\r
+            //var selectivePaths = UrisToFilePaths(uris);\r
+            \r
+            var selectiveUri = uris.ToList();\r
+            this.Selectives.SetSelectedUris(_accountInfo,selectiveUri);\r
+\r
+            var removedPaths = UrisToFilePaths(removed);\r
+            UnversionSelectivePaths(removedPaths);\r
+\r
+        }\r
+\r
+        /// <summary>\r
+        /// Mark all unselected paths as Unversioned\r
+        /// </summary>\r
+        /// <param name="removed"></param>\r
+        private void UnversionSelectivePaths(List<string> removed)\r
+        {\r
+            if (removed == null)\r
+                return;\r
+\r
+            //Ensure we remove any file state below the deleted folders\r
+            FileState.UnversionPaths(removed);\r
+        }\r
+\r
+\r
+        /// <summary>\r
+        /// Return a list of absolute filepaths from a list of Uris\r
+        /// </summary>\r
+        /// <param name="uris"></param>\r
+        /// <returns></returns>\r
+        public List<string> UrisToFilePaths(IEnumerable<Uri> uris)\r
+        {\r
+            if (uris == null)\r
+                return new List<string>();\r
+\r
+            var own = (from uri in uris\r
+                       where uri.ToString().StartsWith(_accountInfo.StorageUri.ToString())\r
+                                   let relativePath = _accountInfo.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()\r
+                                   //Trim the account name\r
+                                   select Path.Combine(RootPath, relativePath.After(_accountInfo.UserName + '\\'))).ToList();\r
+            var others= (from uri in uris\r
+                         where !uri.ToString().StartsWith(_accountInfo.StorageUri.ToString())\r
+                                   let relativePath = _accountInfo.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()\r
+                                   //Trim the account name\r
+                                   select Path.Combine(RootPath,"others-shared", relativePath)).ToList();\r
+            return own.Union(others).ToList();            \r
+        }\r
+\r
+\r
+        public ObjectInfo GetObjectInfo(string filePath)\r
+        {\r
+            if (String.IsNullOrWhiteSpace(filePath))\r
+                throw new ArgumentNullException("filePath");\r
+            Contract.EndContractBlock();\r
+\r
+            var file=new FileInfo(filePath);\r
+            string relativeUrl;//=file.AsRelativeUrlTo(this.RootPath);\r
+            var relativePath = file.AsRelativeTo(RootPath);\r
+            \r
+            string accountName,container;\r
+            \r
+            var parts=relativePath.Split('\\');\r
+\r
+            var accountInfo = _accountInfo;\r
+            if (relativePath.StartsWith(FolderConstants.OthersFolder))\r
+            {                \r
+                accountName = parts[1];\r
+                container = parts[2];\r
+                relativeUrl = String.Join("/", parts.Splice(3));\r
+                //Create the root URL for the target account\r
+                var oldName = UserName;\r
+                var absoluteUri =  _accountInfo.StorageUri.AbsoluteUri;\r
+                var nameIndex=absoluteUri.IndexOf(oldName, StringComparison.Ordinal);\r
+                var root=absoluteUri.Substring(0, nameIndex);\r
+\r
+                accountInfo = new AccountInfo\r
+                {\r
+                    UserName = accountName,\r
+                    AccountPath = Path.Combine(accountInfo.AccountPath, parts[0], parts[1]),\r
+                    StorageUri = new Uri(root + accountName),\r
+                    BlockHash=accountInfo.BlockHash,\r
+                    BlockSize=accountInfo.BlockSize,\r
+                    Token=accountInfo.Token\r
+                };\r
+            }\r
+            else\r
+            {\r
+                accountName = UserName;\r
+                container = parts[0];\r
+                relativeUrl = String.Join("/", parts.Splice(1));\r
+            }\r
+            \r
+            var client = new CloudFilesClient(accountInfo);\r
+            var objectInfo=client.GetObjectInfo(accountName, container, relativeUrl);\r
+            return objectInfo;\r
+        }\r
+        \r
+        public Task<ContainerInfo> GetContainerInfo(string filePath)\r
+        {\r
+            if (String.IsNullOrWhiteSpace(filePath))\r
+                throw new ArgumentNullException("filePath");\r
+            Contract.EndContractBlock();\r
+\r
+            var file=new FileInfo(filePath);\r
+            var relativePath = file.AsRelativeTo(RootPath);\r
+            \r
+            string accountName,container;\r
+            \r
+            var parts=relativePath.Split('\\');\r
+\r
+            var accountInfo = _accountInfo;\r
+            if (relativePath.StartsWith(FolderConstants.OthersFolder))\r
+            {                \r
+                accountName = parts[1];\r
+                container = parts[2];                \r
+                //Create the root URL for the target account\r
+                var oldName = UserName;\r
+                var absoluteUri =  _accountInfo.StorageUri.AbsoluteUri;\r
+                var nameIndex=absoluteUri.IndexOf(oldName, StringComparison.Ordinal);\r
+                var root=absoluteUri.Substring(0, nameIndex);\r
+\r
+                accountInfo = new AccountInfo\r
+                {\r
+                    UserName = accountName,\r
+                    AccountPath = Path.Combine(accountInfo.AccountPath, parts[0], parts[1]),\r
+                    StorageUri = new Uri(root + accountName),\r
+                    BlockHash=accountInfo.BlockHash,\r
+                    BlockSize=accountInfo.BlockSize,\r
+                    Token=accountInfo.Token\r
+                };\r
+            }\r
+            else\r
+            {\r
+                accountName = UserName;\r
+                container = parts[0];                \r
+            }\r
+\r
+            return Task.Factory.StartNew(() =>\r
+            {\r
+                var client = new CloudFilesClient(accountInfo);\r
+                var containerInfo = client.GetContainerInfo(accountName, container);\r
+                return containerInfo;\r
+            });\r
+        }\r
+    }\r
+}\r