Index: /extensions/PiwigoLib/PiwigoLib/DTO/PwgSession.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoLib/DTO/PwgSession.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoLib/DTO/PwgSession.cs	(revision 11911)
@@ -7,6 +7,9 @@
     public class PwgSession
     {
-        public Boolean IsConnected {
-            get { return this.Status != PwgSessionStatusEnum.Guest; }
+        private Boolean _isConnected = false;
+        public Boolean IsConnected
+        {
+            get { return this._isConnected; }
+            internal set { _isConnected = value; } //Is connected is set by the session service when connecting is done
         }
  
Index: /extensions/PiwigoLib/PiwigoLib/Service/PwgSessionService.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoLib/Service/PwgSessionService.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoLib/Service/PwgSessionService.cs	(revision 11911)
@@ -44,4 +44,5 @@
                     {
                         ConvertProxyResponseToDTO(response, ref PwgSession);
+                        PwgSession.IsConnected = true;
                     }
                 } catch (PwgProxyException ex)
Index: /extensions/PiwigoLib/PiwigoWpf/App.xaml
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/App.xaml	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/App.xaml	(revision 11911)
@@ -6,8 +6,8 @@
              Exit="onAppExit">
     <Application.Resources>
-        <ObjectDataProvider x:Name="ImagesODP" x:Key="Images" ObjectType="{x:Type piwigo:PwgImageListWPF}" />
+        <ObjectDataProvider x:Name="ImagesODP" x:Key="Images" ObjectType="{x:Type piwigo:PwgImageListWPF}"/> <!--IsAsynchronous="True"-->
         <ObjectDataProvider x:Name="SessionODP" x:Key="Session" ObjectType="{x:Type piwigo:PwgSessionWPF}" />
-        <ObjectDataProvider x:Name="CategoriesODP" x:Key="Categories" ObjectType="{x:Type piwigo:PwgCategoryListWPF}" />
-        
+        <ObjectDataProvider x:Name="CategoriesODP" x:Key="Categories" ObjectType="{x:Type piwigo:PwgCategoryListWPF}"/> <!--IsAsynchronous="True"-->
+
         <ResourceDictionary  x:Key="VisualStyleApp" Source="VisualStyleApp.xaml"/>
     </Application.Resources>
Index: /extensions/PiwigoLib/PiwigoWpf/App.xaml.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/App.xaml.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/App.xaml.cs	(revision 11911)
@@ -17,4 +17,5 @@
             PwgServiceProvider.Instance.PwgSetupService.Setup( "Com.Piwigo.Wpf.PiwigoWPF", null, null);
 
+             // Model object was created in the app.xaml, so we have to link to them
             PwgModelManager.Instance.Session = (PwgSessionWPF)(this.Resources["Session"] as ObjectDataProvider).Data;
             PwgModelManager.Instance.CategoryList = (PwgCategoryListWPF)(this.Resources["Categories"] as ObjectDataProvider).Data;
Index: /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdConnect.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdConnect.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdConnect.cs	(revision 11911)
@@ -19,9 +19,17 @@
 
                 PwgServiceProvider.Instance.PwgSetupService.Setup(null, null, uriServer);
-                PwgSession sess = PwgServiceProvider.Instance.PwgSessionService.GetPwgSession();
-                sess = PwgServiceProvider.Instance.PwgSessionService.Login( PwgModelManager.Instance.Session.UserName,
-                                                                            PwgModelManager.Instance.Session.Password);
+                PwgSessionWPF sesWPF = PwgModelManager.Instance.Session;
+                
+                PwgSession sess = null;
+                if (String.IsNullOrWhiteSpace(sesWPF.UserName) && String.IsNullOrWhiteSpace(sesWPF.Password))
+                {
+                    sess = PwgServiceProvider.Instance.PwgSessionService.GetPwgSession();
+                }
+                else
+                {
+                    sess = PwgServiceProvider.Instance.PwgSessionService.Login(PwgModelManager.Instance.Session.UserName,
+                                                                               PwgModelManager.Instance.Session.Password);
+                }
 
-                PwgSessionWPF sesWPF = PwgModelManager.Instance.Session;
                 PwgSessionWPFHelper.AddPwgSessionInfoToPwgSessionWPF(sess, ref sesWPF);
 
@@ -32,4 +40,5 @@
 
                 ImageCacheManager.Instance.SetCurrentServer(uriServer.AbsoluteUri);
+
                 IsRunning = false;
             }
