Esempio n. 1
0
 public Factory(
     ITempFilesManager tempFiles,
     ITraceSourceFactory traceSourceFactory,
     MultiInstance.IInstancesCounter mutualExecutionCounter,
     IShutdown shutdown,
     ISynchronizationContext synchronizationContext,
     Persistence.IFirstStartDetector firstStartDetector,
     Telemetry.ITelemetryCollector telemetry,
     Persistence.IStorageManager storage,
     IChangeNotification changeNotification,
     string autoUpdateUrl,
     string pluginsIndexUrl
     )
 {
     this.tempFiles              = tempFiles;
     this.traceSourceFactory     = traceSourceFactory;
     this.shutdown               = shutdown;
     this.synchronizationContext = synchronizationContext;
     this.mutualExecutionCounter = mutualExecutionCounter;
     this.firstStartDetector     = firstStartDetector;
     this.telemetry              = telemetry;
     this.storage            = storage;
     this.changeNotification = changeNotification;
     this.autoUpdateUrl      = autoUpdateUrl;
     this.pluginsIndexUrl    = pluginsIndexUrl;
 }
        public PluggableProtocolManager(
            ITraceSourceFactory traceSourceFactory,
            MultiInstance.IInstancesCounter instancesCounter,
            IShutdown shutdown,
            Telemetry.ITelemetryCollector telemetryCollector,
            Persistence.IFirstStartDetector firstStartDetector,
            ILaunchUrlParser launchUrlParser
            )
        {
            this.tracer          = traceSourceFactory.CreateTraceSource("PluggableProtocol");
            this.launchUrlParser = launchUrlParser;

            if (instancesCounter.IsPrimaryInstance)
            {
                this.regUpdater = RegistryUpdater(shutdown.ShutdownToken, telemetryCollector, firstStartDetector.IsFirstStartDetected);
            }

            shutdown.Cleanup += (s, e) =>
            {
                if (regUpdater != null)
                {
                    shutdown.AddCleanupTask(regUpdater.WithTimeout(TimeSpan.FromSeconds(1)));
                }
            };
        }
Esempio n. 3
0
        public TelemetryCollector(
            Persistence.IStorageManager storage,
            ITelemetryUploader telemetryUploader,
            IInvokeSynchronization synchronization,
            MultiInstance.IInstancesCounter instancesCounter,
            IShutdown shutdown,
            ILogSourcesManager logSourcesManager,
            IMemBufferTraceAccess traceAccess
            )
        {
            this.telemetryUploader = telemetryUploader;
            this.synchronization   = synchronization;
            this.traceAccess       = traceAccess;

            this.telemetryStorageEntry = storage.GetEntry("telemetry");
            this.sessionStartedMillis  = Environment.TickCount;

            this.currentSessionId = telemetryUploader.IsTelemetryConfigured ?
                                    ("session" + Guid.NewGuid().ToString("n")) : null;

            this.transactionInvoker = new AsyncInvokeHelper(synchronization,
                                                            (Action)(() => DoSessionsRegistryTransaction(TransactionFlag.Default)), new object[0]);

            shutdown.Cleanup += (s, e) => shutdown.AddCleanupTask(DisposeAsync());

            if (currentSessionId != null)
            {
                CreateCurrentSessionSection();
                InitStaticTelemetryProperties();

                logSourcesManager.OnLogSourceAdded += (s, e) =>
                {
                    ++totalNfOfLogs;
                    var nfOfSimultaneousLogs = logSourcesManager.Items.Count();
                    maxNfOfSimultaneousLogs = Math.Max(maxNfOfSimultaneousLogs, nfOfSimultaneousLogs);
                };
            }

            if (telemetryUploader.IsTelemetryConfigured && instancesCounter.IsPrimaryInstance)
            {
                this.workerCancellation     = new CancellationTokenSource();
                this.workerCancellationTask = new TaskCompletionSource <int>();
                this.worker = TaskUtils.StartInThreadPoolTaskScheduler(Worker);
            }
        }
Esempio n. 4
0
        public void BeforeEach()
        {
            storage          = Substitute.For <Persistence.IStorageManager>();
            uploader         = Substitute.For <ITelemetryUploader>();
            instancesCounter = Substitute.For <MultiInstance.IInstancesCounter>();
            shutdown         = Substitute.For <IShutdown>();
            traceAccess      = Substitute.For <IMemBufferTraceAccess>();

            collector = new TelemetryCollector(
                storage, uploader,
                new SerialSynchronizationContext(),
                instancesCounter, shutdown,
                traceAccess,
                new TraceSourceFactory()
                );

            uploader.IsIssuesReportingConfigured.Returns(true);
        }
