public static void Reload([NotNull] SessionViewModel session, ILogger log, Action postReloadAction, Action undoAction, [NotNull] Dictionary <PackageLoadedAssembly, string> modifiedAssemblies)
        {
            var loadedAssemblies = modifiedAssemblies.Where(x => File.Exists(x.Key.Path)).ToDictionary(x => x.Key, x => x.Value);

            var assemblyContainer = session.AssemblyContainer;

            using (session.CreateAssetFixupContext())
            {
                // TODO: Filter by "modified assemblies", for now we reload everything
                var loadedAssembliesSet = new HashSet <Assembly>(loadedAssemblies.Select(x => x.Key.Assembly).NotNull());

                // Serialize types from unloaded assemblies as Yaml, and unset them
                var unloadingVisitor = new UnloadingVisitor(log, loadedAssembliesSet);
                Dictionary <AssetViewModel, List <ItemToReload> > assetItemsToReload;
                try
                {
                    assetItemsToReload = PrepareAssemblyReloading(session, unloadingVisitor, session.UndoRedoService);
                }
                catch (Exception e)
                {
                    log.Error("Could not prepare asset for assembly reload", e);
                    throw;
                }

                var reloadOperation = new ReloadAssembliesOperation(assemblyContainer, modifiedAssemblies, Enumerable.Empty <IDirtiable>());
                session.UndoRedoService.SetName(reloadOperation, "Reload assemblies");

                // Reload assemblies
                reloadOperation.Execute(log);
                session.UndoRedoService.PushOperation(reloadOperation);

                postReloadAction();
                var postReloadOperation = new AnonymousDirtyingOperation(Enumerable.Empty <IDirtiable>(), postReloadAction, postReloadAction);
                session.UndoRedoService.PushOperation(postReloadOperation);
                session.UndoRedoService.SetName(postReloadOperation, "Post reload action");

                // Restore deserialized objects (or IUnloadable if it didn't work)
                var reloadingVisitor = new ReloadingVisitor(log, loadedAssembliesSet);
                try
                {
                    PostAssemblyReloading(session.UndoRedoService, session.AssetNodeContainer, reloadingVisitor, log, assetItemsToReload);
                }
                catch (Exception e)
                {
                    log.Error("Could not restore asset after assembly reload", e);
                    throw;
                }

                var undoOperation = new AnonymousDirtyingOperation(Enumerable.Empty <IDirtiable>(), undoAction, null);
                session.UndoRedoService.PushOperation(undoOperation);
                session.UndoRedoService.SetName(undoOperation, "Undo action");
            }

            session.ActiveProperties.RefreshSelectedPropertiesAsync().Forget();
        }
        private static void PostAssemblyReloading(IUndoRedoService actionService, SessionNodeContainer nodeContainer, ReloadingVisitor reloaderVisitor, ILogger log, Dictionary <AssetViewModel, List <ItemToReload> > assetItemsToReload)
        {
            log?.Info("Updating components with newly loaded assemblies");

            // Recreate new objects from Yaml streams
            foreach (var asset in assetItemsToReload)
            {
                // Deserialize objects with reloaded types from Yaml
                reloaderVisitor.Run(asset.Key.Asset, asset.Value);

                // Set new values
                var overrides = new YamlAssetMetadata <OverrideType>();
                foreach (var itemToReload in asset.Value)
                {
                    // Set (members) or add nodes (collections) with values created using newly loaded assemblies
                    ReplaceNode(actionService, asset.Key, itemToReload);
                    if (itemToReload.Overrides != null)
                    {
                        var extendedPath = itemToReload.GraphPath.Clone();
                        if (itemToReload.GraphPathIndex != NodeIndex.Empty)
                        {
                            extendedPath.PushIndex(itemToReload.GraphPathIndex);
                        }

                        var pathToPrepend = AssetNodeMetadataCollectorBase.ConvertPath(extendedPath);

                        foreach (var entry in itemToReload.Overrides)
                        {
                            var path = pathToPrepend.Append(entry.Key);
                            overrides.Set(path, entry.Value);
                        }
                    }
                }

                FixupObjectReferences.RunFixupPass(asset.Key.Asset, reloaderVisitor.ObjectReferences, true, false, log);

                var rootNode = (IAssetNode)nodeContainer.GetNode(asset.Key.Asset);
                AssetPropertyGraph.ApplyOverrides(rootNode, overrides);
            }
        }