Index: /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdDisconnect.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdDisconnect.cs	(revision 11911)
+++ /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdDisconnect.cs	(revision 11911)
@@ -0,0 +1,42 @@
+﻿using System;
+using System.Collections.Generic;
+using Com.Piwigo.Lib.IService;
+using Com.Piwigo.Wpf.DTO;
+using Com.Piwigo.Lib.DTO;
+using Com.Piwigo.Wpf.DTO.Helper;
+using Com.Piwigo.Wpf.Helper;
+using Com.Piwigo.Wpf.Service;
+
+namespace Com.Piwigo.Wpf.Command
+{
+    public sealed class PwgCmdDisconnect : PwgCmdBase
+    {
+        public override void Execute(object parameter)
+        {
+            try {
+                IsRunning = true;
+                PwgSessionWPF sesWPF = PwgModelManager.Instance.Session;
+                
+                PwgSession sess = null;
+                sess = PwgServiceProvider.Instance.PwgSessionService.Logout();
+
+                PwgSessionWPFHelper.AddPwgSessionInfoToPwgSessionWPF(sess, ref sesWPF);
+                
+                if (PwgModelManager.Instance.CategoryList != null)
+                {
+                    PwgModelManager.Instance.CategoryList.Clear();
+                }
+
+                ImageCacheManager.Instance.UnsetCurrentServer();
+
+                IsRunning = false;
+            }
+            catch (PwgServiceException ex)
+            {
+                Console.WriteLine("Erreur " + ex.NumeroErr + " " + ex.MessageErr);
+                Console.WriteLine(ex.Message);
+            }
+
+        }
+    }
+}
Index: /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdGetImageforCategory.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdGetImageforCategory.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdGetImageforCategory.cs	(revision 11911)
@@ -24,4 +24,5 @@
                 {
                     catParam = (PwgCategoryWPF)parameter;
+                    ImageCacheManager.Instance.SetCurrentCategory(catParam.Id.ToString());
 
                     List<PwgImage> lstImg = PwgServiceProvider.Instance.PwgCategoriesService.GetListOfImagesFormCategory(catParam.Id, false, null, null, null, null, null, null, null, null, null, null, null, null, null, true, ref aPage, ref aPerPage, ref  acount);
Index: /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdProvider.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdProvider.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/Command/PwgCmdProvider.cs	(revision 11911)
@@ -9,6 +9,29 @@
     public static class PwgCmdProvider
     {
-        public static ICommand _pwgCmdConnect;
-        public static ICommand PwgCmdConnect
+        public static PwgCmdBase GetByType<T>()
+        {
+            PwgCmdBase objICom;
+
+            switch (typeof(T).Name)
+            {
+                case "PwgCmdConnect":
+                    objICom = PwgCmdConnect;
+                    break;
+                case "PwgCmdDisconnect":
+                    objICom = PwgCmdDisconnect;
+                    break;
+                case "PwgCmdGetImageforCategory":
+                    objICom = PwgCmdGetImageforCategory;
+                    break;
+                default:
+                    objICom = null;
+                    break;
+            }
+
+            return objICom;
+        }
+
+        public static PwgCmdBase _pwgCmdConnect;
+        public static PwgCmdBase PwgCmdConnect
         {
             get
@@ -21,4 +44,30 @@
             }
         }
+
+        public static PwgCmdBase _pwgCmdDisconnect;
+        public static PwgCmdBase PwgCmdDisconnect
+        {
+            get
+            {
+                if (_pwgCmdDisconnect == null)
+                {
+                    _pwgCmdDisconnect = new PwgCmdDisconnect();
+                }
+                return _pwgCmdDisconnect;
+            }
+        }
+
+        public static PwgCmdBase _pwgCmdGetImageforCategory;
+        public static PwgCmdBase PwgCmdGetImageforCategory
+        {
+            get
+            {
+                if (_pwgCmdGetImageforCategory == null)
+                {
+                    _pwgCmdGetImageforCategory = new PwgCmdGetImageforCategory();
+                }
+                return _pwgCmdGetImageforCategory;
+            }
+        }
     }
 }