Esempio n. 5
0
        public TempFilesManager(ITraceSourceFactory traceSourceFactory, MultiInstance.IInstancesCounter instancesCounter)
        {
            var tracer = traceSourceFactory.CreateTraceSource("App", "tmp");

            using (tracer.NewFrame)
            {
#if !SILVERLIGHT
                folder = Path.Combine(Path.GetTempPath(), "LogJoint");
#else
#endif
                tracer.Info("Temp directory: {0}", folder);

                if (!Directory.Exists(folder))
                {
                    tracer.Info("Temp directory doesn't exist. Creating it.");
                    Directory.CreateDirectory(folder);
                }
                else
                {
                    if (!instancesCounter.IsPrimaryInstance)
                    {
                        tracer.Info("Temp directory exists and I am NOT the only instance in the system. Skipping temp cleanup.");
                    }
                    else
                    {
                        tracer.Info("Temp directory exists. Deleting it first.");
                        try
                        {
                            Directory.Delete(folder, true);
                        }
                        catch (Exception e)
                        {
                            tracer.Error(e, "Failed to delete tempdir");
                        }
                    }
                    tracer.Info("Creating temp directory.");
                    Directory.CreateDirectory(folder);
                }
            }
        }
Esempio n. 6
0
        public TelemetryCollector(
            Persistence.IStorageManager storage,
            ITelemetryUploader telemetryUploader,
            ISynchronizationContext synchronization,
            MultiInstance.IInstancesCounter instancesCounter,
            IShutdown shutdown,
            IMemBufferTraceAccess traceAccess,
            ITraceSourceFactory traceSourceFactory
            )
        {
            this.trace             = traceSourceFactory.CreateTraceSource("Telemetry");
            this.telemetryUploader = telemetryUploader;
            this.synchronization   = synchronization;
            this.traceAccess       = traceAccess;

            this.telemetryStorageEntry = storage.GetEntry("telemetry");
            this.sessionStartedMillis  = Environment.TickCount;

            this.currentSessionId = telemetryUploader.IsTelemetryConfigured ?
                                    ("session" + Guid.NewGuid().ToString("n")) : null;

            this.transactionInvoker = new AsyncInvokeHelper(synchronization,
                                                            () => DoSessionsRegistryTransaction(TransactionFlag.Default));

            shutdown.Cleanup += (s, e) => shutdown.AddCleanupTask(DisposeAsync());

            if (currentSessionId != null)
            {
                CreateCurrentSessionSection();
                InitStaticTelemetryProperties();
            }

            if (telemetryUploader.IsTelemetryConfigured && instancesCounter.IsPrimaryInstance)
            {
                this.workerCancellation     = new CancellationTokenSource();
                this.workerCancellationTask = new TaskCompletionSource <int>();
                this.worker = TaskUtils.StartInThreadPoolTaskScheduler(Worker);
            }
        }
