/// <summary>
      /// Create the navigation structure containing all ViewModels
      /// </summary>
      /// <param name="mainViewModels">An array of the application's ViewModels</param>
      private void LoadNavigation(ViewModelFoundation[] mainViewModels) {

         // Browse every ViewModels and search if it has a Navig attribute
         foreach(var vm in mainViewModels) {
            foreach(NavigAttribute na in vm.GetType().GetCustomAttributes(typeof(NavigAttribute), inherit: false)) {
               NavigConfig mainConf;

               // Check if it already exists a NavigConf with the same name
               var existingMainConf = navStructure.SingleOrDefault(n => n.Name == na.MainConfig.Name);

               if(existingMainConf != null) // If it's the case, set mainConf to it
                  mainConf = existingMainConf;
               else {                       // Else we use the MainConfig as a new elem of navStructure
                  if(!vm.IsAuthorized(CurrentUser))
                     na.MainConfig.Enabled = false;
                  mainConf = na.MainConfig;
                  navStructure.Add(mainConf);
               }

               // Assign the VM to the SubConfig or the main (if NavigAttribute has a single param)
               if(na.SubConfig != null) {
                  if(!vm.IsAuthorized(CurrentUser))
                     na.SubConfig.Enabled = false;
                  na.SubConfig.VM = vm;
                  mainConf.SubConfig.Add(na.SubConfig);
               } else
                  mainConf.VM = vm;
            }
         }
         CurrentMainNav = MainNavig[0];
         CurrentViewModel = SubNavig[0].VM;
         CurrentMainNav.IsSelected = true;
         SubNavig[0].IsSelected = true;
      }
      /// <summary>
      /// Instanciate the ApplicationViewModel. All registred ViewModels are injected into the param mainViewModels
      /// </summary>
      /// <param name="mainViewModels">An array of the application's ViewModels (injected)</param>
      /// <param name="loadingVm">The ViewModel representing the loading (injected)</param>
      /// <param name="authVm">The ViewModel representing the authentication (injected)</param>
      /// <param name="navConfs">An array containing the navigation configuration (injected)</param>
      public ApplicationViewModel(ViewModelFoundation[] mainViewModels, ViewModelFoundation loadingVm, ViewModelFoundation authVm, NavigConfig[] navConfs) {

         // Set the callback when the CurrentUser object has finished loading
         CurrentUser.AsyncLoadingFinished += (s, a) => {
            LoadNavigation(mainViewModels);
            RaisePropertyChanged("MainNavig");
         };
         CurrentViewModel = authVm; // Display the authentication view
         CurrentUser.AsyncLogin();  // Asynchronously log the user in

         loadingViewModel = loadingVm;

         // Load custom navigation informations
         NavigAttribute.RegisterConfigurations(navConfs);

         changeMainCmd = new Lazy<ICommand>(() => 
            new RelayCommand<NavigConfig>(nc => CurrentMainNav = nc));
         changeViewCmd = new Lazy<ICommand>(() => 
            new RelayCommand<ViewModelFoundation>(vm => CurrentViewModel = vm));
      }
      /// <summary>
      /// Sets the view as a loading one and execute asynchronously the PreLoad method of IPreLoadable.
      /// Once loaded, it replaces the loading view by the freshly loaded ViewModel
      /// </summary>
      /// <param name="vm"></param>
      private async void AsyncLoadViewModel(IPreLoadable vm) {
         vm.IsPreLoadNeeded = false;             // This ViewModel doesn't need loading anymore
         nowLoadingViewModel = currentViewModel; // Set the currently loading ViewModel
         currentViewModel = loadingViewModel;    // Display the loading view

         vm.IsCurrentlyLoading = true;
         await Task.Factory.StartNew(vm.PreLoad); // Launch the preloading in another task
         vm.IsCurrentlyLoading = false;

         // Check if the view is a ILoadingViewModel and if it's currently in a loading state
         if(nowLoadingViewModel != null && !(nowLoadingViewModel as IPreLoadable).IsCurrentlyLoading) {
            currentViewModel = nowLoadingViewModel; // Replace the loading by the freshly loaded ViewModel
            nowLoadingViewModel = null;
            RaiseViewModelDisplayed(currentViewModel);
            RaisePropertyChanged("CurrentViewModel");
         }
      }
 /// <summary>
 /// Raise a ViewModelDisplayed event to alert the subscribers that a new ViewModel 
 /// has been loaded into the application
 /// </summary>
 /// <param name="sender">The ViewModel that will be displayed</param>
 protected virtual void RaiseViewModelDisplayed(ViewModelFoundation sender)
 {
     EventHandler handler = sender.ViewModelDisplayed;
      if(handler != null)
     handler(sender, EventArgs.Empty);
 }