Index: /extensions/PiwigoLib/PiwigoWpf/DTO/AsyncObservableCollection.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/DTO/AsyncObservableCollection.cs	(revision 11911)
+++ /extensions/PiwigoLib/PiwigoWpf/DTO/AsyncObservableCollection.cs	(revision 11911)
@@ -0,0 +1,62 @@
+﻿using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Threading;
+using System.Collections.Specialized;
+using System.ComponentModel;
+
+namespace Com.Piwigo.Wpf.DTO
+{
+    public class AsyncObservableCollection<T> : ObservableCollection<T>
+    {
+        private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;
+
+        public AsyncObservableCollection()
+        {
+        }
+
+        public AsyncObservableCollection(IEnumerable<T> list)
+            : base(list)
+        {
+        }
+
+        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
+        {
+            if (SynchronizationContext.Current == _synchronizationContext)
+            {
+                // Execute the CollectionChanged event on the current thread
+                RaiseCollectionChanged(e);
+            }
+            else
+            {
+                // Send the CollectionChanged event on the creator thread
+                _synchronizationContext.Send(RaiseCollectionChanged, e);
+            }
+        }
+
+        private void RaiseCollectionChanged(object param)
+        {
+            // We are in the creator thread, call the base implementation directly
+            base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);
+        }
+
+        protected override void OnPropertyChanged(PropertyChangedEventArgs e)
+        {
+            if (SynchronizationContext.Current == _synchronizationContext)
+            {
+                // Execute the PropertyChanged event on the current thread
+                RaisePropertyChanged(e);
+            }
+            else
+            {
+                // Post the PropertyChanged event on the creator thread
+                _synchronizationContext.Post(RaisePropertyChanged, e);
+            }
+        }
+
+        private void RaisePropertyChanged(object param)
+        {
+            // We are in the creator thread, call the base implementation directly
+            base.OnPropertyChanged((PropertyChangedEventArgs)param);
+        }
+    }
+}
Index: /extensions/PiwigoLib/PiwigoWpf/DTO/Helper/PwgCategoryListWPFHelper.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/DTO/Helper/PwgCategoryListWPFHelper.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/DTO/Helper/PwgCategoryListWPFHelper.cs	(revision 11911)
@@ -30,8 +30,12 @@
             if (aPwgCategoryList != null)
             {
-            foreach (PwgCategory pwgCat in aPwgCategoryList)
-            {
-                AddPwgCategoryToList(pwgCat, ref aPwgCategoryListWPF);
-            }
+                if (aPwgCategoryListWPF == null)
+                {
+                    aPwgCategoryListWPF = new PwgCategoryListWPF();
+                }
+                foreach (PwgCategory pwgCat in aPwgCategoryList)
+                {
+                    AddPwgCategoryToList(pwgCat, ref aPwgCategoryListWPF);
+                }
             }
         }
Index: /extensions/PiwigoLib/PiwigoWpf/DTO/Helper/PwgSessionWPFHelper.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/DTO/Helper/PwgSessionWPFHelper.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/DTO/Helper/PwgSessionWPFHelper.cs	(revision 11911)
@@ -17,9 +17,10 @@
                     aPwgSessionWPF = new PwgSessionWPF();
                 }
-                aPwgSession.UserName = aPwgSessionWPF.UserName;
-                aPwgSession.Status = aPwgSessionWPF.Status;
-                aPwgSession.Template = aPwgSessionWPF.Template;
-                aPwgSession.Theme = aPwgSessionWPF.Theme;
-                aPwgSession.CharSet = aPwgSessionWPF.CharSet;
+                aPwgSessionWPF.IsConnected = aPwgSession.IsConnected;
+                aPwgSessionWPF.UserName = aPwgSession.UserName;
+                aPwgSessionWPF.Status = aPwgSession.Status;
+                aPwgSessionWPF.Template = aPwgSession.Template;
+                aPwgSessionWPF.Theme = aPwgSession.Theme;
+                aPwgSessionWPF.CharSet = aPwgSession.CharSet;
             }
         }