Esempio n. 7
0
        public static async Task <IPendingUpdate> Create(
            IFactory factory,
            ITempFilesManager tempFiles,
            ITraceSourceFactory traceSourceFactory,
            MultiInstance.IInstancesCounter mutualExecutionCounter,
            IReadOnlyList <Extensibility.IPluginInfo> requiredPlugins,
            string managedAssembliesPath,
            string updateLogFileName,
            CancellationToken cancellation
            )
        {
            LJTraceSource trace = traceSourceFactory.CreateTraceSource("AutoUpdater", $"pupd-{Interlocked.Increment(ref pendingUpdateIdx)}");

            string installationDir = Path.GetFullPath(
                Path.Combine(managedAssembliesPath, Constants.installationPathRootRelativeToManagedAssembliesLocation));
            string tempInstallationDir = GetTempInstallationDir(installationDir, tempFiles);

            async Task <(string tempZipFile, DownloadUpdateResult result)> Download(IUpdateDownloader updateDownloader, string name)
            {
                var tempFileName = tempFiles.GenerateNewName();

                using (var tempFileStream = new FileStream(tempFileName, FileMode.Create, FileAccess.Write))
                {
                    trace.Info("downloading update for '{0}' to '{1}'", name, tempFileName);
                    var downloadResult = await updateDownloader.DownloadUpdate(null, tempFileStream, cancellation);

                    cancellation.ThrowIfCancellationRequested();
                    if (downloadResult.Status == DownloadUpdateResult.StatusCode.Failure)
                    {
                        throw new Exception($"Failed to download update for {name}: {downloadResult.ErrorMessage}");
                    }
                    return(tempFileName, downloadResult);
                }
            }

            var downloadResults = await Task.WhenAll(
                new[] { Download(factory.CreateAppUpdateDownloader(), "app") }
                .Union(requiredPlugins.Select(plugin => Download(factory.CreatePluginUpdateDownloader(plugin), plugin.Name)))
                );

            void UnzipDownloadedUpdate(string zipFileName, string targetDir)
            {
                using (var fs = new FileStream(zipFileName, FileMode.Open))
                    using (var zipFile = new ZipArchive(fs, ZipArchiveMode.Read))
                    {
                        try
                        {
                            zipFile.ExtractToDirectory(targetDir);
                        }
                        catch (UnauthorizedAccessException e)
                        {
                            throw new BadInstallationDirException(e);
                        }
                    }
                cancellation.ThrowIfCancellationRequested();
            }

            trace.Info("unzipping downloaded update to {0}", tempInstallationDir);
            UnzipDownloadedUpdate(downloadResults[0].tempZipFile, tempInstallationDir);

            var newUpdateInfoPath = Path.Combine(tempInstallationDir,
                                                 Constants.managedAssembliesLocationRelativeToInstallationRoot, Constants.updateInfoFileName);

            new UpdateInfoFileContent(downloadResults[0].result.ETag, DateTime.UtcNow, null).Write(newUpdateInfoPath);

            UpdatePermissions(tempInstallationDir);

            trace.Info("starting updater");

            async Task <(Process process, string autoRestartFlagFileName)> StartUpdater()
            {
                var    tempUpdaterExePath = tempFiles.GenerateNewName() + ".lj.updater.exe";
                string updaterExePath;
                string programToStart;
                string firstArg;
                string autoRestartCommandLine;
                string autoRestartIPCKey;
                string restartFlagFileName;

                if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    updaterExePath = Path.Combine(installationDir, Constants.managedAssembliesLocationRelativeToInstallationRoot, "logjoint.updater.exe");
                    var monoPath = @"/Library/Frameworks/Mono.framework/Versions/Current/bin/mono";
                    programToStart         = monoPath;
                    firstArg               = string.Format("\"{0}\" ", tempUpdaterExePath);
                    restartFlagFileName    = tempFiles.GenerateNewName() + ".autorestart";
                    autoRestartIPCKey      = restartFlagFileName;
                    autoRestartCommandLine = Path.GetFullPath(Path.Combine(installationDir, ".."));
                }
                else
                {
                    updaterExePath         = Path.Combine(installationDir, "updater", "logjoint.updater.exe");
                    programToStart         = tempUpdaterExePath;
                    firstArg               = "";
                    autoRestartIPCKey      = Constants.startAfterUpdateEventName;
                    autoRestartCommandLine = Path.Combine(installationDir, "logjoint.exe");
                    restartFlagFileName    = null;
                }

                File.Copy(updaterExePath, tempUpdaterExePath);

                trace.Info("updater executable copied to '{0}'", tempUpdaterExePath);

                trace.Info("this update's log is '{0}'", updateLogFileName);

                var updaterExeProcessParams = new ProcessStartInfo()
                {
                    UseShellExecute = false,
                    FileName        = programToStart,
                    Arguments       = string.Format("{0}\"{1}\" \"{2}\" \"{3}\" \"{4}\" \"{5}\" \"{6}\"",
                                                    firstArg,
                                                    installationDir,
                                                    tempInstallationDir,
                                                    mutualExecutionCounter.MutualExecutionKey,
                                                    updateLogFileName,
                                                    autoRestartIPCKey,
                                                    autoRestartCommandLine
                                                    ),
                    WorkingDirectory = Path.GetDirectoryName(tempUpdaterExePath)
                };

                trace.Info("starting updater executable '{0}' with args '{1}'",
                           updaterExeProcessParams.FileName,
                           updaterExeProcessParams.Arguments);

                Environment.SetEnvironmentVariable("MONO_ENV_OPTIONS", "");                 // todo
                var process = Process.Start(updaterExeProcessParams);

                // wait a bit to catch and log immediate updater's failure
                for (int i = 0; i < 10 && !cancellation.IsCancellationRequested; ++i)
                {
                    if (process.HasExited && process.ExitCode != 0)
                    {
                        trace.Error("updater process exited abnormally with code {0}", process.ExitCode);
                        break;
                    }
                    await Task.Delay(100);
                }
                return(process, restartFlagFileName);
            }

            var(updater, autoRestartFlagFileName) = await StartUpdater();

            var key = factory.CreateUpdateKey(
                downloadResults[0].result.ETag,
                ImmutableDictionary.CreateRange(
                    downloadResults.Skip(1).Select(r => r.result.ETag).Zip(requiredPlugins, (etag, plugin) => new KeyValuePair <string, string>(plugin.Id, etag))
                    )
                );

            var pluginsFolder = Path.Combine(tempInstallationDir, Constants.managedAssembliesLocationRelativeToInstallationRoot, "Plugins");

            if (Directory.Exists(pluginsFolder))
            {
                Directory.Delete(pluginsFolder, true);
            }
            Directory.CreateDirectory(pluginsFolder);


            var pluginFormats = new HashSet <string>();

            foreach (var plugin in downloadResults.Skip(1).Zip(requiredPlugins, (downloadResult, plugin) => (plugin, downloadResult)))
            {
                var pluginFolder = Path.Combine(pluginsFolder, plugin.plugin.Id);
                UnzipDownloadedUpdate(plugin.downloadResult.tempZipFile, pluginFolder);
                new UpdateInfoFileContent(plugin.downloadResult.result.ETag, plugin.downloadResult.result.LastModifiedUtc, null).Write(
                    Path.Combine(pluginFolder, Constants.updateInfoFileName));

                try
                {
                    Extensibility.IPluginManifest manifest = new Extensibility.PluginManifest(pluginFolder);
                    pluginFormats.UnionWith(manifest.Files
                                            .Where(f => f.Type == Extensibility.PluginFileType.FormatDefinition)
                                            .Select(f => Path.GetFileName(f.AbsolulePath).ToLower()));
                }
                catch (Extensibility.BadManifestException)
                {
                    continue;
                }
            }

            CopyCustomFormats(
                managedAssembliesPath,
                Path.Combine(tempInstallationDir, Constants.managedAssembliesLocationRelativeToInstallationRoot),
                pluginFormats,                 // Temporary measure: plugin formats used to be copied to root Formats folder. Ignore them on update.
                trace
                );

            return(new PendingUpdate(tempInstallationDir, key, trace, updater, autoRestartFlagFileName));
        }
