private void ReinstallContent(PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken)
        {
            IUninstallCommand uninstall = _commandFactory.CreateUninstallCommand(Context);

            uninstall.Prepare(_status, cancellationToken);
            uninstall.Execute(cancellationToken);

            // not catching any exceptions here, because exception during content installation in this place should be fatal
            var contentStrategy = new AppUpdaterContentStrategy(Context, _status);

            contentStrategy.RepairOnError = false; // do not attempt to repair content to not cause a loop
            contentStrategy.Update(cancellationToken);
        }
        private void PreUpdate(PatchKit.Unity.Patcher.Cancellation.CancellationToken cancellationToken)
        {
            DebugLogger.Log("Pre update integrity check");

            var commandFactory = new AppUpdaterCommandFactory();

            int installedVersionId         = Context.App.GetInstalledVersionId();
            int latestVersionId            = Context.App.GetLatestVersionId();
            int lowestVersionWithContentId = Context.App.GetLowestVersionWithContentId();

            if (lowestVersionWithContentId > installedVersionId)
            {
                DebugLogger.Log(
                    "Repair is impossible because lowest version with content id is "
                    + lowestVersionWithContentId +
                    " and currently installed version id is "
                    + installedVersionId +
                    ". Uninstalling to prepare for content strategy.");

                IUninstallCommand uninstall = commandFactory.CreateUninstallCommand(Context);
                uninstall.Prepare(_status);
                uninstall.Execute(cancellationToken);
                return;
            }

            AppContentSummary installedVersionContentSummary
                = Context.App.RemoteMetaData.GetContentSummary(installedVersionId);

            AppContentSummary latestVersionContentSummary
                = Context.App.RemoteMetaData.GetContentSummary(latestVersionId);

            bool isNewVersionAvailable = installedVersionId < latestVersionId;

            long contentSize = isNewVersionAvailable
                ? latestVersionContentSummary.Size
                : installedVersionContentSummary.Size;

            ICheckVersionIntegrityCommand checkIntegrity = commandFactory
                                                           .CreateCheckVersionIntegrityCommand(
                versionId: installedVersionId,
                context: Context,
                isCheckingHash: false,
                isCheckingSize: true);

            checkIntegrity.Prepare(_status);
            checkIntegrity.Execute(cancellationToken);

            var missingFiles = checkIntegrity.Results.Files
                               .Where(f => f.Status == FileIntegrityStatus.MissingData);

            int missingFilesCount = missingFiles.Count();

            var invalidSizeFiles = checkIntegrity.Results.Files
                                   .Where(f => f.Status == FileIntegrityStatus.InvalidSize);

            int invalidSizeFilesCount = invalidSizeFiles.Count();

            if (missingFilesCount + invalidSizeFilesCount == 0)
            {
                DebugLogger.Log("No missing or invalid size files.");
                return;
            }

            double repairCost = CalculateRepairCost(installedVersionContentSummary, missingFiles.Concat(invalidSizeFiles));

            if (repairCost < contentSize)
            {
                DebugLogger.Log(string.Format("Repair cost {0} is smaller than content cost {1}, repairing...", repairCost, contentSize));
                IAppUpdaterStrategy repairStrategy = _strategyResolver.Create(StrategyType.Repair, Context);
                repairStrategy.Update(cancellationToken);
            }
            else
            {
                DebugLogger.Log("Content cost is smaller than repair. Uninstalling to prepare for content strategy.");
                IUninstallCommand uninstall = commandFactory.CreateUninstallCommand(Context);
                uninstall.Prepare(_status);
                uninstall.Execute(cancellationToken);
            }
        }