Index: /extensions/PiwigoLib/PiwigoWpf/DTO/PwgCategoryListWPF.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/DTO/PwgCategoryListWPF.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/DTO/PwgCategoryListWPF.cs	(revision 11911)
@@ -7,5 +7,5 @@
 namespace Com.Piwigo.Wpf.DTO
 {
-    public class PwgCategoryListWPF : ObservableCollection<PwgCategoryWPF> 
+    public class PwgCategoryListWPF : AsyncObservableCollection<PwgCategoryWPF> 
     {
     }
Index: /extensions/PiwigoLib/PiwigoWpf/DTO/PwgImageListWPF.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/DTO/PwgImageListWPF.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/DTO/PwgImageListWPF.cs	(revision 11911)
@@ -7,5 +7,5 @@
 namespace Com.Piwigo.Wpf.DTO
 {
-    public class PwgImageListWPF : ObservableCollection<PwgImageWPF> 
+    public class PwgImageListWPF : AsyncObservableCollection<PwgImageWPF> 
     {
     }
Index: /extensions/PiwigoLib/PiwigoWpf/DTO/PwgSessionWPF.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/DTO/PwgSessionWPF.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/DTO/PwgSessionWPF.cs	(revision 11911)
@@ -11,6 +11,8 @@
     public class PwgSessionWPF:  INotifyPropertyChanged
     {
+        private Boolean _isConnected;
         public Boolean IsConnected {
-            get { return this.Status != PwgSessionStatusEnum.Guest; }
+            get { return _isConnected; }
+            set { _isConnected = value; OnPropertyChanged("IsConnected"); }
         }
 
@@ -25,5 +27,5 @@
         public String Password
         {
-            set { _password = value; OnPropertyChanged("Password"); }
+            set { _password = value; OnPropertyChanged("Password");}
             get { return _password; }
         }
@@ -32,5 +34,5 @@
         public String ServeurName
         {
-            set { _serverName = value; OnPropertyChanged("ServeurName"); }
+            set { _serverName = value; OnPropertyChanged("ServeurName");}
             get { return _serverName; }
         }
@@ -46,5 +48,5 @@
         public PwgSessionStatusEnum Status
         {
-            set { _status = value; OnPropertyChanged("Status"); OnPropertyChanged("IsConnected"); }
+            set { _status = value; OnPropertyChanged("Status"); }
             get { return _status; }
         }
Index: /extensions/PiwigoLib/PiwigoWpf/Helper/AppHelper.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/Helper/AppHelper.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/Helper/AppHelper.cs	(revision 11911)
@@ -52,7 +52,7 @@
         }
 
-        static public void ExecuteCommand<T>(object parameter) where T:  PwgCmdBase, new()
+        static public void ExecuteCommand<T>(object parameter) where T:  PwgCmdBase
         {
-            T cmd = new T();
+            PwgCmdBase cmd = PwgCmdProvider.GetByType<T>();
             if (cmd.CanExecute(parameter))
             {
Index: /extensions/PiwigoLib/PiwigoWpf/Helper/XMLHelper.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/Helper/XMLHelper.cs	(revision 11911)
+++ /extensions/PiwigoLib/PiwigoWpf/Helper/XMLHelper.cs	(revision 11911)
@@ -0,0 +1,55 @@
+﻿using System;
+using System.Xml;
+using System.IO;
+
+namespace Com.Piwigo.Wpf.Helper
+{
+    public static class XMLHelper<T>
+    {
+        /// <summary>
+        ///  return object from xml retuned by piwigo
+        /// </summary>
+        /// <param name="xmlData"></param>
+        /// <returns></returns>
+        internal static T DeserializeObjectFromFile(FileInfo xmlFile)
+        {
+            T ReturnValue = default(T);
+            try
+            {
+                if (xmlFile.Exists)
+                {
+                    System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
+                    ReturnValue = (T)xsSerializer.Deserialize(xmlFile.OpenRead());
+                }
+            }
+            catch (Exception ex)
+            {
+                throw new ApplicationException (
+                            String.Format(
+                                "The file {0} can't be deserialized in {1}, the error is {2} .",
+                                xmlFile.FullName, typeof(T).Name, ex.Message),
+                            ex);
+            }
+
+            return ReturnValue;
+        }
+
+        internal static void SerializeToXMLFile(T obj, FileInfo xmlFile)
+        {
+            try
+            {
+                if (xmlFile.Exists) xmlFile.Delete();
+                System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
+                serializer.Serialize(xmlFile.CreateText(), obj);
+            }
+            catch (Exception ex)
+            {
+                throw new ApplicationException(
+                            String.Format(
+                                "The value {0} can't be serialized in file {1}, the error is {2} .",
+                                obj.ToString(), xmlFile.FullName, ex.Message),
+                            ex);
+            }
+        }
+    }
+}
Index: /extensions/PiwigoLib/PiwigoWpf/MainWindow.xaml
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/MainWindow.xaml	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/MainWindow.xaml	(revision 11911)
@@ -3,4 +3,5 @@
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:pwg="clr-namespace:Com.Piwigo.Wpf"
+        xmlns:pwgui="clr-namespace:Com.Piwigo.Wpf.UI"
         xmlns:pwgdto="clr-namespace:Com.Piwigo.Wpf.DTO"
         xmlns:pwgcmd="clr-namespace:Com.Piwigo.Wpf.Command"
@@ -20,7 +21,7 @@
                 <Image ToolTip="{Binding File}" >
                     <Image.Source>
-                        <PriorityBinding FallbackValue="pack://application:,,,/Pictures/Globe.png">
+                        <PriorityBinding>
                             <Binding IsAsync="True" Converter="{x:Static pwgsrv:ImageCacheManager.ImageUrlCachedConverter}"/>
-                            
+                            <Binding Source="pack://application:,,,/Pictures/Globe.png" />
                     </PriorityBinding>
                     </Image.Source>
@@ -204,9 +205,11 @@
                 <TextBox Height="23" Name="BbUsr" Width="120" Text="{Binding Path=UserName, Mode=TwoWay}" />
                 <Label Content="Password" Name="LblPwd" />
-                <TextBox Height="23" Name="TbPwd" Width="120" Text="{Binding Path=Password, Mode=TwoWay}"/>
+                <PasswordBox Height="23" Name="TbPwd" Width="120" PasswordChar="*" 
+                             pwgui:PasswordHelper.BindPassword="true" pwgui:PasswordHelper.BoundPassword="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                 <Label Content="Url" Name="LblUrl" />
                 <TextBox Height="23" Name="TbUrl" Width="300" Text="{Binding Path=ServeurName, Mode=TwoWay}"/>
-                <CheckBox  VerticalAlignment="Center" IsChecked="{Binding Path=SaveSetting, Mode=TwoWay}">Save settings</CheckBox>
-                <Button Margin="2" Command="{x:Static pwgcmd:PwgCmdProvider.PwgCmdConnect}">Go</Button>
+                <CheckBox Margin="2" VerticalAlignment="Center" IsChecked="{Binding Path=SaveSetting, Mode=TwoWay}">Save settings</CheckBox>
+                <Button Margin="2" Command="{x:Static pwgcmd:PwgCmdProvider.PwgCmdConnect}" Visibility="{pwgui:SwitchBinding IsConnected, Hidden, Visible}">Conect</Button>
+                <Button Margin="2" Command="{x:Static pwgcmd:PwgCmdProvider.PwgCmdDisconnect}" Visibility="{pwgui:SwitchBinding IsConnected, Visible, Hidden}">Disconect</Button>
             </StackPanel>
            <ProgressBar IsIndeterminate="True" />          
Index: /extensions/PiwigoLib/PiwigoWpf/PiwigoWpf.csproj
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/PiwigoWpf.csproj	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/PiwigoWpf.csproj	(revision 11911)
@@ -77,4 +77,5 @@
       <SubType>Designer</SubType>
     </ApplicationDefinition>
+    <Compile Include="Command\PwgCmdDisconnect.cs" />
     <Compile Include="Command\PwgCmdGetImageforCategory.cs" />
     <Compile Include="Command\PwgCmdProvider.cs" />
@@ -88,4 +89,8 @@
     <Compile Include="DTO\PwgModelManager.cs" />
     <Compile Include="Helper\AppHelper.cs" />
+    <Compile Include="DTO\AsyncObservableCollection.cs" />
+    <Compile Include="UI\SwitchBindingExtension.cs" />
+    <Compile Include="UI\PasswordHelper.cs" />
+    <Compile Include="Helper\XMLHelper.cs" />
     <Compile Include="Helper\ImageUrlCachedConverter.cs" />
     <Compile Include="Service\ImageCacheManager.cs" />
Index: /extensions/PiwigoLib/PiwigoWpf/Service/ImageCacheManager.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/Service/ImageCacheManager.cs	(revision 11910)
+++ /extensions/PiwigoLib/PiwigoWpf/Service/ImageCacheManager.cs	(revision 11911)
@@ -14,7 +14,24 @@
     public class ImageCacheManager
     {
+        #region WPF Converter
+        static readonly ImageUrlCachedConverter _imageUrlCachedConverter = new ImageUrlCachedConverter();
+
+        public static ImageUrlCachedConverter ImageUrlCachedConverter
+        {
+            get
+            {
+                return _imageUrlCachedConverter;
+            }
+        }
+
+        public static String GetDefaultImage()
+        {
+            return ("pack://application:,,,/Pictures/Globe.png");
+        }
+
+        #endregion WPF Converter
+
+        #region Singleton
         static readonly ImageCacheManagerBase _instance = new ImageCacheManagerBase();
-
-        static readonly ImageUrlCachedConverter _imageUrlCachedConverter = new ImageUrlCachedConverter();
 
         // Explicit static constructor to tell C# compiler
@@ -31,34 +48,97 @@
             }
         }
-
-        public static ImageUrlCachedConverter ImageUrlCachedConverter
-        {
-            get
-            {
-                return _imageUrlCachedConverter;
-            }
-        }
-        public class ImageCacheManagerBase
-        {
+        #endregion Singleton
+
+        #region singleton base class
+        public class ImageCacheManagerBase : IDisposable
+        {
+            #region DTO
             // local DTO
-            private class ImageDictionnary : SortedDictionary<Int32, String> { };
-            private class ServerDictionnary : SortedDictionary<String, ImageDictionnary> { };
-
-            private Object _lock = new Object(); 
-            
+            internal class CategoryDictionnaryItem
+            {
+                internal DirectoryInfo BasePath;
+                internal String CategorieId;
+            };
+
+            internal class CategoryDictionnary : SortedDictionary<String, CategoryDictionnaryItem> { };
+
+            internal class ServerDictionnaryItem
+            {
+                internal DirectoryInfo BasePath;
+                internal CategoryDictionnary Categories;
+                internal Uri ServeurUrl;
+            };
+
+            internal class ServerDictionnary : SortedDictionary<String, ServerDictionnaryItem> { };
+
+            internal static DirectoryInfo AppCachedDataDirectory = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),"PiwigoWpf", "cache"));
+
+            internal Object _lock = new Object();
+            internal ServerDictionnary _aServerDictionnary;
+            internal ServerDictionnaryItem _currentServer;
+            internal CategoryDictionnaryItem _currentCategory;
+
+            #endregion DTO
+
+            #region local helper
             // local helper
             static private String BuildServerDirCache(String serveurUri)
             {
-                String AppCachedDataDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),"cache");
-                String ServerDirCache = Path.Combine(AppCachedDataDirectory, serveurUri.Replace("http://", "_").Replace("/", "_")); 
+                String ServerDirCache = Path.Combine(AppCachedDataDirectory.FullName, serveurUri.Replace("http://", "_").Replace("/", "_"));
+                System.Diagnostics.Debug.Print(ServerDirCache);
 
                 return ServerDirCache;
             }
             