Esempio n. 8
0
        public AutoUpdater(
            MultiInstance.IInstancesCounter mutualExecutionCounter,
            IUpdateDownloader updateDownloader,
            ITempFilesManager tempFiles,
            IShutdown shutdown,
            IInvokeSynchronization eventInvoker,
            IFirstStartDetector firstStartDetector,
            Telemetry.ITelemetryCollector telemetry,
            Persistence.IStorageManager storage
            )
        {
            this.mutualExecutionCounter = mutualExecutionCounter;
            this.updateDownloader       = updateDownloader;
            this.tempFiles            = tempFiles;
            this.manualCheckRequested = new TaskCompletionSource <int>();
            this.firstStartDetector   = firstStartDetector;

            this.managedAssembliesPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            this.updateInfoFilePath    = Path.Combine(managedAssembliesPath, updateInfoFileName);
            this.installationDir       = Path.GetFullPath(
                Path.Combine(managedAssembliesPath, installationPathRootRelativeToManagedAssembliesLocation));

            this.eventInvoker = eventInvoker;
            this.telemetry    = telemetry;
            this.storage      = storage;

            shutdown.Cleanup += (s, e) => ((IDisposable)this).Dispose();

            this.updatesStorageEntry = storage.GetEntry("updates");

            bool isFirstInstance        = mutualExecutionCounter.IsPrimaryInstance;
            bool isDownloaderConfigured = updateDownloader.IsDownloaderConfigured;

            if (!isDownloaderConfigured)
            {
                trace.Info("autoupdater is disabled - update downloader not configured");
                isActiveAutoUpdaterInstance = false;

                state = AutoUpdateState.Disabled;
            }
            else if (!isFirstInstance)
            {
                trace.Info("autoupdater is deactivated - not a first instance of logjoint");
                isActiveAutoUpdaterInstance = false;

                state = AutoUpdateState.Inactive;
            }
            else
            {
                trace.Info("autoupdater is enabled");
                isActiveAutoUpdaterInstance = true;

                state = AutoUpdateState.Idle;

                workerCancellation      = new CancellationTokenSource();
                workerCancellationToken = workerCancellation.Token;
                workerCancellationTask  = new TaskCompletionSource <int>();

                worker = TaskUtils.StartInThreadPoolTaskScheduler(Worker);
            }
        }
Esempio n. 9
0
        private async Task StartUpdater(string installationDir, string tempInstallationDir, ITempFilesManager tempFiles,
                                        MultiInstance.IInstancesCounter mutualExecutionCounter, CancellationToken cancel)
        {
            var    tempUpdaterExePath = tempFiles.GenerateNewName() + ".lj.updater.exe";
            string updaterExePath;
            string programToStart;
            string firstArg;
            string autoRestartCommandLine;
            string autoRestartIPCKey;

#if MONOMAC
            updaterExePath = Path.Combine(installationDir, managedAssembliesLocationRelativeToInstallationRoot, "logjoint.updater.exe");
            var monoPath = @"/Library/Frameworks/Mono.framework/Versions/Current/bin/mono";
            programToStart         = monoPath;
            firstArg               = string.Format("\"{0}\" ", tempUpdaterExePath);
            autoRestartIPCKey      = autoRestartFlagFileName = tempFiles.GenerateNewName() + ".autorestart";
            autoRestartCommandLine = Path.GetFullPath(Path.Combine(installationDir, ".."));
#else
            updaterExePath         = Path.Combine(installationDir, "updater", "logjoint.updater.exe");
            programToStart         = tempUpdaterExePath;
            firstArg               = "";
            autoRestartIPCKey      = startAfterUpdateEventName;
            autoRestartCommandLine = Path.Combine(installationDir, "logjoint.exe");
#endif

            File.Copy(updaterExePath, tempUpdaterExePath);

            trace.Info("updater executable copied to '{0}'", tempUpdaterExePath);

            var updateLogFileName = ComposeUpdateLogFileName();
            trace.Info("this update's log is '{0}'", updateLogFileName);

            var updaterExeProcessParams = new ProcessStartInfo()
            {
                UseShellExecute = false,
                FileName        = programToStart,
                Arguments       = string.Format("{0}\"{1}\" \"{2}\" \"{3}\" \"{4}\" \"{5}\" \"{6}\"",
                                                firstArg,
                                                installationDir,
                                                tempInstallationDir,
                                                mutualExecutionCounter.MutualExecutionKey,
                                                updateLogFileName,
                                                autoRestartIPCKey,
                                                autoRestartCommandLine
                                                ),
                WorkingDirectory = Path.GetDirectoryName(tempUpdaterExePath)
            };

            trace.Info("starting updater executable '{0}' with args '{1}'",
                       updaterExeProcessParams.FileName,
                       updaterExeProcessParams.Arguments);

            Environment.SetEnvironmentVariable("MONO_ENV_OPTIONS", "");             // todo
            using (var process = Process.Start(updaterExeProcessParams))
            {
                // wait a bit to catch and log immediate updater's failure
                for (int i = 0; i < 10 && !cancel.IsCancellationRequested; ++i)
                {
                    if (process.HasExited && process.ExitCode != 0)
                    {
                        trace.Error("updater process exited abnormally with code {0}", process.ExitCode);
                        break;
                    }
                    await Task.Delay(100);
                }
            }
        }
