public GetAppInstallFilesBlobDialogViewModel()
        {
            // Show/Hide Blob
            ShowHideBlobSectionCommand.Subscribe(_ =>
            {
                ShowHideBlobSectionButtonLabel.Value = ShowBlobSectionVisibility.Value == Visibility.Collapsed
                    ? ExpandButtonLabel
                    : CollapseButtonLabel;
                ShowBlobSectionVisibility.Value = ShowBlobSectionVisibility.Value == Visibility.Collapsed
                    ? Visibility.Visible
                    : Visibility.Collapsed;
            })
            .AddTo(disposable);

            // Storage Credential Input
            StorageConnectionInput = new ReactiveProperty <string>(blobConnectionUseCase.Read <string>("blob_connection_string"));
            StorageConnectionInput.Subscribe(x => blobConnectionUseCase.Save("blob_connection_string", x)).AddTo(disposable);
            StorageContainerInput = new ReactiveProperty <string>(blobConnectionUseCase.Read <string>("container"));
            StorageContainerInput.Subscribe(x => blobConnectionUseCase.Save("container", x)).AddTo(disposable);

            // Copy Button
            CopyButtonContent  = new ReactiveProperty <string>("Copy SasUrl");
            CopyButtonEnabled  = ArtifactUrl.Select(x => !string.IsNullOrWhiteSpace(x)).ToReactiveProperty();
            OnClickCopyCommand = CopyButtonEnabled.ToReactiveCommand();
            OnClickCopyCommand
            .Do(_ => blobSasUrlUseCase.CopySasUrl(ArtifactUrl.Value, StorageConnectionInput.Value, StorageContainerInput.Value, SelectedArtifact.Value.Name))
            .SelectMany(x => TemporaryDisableCopyButtonAsObservable(TimeSpan.FromMilliseconds(500), "Copy SasUrl"))
            .Subscribe()
            .AddTo(disposable);

            // Download Button
            blobArtifactUsecase.DownloadStatus.Subscribe(x => DownloadStatus.Value = x).AddTo(disposable);
            OnClickDownloadCommand = CopyButtonEnabled.ToAsyncReactiveCommand();
            OnClickDownloadCommand
            .Subscribe(async _ => await blobArtifactUsecase.DownloadHoloLensPackagesAsync(StorageConnectionInput.Value, StorageContainerInput.Value, SelectedArtifact.Value.Name, SelectedArtifact.Value.Size, SelectedArtifact.Value.FileName))
            .AddTo(disposable);

            // OpenFolder Button
            OnClickOpenDownloadFolderCommand.Subscribe(_ => blobArtifactUsecase.OpenFolderAsync()).AddTo(disposable);
            OnClickOpenDownloadBlobFolderCommand.Subscribe(_ => blobArtifactUsecase.OpenDownloadFolderAsync()).AddTo(disposable);

            // Initialize by obtain artifact informations
            blobArtifactUsecase.Artifacts
            .Where(x => x != null)
            .Do(x =>
            {
                Projects.Add(x);
                BlobResult.Value = $"Found {Projects.Count} projects.";
            })
            .Subscribe()
            .AddTo(disposable);
            blobArtifactUsecase.RequestFailedMessage
            .Do(x => BlobResult.Value = x)
            .Subscribe()
            .AddTo(disposable);

            // Blob Download
            ComboBoxEnabled         = Projects.CollectionChangedAsObservable().Any().ToReactiveProperty();
            IsEnableCheckBlobButton = StorageConnectionInput
                                      .CombineLatest(StorageContainerInput, (r, l) => !string.IsNullOrWhiteSpace(r) && !string.IsNullOrWhiteSpace(l))
                                      .ToReadOnlyReactiveProperty();
            OnClickCheckBlobCommand = IsEnableCheckBlobButton.ToAsyncReactiveCommand();
            OnClickCheckBlobCommand.Subscribe(async _ =>
            {
                var task             = blobArtifactUsecase.RequestHoloLensPackagesAsync(StorageConnectionInput.Value, StorageContainerInput.Value);
                IsBlobChecking.Value = true;
                Projects.Clear();
                Branches?.Clear();
                Artifacts?.Clear();
                BlobResult.Value = "Trying obtain project infomations.";
                await task;
                IsBlobChecking.Value = false;
            })
            .AddTo(disposable);
            OnClickCancelBlobCommand = IsBlobChecking.Select(x => x).ToReactiveCommand();
            OnClickCancelBlobCommand
            .Do(_ => Projects.Clear())
            .Subscribe(_ => blobArtifactUsecase.CancelRequest())
            .AddTo(disposable);

            // Update Collection with Clear existing collection when selected.
            Branches = SelectedProject.Where(x => x != null)
                       .Do(_ => Branches?.Clear())
                       .Do(_ => Artifacts?.Clear())
                       .SelectMany(x => blobArtifactUsecase.GetArtifactCache(x.Project))
                       .ToReactiveCollection();
            Artifacts = SelectedBranch.Where(x => x != null)
                        .Do(x => Artifacts?.Clear())
                        .SelectMany(x => blobArtifactUsecase.GetArtifactCache(SelectedProject.Value?.Project, x.Branch))
                        .ToReactiveCollection();
            SelectedArtifact
            .Where(x => x != null)
            .Do(x =>
            {
                ArtifactName.Value    = x.Name;
                ArtifactCaption.Value = $"(Size: {x.Size}, MD5: {x.MD5}, LeaseState: {x.LeaseState})";
                ArtifactUrl.Value     = x.Uri.AbsoluteUri;
            })
            .ToReactiveProperty();
        }