-           
-
-            private ServerDictionnary _aServerDictionnary = new ServerDictionnary();
-            private String _currentServer;
-            private ImageDictionnary _currentImageDictionnary = new ImageDictionnary();
+            static private String BuildCategoryDirCache(ServerDictionnaryItem server, String CatgeoryId)
+            {
+                String CategoryDirCache = String.Empty;
+                if (server != null)
+                {
+                    CategoryDirCache = Path.Combine(server.BasePath.FullName, CatgeoryId.Replace("/", "_")); 
+                }
+                else
+                {
+                    throw new ApplicationException ("Current server not set before using category");
+                }
+
+                return CategoryDirCache;
+            }
+
+            static private ServerDictionnary BuildServerDictionnaryFromCache()
+            {
+                ServerDictionnary retLstServerDictionnary = new ServerDictionnary();
+
+                if (AppCachedDataDirectory.Exists)
+                {
+                    foreach (DirectoryInfo Dir in AppCachedDataDirectory.GetDirectories())
+                    {
+                        FileInfo xmlData = new FileInfo(Path.Combine(Dir.FullName, "serverdictionnaryitem.xml"));
+                        if (xmlData.Exists)
+                        {
+                            ServerDictionnaryItem item = XMLHelper<ServerDictionnaryItem>.DeserializeObjectFromFile(xmlData);
+                            retLstServerDictionnary.Add(item.ServeurUrl.ToString(), item);
+                        }
+                    }
+                }
+
+                return retLstServerDictionnary;
+            }
+
+            static void WriteServerDictionnaryToDisk(ServerDictionnary dcServer)
+            {
+                foreach (ServerDictionnaryItem Item in dcServer.Values)
+                {
+                    FileInfo xmlData = new FileInfo(Path.Combine(Item.BasePath.FullName, "serverdictionnaryitem.xml"));
+                    XMLHelper<ServerDictionnaryItem>.SerializeToXMLFile(Item, xmlData);
+                }
+            }
+            #endregion local helper
+
+            public void UnsetCurrentServer()
+            { 
+                _currentCategory = null;
+                _currentServer = null;
+            }
 
             public void SetCurrentServer(String serveurUri)
