protected async Task UploadInstanceAsync(
            ApplicationInstanceType applicationInstanceType,
            ApplicationPackageType applicationPackageType,
            IEnumerable <ServicePackageType> servicePackages,
            StoreLayoutSpecification storeLayoutSpecification /* If null, don't upload to store */,
            StoreLayoutSpecification clusterManagerOutputSpecification /* If null, dont write to output folder*/,
            bool shouldOverwrite,
            TimeoutHelper timeoutHelper)
        {
            List <Task> uploadTasks = new List <Task>();

            // Write ApplicationInstance to Store
            if (storeLayoutSpecification != null)
            {
                ImageBuilder.TraceSource.WriteInfo(
                    TraceType,
                    "Starting to upload the ApplicationInstance, ApplicationPackage, ServicePackage to the store. ApplicationTypeName:{0}, ApplicationTypeVersion:{1}.",
                    applicationInstanceType.ApplicationTypeName,
                    applicationInstanceType.ApplicationTypeVersion);

                string applicationInstanceLocation = storeLayoutSpecification.GetApplicationInstanceFile(
                    applicationInstanceType.ApplicationTypeName,
                    applicationInstanceType.ApplicationId,
                    applicationInstanceType.Version.ToString(CultureInfo.InvariantCulture));
                var uploadInstanceTask = this.ImageStoreWrapper.SetToStoreAsync <ApplicationInstanceType>(applicationInstanceLocation, applicationInstanceType, timeoutHelper.GetRemainingTime(), shouldOverwrite);

                uploadTasks.Add(uploadInstanceTask);

                string applicationPackageLocation = storeLayoutSpecification.GetApplicationPackageFile(
                    applicationPackageType.ApplicationTypeName,
                    applicationPackageType.ApplicationId,
                    applicationPackageType.RolloutVersion);
                var uploadApplicationPackageTask = this.ImageStoreWrapper.SetToStoreAsync <ApplicationPackageType>(applicationPackageLocation, applicationPackageType, timeoutHelper.GetRemainingTime(), shouldOverwrite);

                uploadTasks.Add(uploadApplicationPackageTask);
                TimeSpan remainingTime = timeoutHelper.GetRemainingTime();
                foreach (ServicePackageType servicePackage in servicePackages)
                {
                    // Write ServicePackage to Store
                    string servicePackageLocation = storeLayoutSpecification.GetServicePackageFile(
                        applicationInstanceType.ApplicationTypeName,
                        applicationInstanceType.ApplicationId,
                        servicePackage.Name,
                        servicePackage.RolloutVersion);
                    var uploadServicePackageTask = this.ImageStoreWrapper.SetToStoreAsync <ServicePackageType>(servicePackageLocation, servicePackage, remainingTime, shouldOverwrite);

                    uploadTasks.Add(uploadServicePackageTask);
                }

                await Task.WhenAll(uploadTasks);
            }

            // Write ApplicationInstance to the outputFolder for the CM
            if (clusterManagerOutputSpecification != null)
            {
                ImageBuilder.TraceSource.WriteInfo(
                    TraceType,
                    "Starting to write the ApplicationInstance, ApplicationPackage, ServicePackage to folder {0}. ApplicationTypeName:{1}, ApplicationTypeVersion:{2}.",
                    clusterManagerOutputSpecification.GetRoot(),
                    applicationInstanceType.ApplicationTypeName,
                    applicationInstanceType.ApplicationTypeVersion);

                string clusterManagerApplicationInstanceLocation = clusterManagerOutputSpecification.GetApplicationInstanceFile(
                    applicationInstanceType.ApplicationTypeName,
                    applicationInstanceType.ApplicationId,
                    applicationInstanceType.Version.ToString(CultureInfo.InvariantCulture));
                ImageBuilderUtility.WriteXml <ApplicationInstanceType>(clusterManagerApplicationInstanceLocation, applicationInstanceType);

                string clusterManagerApplicationPackageLocation = clusterManagerOutputSpecification.GetApplicationPackageFile(
                    applicationPackageType.ApplicationTypeName,
                    applicationPackageType.ApplicationId,
                    applicationPackageType.RolloutVersion);
                ImageBuilderUtility.WriteXml <ApplicationPackageType>(clusterManagerApplicationPackageLocation, applicationPackageType);

                foreach (ServicePackageType servicePackage in servicePackages)
                {
                    string clusterManagerServicePackageLocation = clusterManagerOutputSpecification.GetServicePackageFile(
                        applicationInstanceType.ApplicationTypeName,
                        applicationInstanceType.ApplicationId,
                        servicePackage.Name,
                        servicePackage.RolloutVersion);
                    ImageBuilderUtility.WriteXml <ServicePackageType>(clusterManagerServicePackageLocation, servicePackage);
                }
            }

            ImageBuilder.TraceSource.WriteInfo(
                TraceType,
                "Completed uploading/writing ApplicationInstance, ApplicationPackage, ServicePackage to the store/folder. ApplicationTypeName:{0}, ApplicationTypeVersion:{1}.",
                applicationInstanceType.ApplicationTypeName,
                applicationInstanceType.ApplicationTypeVersion);
        }