Esempio n. 10
0
        public AutoUpdater(
            IFactory factory,
            MultiInstance.IInstancesCounter mutualExecutionCounter,
            IShutdown shutdown,
            ISynchronizationContext eventInvoker,
            Telemetry.ITelemetryCollector telemetry,
            Persistence.IStorageManager storage,
            ITraceSourceFactory traceSourceFactory,
            Extensibility.IPluginsManagerInternal pluginsManager,
            IChangeNotification changeNotification
            )
        {
            this.updateDownloader = factory.CreateAppUpdateDownloader();
            this.checkRequested   = new TaskCompletionSource <int>();
            this.factory          = factory;
            this.pluginsManager   = pluginsManager;
            this.trace            = traceSourceFactory.CreateTraceSource("AutoUpdater");

            var entryAssemblyLocation = Assembly.GetEntryAssembly()?.Location;

            if (entryAssemblyLocation != null)
            {
                this.managedAssembliesPath = Path.GetDirectoryName(entryAssemblyLocation);
                this.updateInfoFilePath    = Path.Combine(managedAssembliesPath, Constants.updateInfoFileName);
                this.installationDir       = Path.GetFullPath(
                    Path.Combine(managedAssembliesPath, Constants.installationPathRootRelativeToManagedAssembliesLocation));
            }

            this.eventInvoker = eventInvoker;
            this.telemetry    = telemetry;
            this.storage      = storage;

            shutdown.Cleanup += (s, e) => ((IDisposable)this).Dispose();

            this.updatesStorageEntry = storage.GetEntry("updates");

            bool isFirstInstance        = mutualExecutionCounter.IsPrimaryInstance;
            bool isDownloaderConfigured = updateDownloader.IsDownloaderConfigured;

            if (entryAssemblyLocation == null)
            {
                trace.Info("autoupdater is disabled - no entry assembly");
                isActiveAutoUpdaterInstance = false;

                state = AutoUpdateState.Disabled;
            }
            else if (!isDownloaderConfigured)
            {
                trace.Info("autoupdater is disabled - update downloader not configured");
                isActiveAutoUpdaterInstance = false;

                state = AutoUpdateState.Disabled;
            }
            else if (!isFirstInstance)
            {
                trace.Info("autoupdater is deactivated - not a first instance of logjoint");
                isActiveAutoUpdaterInstance = false;

                state = AutoUpdateState.Inactive;
            }
            else
            {
                trace.Info("autoupdater is enabled");
                isActiveAutoUpdaterInstance = true;

                state = AutoUpdateState.Idle;

                workerCancellation      = new CancellationTokenSource();
                workerCancellationToken = workerCancellation.Token;
                workerCancellationTask  = new TaskCompletionSource <int>();

                changeListenerSubscription = changeNotification.CreateSubscription(Updaters.Create(
                                                                                       () => pluginsManager.InstallationRequests,
                                                                                       (_, prev) =>
                {
                    if (prev != null)
                    {
                        checkRequested.TrySetResult(1);
                    }
                }
                                                                                       ));

                worker = TaskUtils.StartInThreadPoolTaskScheduler(Worker);
            }
        }