@@ -67,19 +147,63 @@
                 lock (_lock)
                 {
+                    // load data from disk on first access
+                    if (_aServerDictionnary == null)
+                    {
+                        _aServerDictionnary = BuildServerDictionnaryFromCache();
+                    }
+
                     if (_aServerDictionnary.ContainsKey(serveurUri))
                     {
-                        _currentServer = serveurUri;
+                        _currentServer = _aServerDictionnary[serveurUri];
                     }
                     else
                     {
-                        ImageDictionnary newImageDictionnary = new ImageDictionnary();
-                        _aServerDictionnary.Add(serveurUri, newImageDictionnary);
-                        _currentServer = serveurUri;
-                    }
-                }
-                if (!Directory.Exists(currentserverDir))
-                {
-                    //Create it
-                    Directory.CreateDirectory(currentserverDir);
+                        ServerDictionnaryItem server = new ServerDictionnaryItem();
+                        server.ServeurUrl = new Uri(serveurUri);
+                        server.BasePath = new DirectoryInfo(currentserverDir);
+                        server.Categories = new CategoryDictionnary();
+                        _aServerDictionnary.Add(serveurUri, server);
+                        _currentServer = server;
+                    }
+
+                    if (!Directory.Exists(currentserverDir))
+                    {
+                        //Create it
+                        Directory.CreateDirectory(currentserverDir);
+                        _currentServer.Categories.Clear();
+                    }
+                }
+            }
+
+            public void SetCurrentCategory(String CategorieId)
+            {
+                if (_currentServer != null)
+                {
+                    lock (_lock)
+                    {
+                        String currentsCategoryDir = BuildCategoryDirCache(_currentServer, CategorieId);
+                        if (_currentServer.Categories.ContainsKey(CategorieId))
+                        {
+                            _currentCategory = _currentServer.Categories[CategorieId];
+                        }
+                        else
+                        {
+                            CategoryDictionnaryItem category = new CategoryDictionnaryItem();
+                            category.BasePath = new DirectoryInfo(currentsCategoryDir);
+                            category.CategorieId = CategorieId;
+                            _currentServer.Categories.Add(CategorieId, category);
+                            _currentCategory = category;
+                        }
+
+                        if (!Directory.Exists(currentsCategoryDir))
+                        {
+                            //Create it
+                            Directory.CreateDirectory(currentsCategoryDir);
+                        }
+                    }
+                }
+                else
+                {
+                    throw new ApplicationException("Current server not set before using category");
                 }
             }
