public async Task<IGalleryContext> CreateAsync(ContextConfiguration config, CancellationToken cancellationToken)
        {
            var workspace = config.Workspace;
            var acceptSnapshot = workspace == null;

            var sandboxes = config.Sandboxes ?? new SandboxCollection();

            if (workspace != DefaultWorkspace && sandboxes.Count == 0)
            {
                var extendedWorkspacesClient = ExtendedWorkspacesClient.FromEndpointUri(config.WorkspacesEndpoint,
                config.AuthenticationToken, acceptSnapshot);

                sandboxes = await extendedWorkspacesClient.GetActiveSandboxesAsync(config.AccountName, workspace,
                cancellationToken).ConfigureAwait(false);
            }

            return await ConnectAsync(config.WorkspacesEndpoint, config.AppsEndpoint, config.AuthenticationToken,
                config.AccountName, acceptSnapshot, workspace, sandboxes,
                config.ServiceName, config.ArchiveExcludePrefixes, cancellationToken).ConfigureAwait(false);
        }
        public async Task<IGalleryContext> CreateFromApiRequestAsync(HttpRequestMessage request,
            ContextConfiguration config, CancellationToken cancellationToken)
        {
            var specifiedWorkspace = config.Workspace ?? GetWorkspaceFromHeader(request);
            var workspace = specifiedWorkspace ?? DefaultWorkspace;
            var acceptSnapshot = GetAcceptSnapshotFromHeader(request);

            var sandboxes = config.Sandboxes ?? SandboxCollection.FromHeaders(request.Headers);
            var accountName = config.AccountName ?? GetAccountNameFromPath(request.RequestUri);

            if (workspace != DefaultWorkspace && sandboxes.Count == 0)
            {
                var extendedWorkspacesClient = ExtendedWorkspacesClient.FromEndpointUri(config.WorkspacesEndpoint,
                config.AuthenticationToken, acceptSnapshot);

                sandboxes = await extendedWorkspacesClient.GetActiveSandboxesAsync(accountName, workspace,
                cancellationToken).ConfigureAwait(false);
            }

            return await ConnectAsync(config.WorkspacesEndpoint, config.AppsEndpoint, config.AuthenticationToken, accountName,
                acceptSnapshot, workspace, sandboxes, config.ServiceName, config.ArchiveExcludePrefixes,
                cancellationToken).ConfigureAwait(false);
        }
        public async Task<IGalleryContext> CreateFromPageRequestAsync(HttpRequestMessage request,
            ContextConfiguration config, CancellationToken cancellationToken)
        {
            var specifiedWorkspace = config.Workspace ?? GetWorkspaceFromCookie(request);
            var acceptSnapshot = specifiedWorkspace == null;
            var workspace = specifiedWorkspace ?? DefaultWorkspace;

            var extendedWorkspacesClient = ExtendedWorkspacesClient.FromEndpointUri(config.WorkspacesEndpoint,
                config.AuthenticationToken, acceptSnapshot);
            var sandboxes = new SandboxCollection();

            if (workspace != DefaultWorkspace)
            {
                sandboxes = await extendedWorkspacesClient.GetActiveSandboxesAsync(config.AccountName, workspace,
                cancellationToken).ConfigureAwait(false);
            }

            if (string.IsNullOrWhiteSpace(config.AccountName))
                throw new ArgumentException("You must set the account name in ContextConfiguration.");

            return await ConnectAsync(extendedWorkspacesClient, config.AppsEndpoint, config.AuthenticationToken,
                config.AccountName, workspace, sandboxes, config.ServiceName, config.ArchiveExcludePrefixes,
                cancellationToken).ConfigureAwait(false);
        }