Esempio n. 11
0
        public static ModelObjects Create(
            ModelConfig config,
            ISynchronizationContext modelSynchronizationContext,
            Func <Persistence.IStorageManager, Preprocessing.ICredentialsCache> createPreprocessingCredentialsCache,
            Func <IShutdownSource, Persistence.IWebContentCache, ITraceSourceFactory, WebViewTools.IWebViewTools> createWebBrowserDownloader,
            Drawing.IMatrixFactory matrixFactory,
            RegularExpressions.IRegexFactory regexFactory
            )
        {
            ITraceSourceFactory traceSourceFactory = new TraceSourceFactory(config.TraceListeners);
            IShutdownSource     shutdown           = new Shutdown();
            var tracer = traceSourceFactory.CreateTraceSource("App", "model");

            Telemetry.UnhandledExceptionsReporter.SetupLogging(tracer, shutdown);
            ILogProviderFactoryRegistry  logProviderFactoryRegistry  = new LogProviderFactoryRegistry();
            IFormatDefinitionsRepository formatDefinitionsRepository = new DirectoryFormatsRepository(null);

            MultiInstance.IInstancesCounter instancesCounter = config.DisableLogjointInstancesCounting ?
                                                               (MultiInstance.IInstancesCounter) new MultiInstance.DummyInstancesCounter() :
                                                               (MultiInstance.IInstancesCounter) new MultiInstance.InstancesCounter(shutdown);
            ITempFilesManager tempFilesManager = new TempFilesManager(traceSourceFactory, instancesCounter);

            Persistence.Implementation.IStorageManagerImplementation userDataStorage = new Persistence.Implementation.StorageManagerImplementation();
            Persistence.IStorageManager storageManager = new Persistence.PersistentUserDataManager(traceSourceFactory, userDataStorage, shutdown);
            var persistentUserDataFileSystem           = Persistence.Implementation.DesktopFileSystemAccess.CreatePersistentUserDataFileSystem(config.AppDataDirectory);

            Settings.IGlobalSettingsAccessor globalSettingsAccessor = new Settings.GlobalSettingsAccessor(storageManager);
            userDataStorage.Init(
                new Persistence.Implementation.RealTimingAndThreading(),
                persistentUserDataFileSystem,
                new Persistence.PersistentUserDataManager.ConfigAccess(globalSettingsAccessor)
                );
            Telemetry.ITelemetryUploader telemetryUploader = new Telemetry.AzureTelemetryUploader(
                traceSourceFactory,
                config.TelemetryUrl,
                config.IssuesUrl
                );
            var telemetryCollectorImpl = new Telemetry.TelemetryCollector(
                storageManager,
                telemetryUploader,
                modelSynchronizationContext,
                instancesCounter,
                shutdown,
                new MemBufferTraceAccess(),
                traceSourceFactory
                );

            Telemetry.ITelemetryCollector telemetryCollector        = telemetryCollectorImpl;
            FieldsProcessor.IFactory      fieldsProcessorFactory    = new FieldsProcessor.FieldsProcessorImpl.Factory(storageManager, telemetryCollector);
            UserDefinedFormatsManager     userDefinedFormatsManager = new UserDefinedFormatsManager(
                formatDefinitionsRepository, logProviderFactoryRegistry, tempFilesManager, traceSourceFactory, regexFactory, fieldsProcessorFactory);

            RegisterUserDefinedFormats(userDefinedFormatsManager);
            RegisterPredefinedFormatFactories(logProviderFactoryRegistry, tempFilesManager, userDefinedFormatsManager, regexFactory, traceSourceFactory);
            ISynchronizationContext threadPoolSynchronizationContext = new ThreadPoolSynchronizationContext();
            IChangeNotification     changeNotification = new ChangeNotification(modelSynchronizationContext);
            IFiltersFactory         filtersFactory     = new FiltersFactory(changeNotification, regexFactory);
            IBookmarksFactory       bookmarksFactory   = new BookmarksFactory(changeNotification);
            var bookmarks = bookmarksFactory.CreateBookmarks();

            Persistence.IFirstStartDetector firstStartDetector = persistentUserDataFileSystem;
            Persistence.Implementation.IStorageManagerImplementation contentCacheStorage = new Persistence.Implementation.StorageManagerImplementation();
            contentCacheStorage.Init(
                new Persistence.Implementation.RealTimingAndThreading(),
                Persistence.Implementation.DesktopFileSystemAccess.CreateCacheFileSystemAccess(config.AppDataDirectory),
                new Persistence.ContentCacheManager.ConfigAccess(globalSettingsAccessor)
                );
            Persistence.IContentCache           contentCache          = new Persistence.ContentCacheManager(traceSourceFactory, contentCacheStorage);
            Persistence.IWebContentCacheConfig  webContentCacheConfig = config.WebContentCacheConfig;
            Preprocessing.ILogsDownloaderConfig logsDownloaderConfig  = config.LogsDownloaderConfig;
            Persistence.IWebContentCache        webContentCache       = new Persistence.WebContentCache(
                contentCache,
                webContentCacheConfig
                );
            IHeartBeatTimer heartBeatTimer = new HeartBeatTimer();

            Progress.IProgressAggregatorFactory progressAggregatorFactory = new Progress.ProgressAggregator.Factory(heartBeatTimer, modelSynchronizationContext);
            Progress.IProgressAggregator        progressAggregator        = progressAggregatorFactory.CreateProgressAggregator();

            var threadColorsLease = new ColorLease(1);
            IModelThreadsInternal modelThreads = new ModelThreads(threadColorsLease);


            MRU.IRecentlyUsedEntities recentlyUsedLogs = new MRU.RecentlyUsedEntities(
                storageManager,
                logProviderFactoryRegistry,
                telemetryCollector
                );

            ILogSourcesManager logSourcesManager = new LogSourcesManager(
                heartBeatTimer,
                modelSynchronizationContext,
                modelThreads,
                tempFilesManager,
                storageManager,
                bookmarks,
                globalSettingsAccessor,
                recentlyUsedLogs,
                shutdown,
                traceSourceFactory,
                changeNotification,
                regexFactory
                );

            telemetryCollectorImpl.SetLogSourcesManager(logSourcesManager);

            Telemetry.UnhandledExceptionsReporter.Setup(telemetryCollector, shutdown);

            IFormatAutodetect formatAutodetect = new FormatAutodetect(
                recentlyUsedLogs,
                logProviderFactoryRegistry,
                traceSourceFactory
                );

            Workspaces.Backend.IBackendAccess workspacesBackendAccess = new Workspaces.Backend.AzureWorkspacesBackend(
                traceSourceFactory,
                config.WorkspacesUrl
                );

            Workspaces.IWorkspacesManager workspacesManager = new Workspaces.WorkspacesManager(
                logSourcesManager,
                logProviderFactoryRegistry,
                storageManager,
                workspacesBackendAccess,
                tempFilesManager,
                recentlyUsedLogs,
                shutdown,
                traceSourceFactory
                );

            AppLaunch.ILaunchUrlParser launchUrlParser = new AppLaunch.LaunchUrlParser();

            Preprocessing.IExtensionsRegistry preprocessingManagerExtensionsRegistry =
                new Preprocessing.PreprocessingManagerExtentionsRegistry(logsDownloaderConfig);

            Preprocessing.ICredentialsCache preprocessingCredentialsCache = createPreprocessingCredentialsCache(
                storageManager
                );

            WebViewTools.IWebViewTools webBrowserDownloader = createWebBrowserDownloader(shutdown, webContentCache, traceSourceFactory);

            Preprocessing.IStepsFactory preprocessingStepsFactory = new Preprocessing.PreprocessingStepsFactory(
                workspacesManager,
                launchUrlParser,
                modelSynchronizationContext,
                preprocessingManagerExtensionsRegistry,
                progressAggregator,
                webContentCache,
                preprocessingCredentialsCache,
                logProviderFactoryRegistry,
                webBrowserDownloader,
                logsDownloaderConfig,
                regexFactory
                );

            Preprocessing.IManager logSourcesPreprocessings = new Preprocessing.LogSourcesPreprocessingManager(
                modelSynchronizationContext,
                formatAutodetect,
                preprocessingManagerExtensionsRegistry,
                new Preprocessing.BuiltinStepsExtension(preprocessingStepsFactory),
                telemetryCollector,
                tempFilesManager,
                logSourcesManager,
                shutdown,
                traceSourceFactory,
                changeNotification
                );

            ISearchManager searchManager = new SearchManager(
                logSourcesManager,
                progressAggregatorFactory,
                modelSynchronizationContext,
                globalSettingsAccessor,
                telemetryCollector,
                heartBeatTimer,
                changeNotification,
                traceSourceFactory
                );

            IUserDefinedSearches userDefinedSearches = new UserDefinedSearchesManager(storageManager, filtersFactory, modelSynchronizationContext);

            ISearchHistory searchHistory = new SearchHistory(storageManager.GlobalSettingsEntry, userDefinedSearches);

            IBookmarksController bookmarksController = new BookmarkController(
                bookmarks,
                modelThreads,
                heartBeatTimer
                );

            IFiltersManager filtersManager = new FiltersManager(
                filtersFactory,
                globalSettingsAccessor,
                logSourcesManager,
                shutdown
                );

            Postprocessing.IUserNamesProvider analyticsShortNames = new Postprocessing.CodenameUserNamesProvider(
                logSourcesManager
                );

            Postprocessing.TimeSeries.ITimeSeriesTypesAccess timeSeriesTypesAccess = new Postprocessing.TimeSeries.TimeSeriesTypesLoader();

            Postprocessing.ILogPartTokenFactories logPartTokenFactories = new Postprocessing.LogPartTokenFactories();

            Postprocessing.Correlation.ISameNodeDetectionTokenFactories sameNodeDetectionTokenFactories = new Postprocessing.Correlation.SameNodeDetectionTokenFactories();

            Postprocessing.IManagerInternal postprocessorsManager = new Postprocessing.PostprocessorsManager(
                logSourcesManager,
                telemetryCollector,
                modelSynchronizationContext,
                threadPoolSynchronizationContext,
                heartBeatTimer,
                progressAggregator,
                globalSettingsAccessor,
                new Postprocessing.OutputDataDeserializer(timeSeriesTypesAccess, logPartTokenFactories, sameNodeDetectionTokenFactories),
                traceSourceFactory,
                logPartTokenFactories,
                sameNodeDetectionTokenFactories,
                changeNotification
                );

            Postprocessing.Correlation.ICorrelationManager correlationManager = new Postprocessing.Correlation.CorrelationManager(
                postprocessorsManager,
                () => new LogJoint.Postprocessing.Correlation.EmbeddedSolver.EmbeddedSolver(),
                modelSynchronizationContext,
                logSourcesManager,
                changeNotification,
                telemetryCollector
                );


            Postprocessing.IModel postprocessingModel = new Postprocessing.Model(
                postprocessorsManager,
                timeSeriesTypesAccess,
                new Postprocessing.StateInspector.Model(tempFilesManager, logPartTokenFactories),
                new Postprocessing.Timeline.Model(tempFilesManager, logPartTokenFactories),
                new Postprocessing.SequenceDiagram.Model(tempFilesManager, logPartTokenFactories),
                new Postprocessing.TimeSeries.Model(timeSeriesTypesAccess),
                new Postprocessing.Correlation.Model(tempFilesManager, logPartTokenFactories, sameNodeDetectionTokenFactories)
                );

            AutoUpdate.IFactory autoUpdateFactory = new AutoUpdate.Factory(
                tempFilesManager,
                traceSourceFactory,
                instancesCounter,
                shutdown,
                modelSynchronizationContext,
                firstStartDetector,
                telemetryCollector,
                storageManager,
                changeNotification,
                config.AutoUpdateUrl,
                config.PluginsUrl
                );

            AppLaunch.ICommandLineHandler commandLineHandler = new AppLaunch.CommandLineHandler(
                logSourcesPreprocessings,
                preprocessingStepsFactory);

            Postprocessing.IAggregatingLogSourceNamesProvider logSourceNamesProvider = new Postprocessing.AggregatingLogSourceNamesProvider();

            Postprocessing.InternalTracePostprocessors.Register(
                postprocessorsManager,
                userDefinedFormatsManager,
                timeSeriesTypesAccess,
                postprocessingModel
                );

            Extensibility.IPluginsManagerInternal pluginsManager = new Extensibility.PluginsManager(
                traceSourceFactory,
                telemetryCollector,
                shutdown,
                userDefinedFormatsManager,
                autoUpdateFactory.CreatePluginsIndexUpdateDownloader(),
                new Extensibility.PluginsIndex.Factory(telemetryCollector),
                changeNotification,
                autoUpdateFactory.CreateAppUpdateDownloader()
                );

            AutoUpdate.IAutoUpdater autoUpdater = autoUpdateFactory.CreateAutoUpdater(pluginsManager);

            Model expensibilityModel = new Model(
                modelSynchronizationContext,
                changeNotification,
                webContentCache,
                contentCache,
                storageManager,
                bookmarks,
                logSourcesManager,
                modelThreads,
                tempFilesManager,
                new Preprocessing.Model(
                    logSourcesPreprocessings,
                    preprocessingStepsFactory,
                    preprocessingManagerExtensionsRegistry
                    ),
                progressAggregator,
                logProviderFactoryRegistry,
                userDefinedFormatsManager,
                recentlyUsedLogs,
                progressAggregatorFactory,
                shutdown,
                webBrowserDownloader,
                postprocessingModel,
                pluginsManager,
                traceSourceFactory
                );

            tracer.Info("model creation completed");

            return(new ModelObjects
            {
                GlobalSettingsAccessor = globalSettingsAccessor,
                InstancesCounter = instancesCounter,
                Shutdown = shutdown,
                TelemetryCollector = telemetryCollector,
                FirstStartDetector = firstStartDetector,
                LaunchUrlParser = launchUrlParser,
                ChangeNotification = changeNotification,
                BookmarksFactory = bookmarksFactory,
                LogSourcesManager = logSourcesManager,
                ModelThreads = modelThreads,
                FiltersManager = filtersManager,
                Bookmarks = bookmarks,
                SearchManager = searchManager,
                FiltersFactory = filtersFactory,
                LogSourcesPreprocessings = logSourcesPreprocessings,
                UserDefinedSearches = userDefinedSearches,
                SearchHistory = searchHistory,
                ProgressAggregatorFactory = progressAggregatorFactory,
                PreprocessingStepsFactory = preprocessingStepsFactory,
                WorkspacesManager = workspacesManager,
                RecentlyUsedLogs = recentlyUsedLogs,
                LogProviderFactoryRegistry = logProviderFactoryRegistry,
                UserDefinedFormatsManager = userDefinedFormatsManager,
                PluginFormatsManager = userDefinedFormatsManager,
                FormatDefinitionsRepository = formatDefinitionsRepository,
                TempFilesManager = tempFilesManager,
                StorageManager = storageManager,
                TelemetryUploader = telemetryUploader,
                ProgressAggregator = progressAggregator,
                PostprocessorsManager = postprocessorsManager,
                CorrelationManager = correlationManager,
                ExpensibilityEntryPoint = expensibilityModel,
                AnalyticsShortNames = analyticsShortNames,
                SynchronizationContext = modelSynchronizationContext,
                AutoUpdater = autoUpdater,
                CommandLineHandler = commandLineHandler,
                LogSourceNamesProvider = logSourceNamesProvider,
                HeartBeatTimer = heartBeatTimer,
                ThreadColorsLease = threadColorsLease,
                PluginsManager = pluginsManager,
                TraceSourceFactory = traceSourceFactory,
                MatrixFactory = matrixFactory,
                RegexFactory = regexFactory,
                FieldsProcessorFactory = fieldsProcessorFactory,
            });
        }