@@ -87,49 +211,56 @@
             public String GetImageFilename(PwgImageWPF aImageWPF)
                 {
+                    String retValue = String.Empty;
                     if (aImageWPF == null)
                     {
-                        return String.Empty;
-                    }
-
-                    String retValue;
-                    String currentserverDir = BuildServerDirCache(_currentServer); 
-                    String localFile = Path.Combine(currentserverDir, String.Format("{0}-{1}", aImageWPF.Id, aImageWPF.File)); 
-
-                    if (_aServerDictionnary[_currentServer].ContainsKey(aImageWPF.Id))
-                    {
-                        retValue = _aServerDictionnary[_currentServer][aImageWPF.Id];
+                        return retValue;
+                    }
+
+                    if (_currentCategory != null)
+                    {
+                        String localFile = Path.Combine(_currentCategory.BasePath.FullName, String.Format("{0}-{1}", aImageWPF.Id, aImageWPF.File));
+
+                        if (!File.Exists(localFile))
+                        {
+                            ThreadPool.QueueUserWorkItem((WaitCallback)delegate
+                            {
+                                WebRequest request = HttpWebRequest.Create(aImageWPF.UrlElement);
+                                WebResponse response = request.GetResponse();
+
+                                //check the content type to assert that the file in the uri is an image
+                                if (!response.ContentType.StartsWith("image"))
+                                {
+                                    throw new FileFormatException(aImageWPF.UrlElement, String.Format("Uri passed to ImageCacher does not return an image. Content is of type {0}.", response.ContentType));
+                                }
+
+                                //load the image from the stream
+                                Image image = Image.FromStream(response.GetResponseStream());
+
+                                //save it
+                                image.Save(localFile);
+
+                            });
+
+                            retValue = localFile;
+                        }
                     }
                     else
                     {
-                        if (!File.Exists(localFile))
-                        {
-                           ThreadPool.QueueUserWorkItem((WaitCallback)delegate
-                        {
-                            WebRequest request = HttpWebRequest.Create(aImageWPF.UrlElement);
-                            WebResponse response = request.GetResponse();
-
-                            //check the content type to assert that the file in the uri is an image
-                           if (!response.ContentType.StartsWith("image"))
-                           {
-                              throw new FileFormatException(aImageWPF.UrlElement, String.Format("Uri passed to ImageCacher does not return an image. Content is of type {0}.", response.ContentType));
-                           }
-
-                           //load the image from the stream
-                           Image image = Image.FromStream(response.GetResponseStream());
-  
-                           //save it
-                           image.Save(localFile); 
-
-                        });
-
-                        }
-                        
-                        _aServerDictionnary[_currentServer].Add(aImageWPF.Id,localFile);
-                        retValue = localFile; 
+                        throw new ApplicationException("Current category not set before using image cache.");
                     }
                     return retValue;
                 }
-        }
-    }
-
+
+            public void Dispose()
+            {
+                if (_aServerDictionnary != null)
+                {
+                    WriteServerDictionnaryToDisk(_aServerDictionnary);
+                }
+            }
+        }
+
+        #endregion singleton base class
 }
+
+}
Index: /extensions/PiwigoLib/PiwigoWpf/UI/PasswordHelper.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/UI/PasswordHelper.cs	(revision 11911)
+++ /extensions/PiwigoLib/PiwigoWpf/UI/PasswordHelper.cs	(revision 11911)
@@ -0,0 +1,112 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Com.Piwigo.Wpf.UI
+{
+    public static class PasswordHelper
+    {
+        public static readonly DependencyProperty BoundPassword =
+          DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(PasswordHelper), new PropertyMetadata(string.Empty, OnBoundPasswordChanged));
+
+        public static readonly DependencyProperty BindPassword = DependencyProperty.RegisterAttached(
+            "BindPassword", typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false, OnBindPasswordChanged));
+
+        private static readonly DependencyProperty UpdatingPassword =
+            DependencyProperty.RegisterAttached("UpdatingPassword", typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false));
+
+        private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            PasswordBox box = d as PasswordBox;
+
+            // only handle this event when the property is attached to a PasswordBox
+            // and when the BindPassword attached property has been set to true
+            if (d == null || !GetBindPassword(d))
+            {
+                return;
+            }
+
+            // avoid recursive updating by ignoring the box's changed event
+            box.PasswordChanged -= HandlePasswordChanged;
+
+            string newPassword = (string)e.NewValue;
+
+            if (!GetUpdatingPassword(box))
+            {
+                box.Password = newPassword;
+            }
+
+            box.PasswordChanged += HandlePasswordChanged;
+        }
+
+        private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
+        {
+            // when the BindPassword attached property is set on a PasswordBox,
+            // start listening to its PasswordChanged event
+
+            PasswordBox box = dp as PasswordBox;
+
+            if (box == null)
+            {
+                return;
+            }
+
+            bool wasBound = (bool)(e.OldValue);
+            bool needToBind = (bool)(e.NewValue);
+
+            if (wasBound)
+            {
+                box.PasswordChanged -= HandlePasswordChanged;
+            }
+
+            if (needToBind)
+            {
+                box.PasswordChanged += HandlePasswordChanged;
+            }
+        }
+
+        private static void HandlePasswordChanged(object sender, RoutedEventArgs e)
+        {
+            PasswordBox box = sender as PasswordBox;
+
+            // set a flag to indicate that we're updating the password
+            SetUpdatingPassword(box, true);
+            // push the new password into the BoundPassword property
+            SetBoundPassword(box, box.Password);
+            SetUpdatingPassword(box, false);
+        }
+
+        public static void SetBindPassword(DependencyObject dp, bool value)
+        {
+            dp.SetValue(BindPassword, value);
+        }
+
+        public static bool GetBindPassword(DependencyObject dp)
+        {
+            return (bool)dp.GetValue(BindPassword);
+        }
+
+        public static string GetBoundPassword(DependencyObject dp)
+        {
+            return (string)dp.GetValue(BoundPassword);
+        }
+
+        public static void SetBoundPassword(DependencyObject dp, string value)
+        {
+            dp.SetValue(BoundPassword, value);
+        }
+
+        private static bool GetUpdatingPassword(DependencyObject dp)
+        {
+            return (bool)dp.GetValue(UpdatingPassword);
+        }
+
+        private static void SetUpdatingPassword(DependencyObject dp, bool value)
+        {
+            dp.SetValue(UpdatingPassword, value);
+        }
+    }
+}
Index: /extensions/PiwigoLib/PiwigoWpf/UI/SwitchBindingExtension.cs
===================================================================
--- /extensions/PiwigoLib/PiwigoWpf/UI/SwitchBindingExtension.cs	(revision 11911)
+++ /extensions/PiwigoLib/PiwigoWpf/UI/SwitchBindingExtension.cs	(revision 11911)
@@ -0,0 +1,78 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Data;
+using System.Windows.Markup;
+using System.Windows;
+
+namespace Com.Piwigo.Wpf.UI
+{
+    public class SwitchBindingExtension : Binding
+    {
+        public SwitchBindingExtension()
+        {
+            Initialize();
+        }
+
+        public SwitchBindingExtension(string path)
+            : base(path)
+        {
+            Initialize();
+        }
+
+        public SwitchBindingExtension(string path, object valueIfTrue, object valueIfFalse)
+            : base(path)
+        {
+            Initialize();
+            this.ValueIfTrue = valueIfTrue;
+            this.ValueIfFalse = valueIfFalse;
+        }
+
+        private void Initialize()
+        {
+            this.ValueIfTrue = Binding.DoNothing;
+            this.ValueIfFalse = Binding.DoNothing;
+            this.Converter = new SwitchConverter(this);
+        }
+
+        [ConstructorArgument("valueIfTrue")]
+        public object ValueIfTrue { get; set; }
+
+        [ConstructorArgument("valueIfFalse")]
+        public object ValueIfFalse { get; set; }
+
+        private class SwitchConverter : IValueConverter
+        {
+            public SwitchConverter(SwitchBindingExtension switchExtension)
+            {
+                _switch = switchExtension;
+            }
+
+            private SwitchBindingExtension _switch;
+
+            #region IValueConverter Members
+
+            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+            {
+                try
+                {
+                    bool b = System.Convert.ToBoolean(value);
+                    return b ? _switch.ValueIfTrue : _switch.ValueIfFalse;
+                }
+                catch
+                {
+                    return DependencyProperty.UnsetValue;
+                }
+            }
+
+            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+            {
+                return Binding.DoNothing;
+            }
+
+            #endregion
+        }
+
+    }
+}
