public async Task <Target> CreateTarget(string displayName, string description, IReadOnlyDictionary <string, string> labels, byte[] referenceImageBinaries)
        {
            GoogleCredential cred = this.CreateCredentials();
            var channel           = new Channel(ProductSearchClient.DefaultEndpoint.Host, ProductSearchClient.DefaultEndpoint.Port, cred.ToChannelCredentials());

            try
            {
                var client  = ProductSearchClient.Create(channel);
                var storage = await StorageClient.CreateAsync(cred);

                string productId            = Guid.NewGuid().ToString();
                var    createProductOptions = new CreateProductOptions
                {
                    ProjectID       = this.options.Value.ProjectId,
                    ComputeRegion   = this.options.Value.LocationId,
                    ProductID       = productId,
                    ProductCategory = "apparel",
                    DisplayName     = displayName,
                    Description     = description,
                    ProductLabels   = labels,
                };
                Product product = await this.CreateProduct(client, createProductOptions);

                var addProductOptions = new AddProductToProductSetOptions
                {
                    ProjectID     = this.options.Value.ProjectId,
                    ComputeRegion = this.options.Value.LocationId,
                    ProductID     = product.ProductName.ProductId,
                    ProductSetId  = this.options.Value.ProductSetId,
                };
                await this.AddProductToProductSet(client, addProductOptions);

                string referenceImageId = Guid.NewGuid().ToString();
                await this.UploadFile(storage, this.options.Value.StorageBucketName, referenceImageId, referenceImageBinaries);

                var createReferenceImageOptions = new CreateReferenceImageOptions
                {
                    ProjectID         = this.options.Value.ProjectId,
                    ComputeRegion     = this.options.Value.LocationId,
                    ProductID         = product.ProductName.ProductId,
                    ReferenceImageID  = referenceImageId,
                    ReferenceImageURI = $"gs://{this.options.Value.StorageBucketName}/{referenceImageId}",
                };
                Google.Cloud.Vision.V1.ReferenceImage referenceImage = await this.CreateReferenceImage(client, createReferenceImageOptions);

                Target target = this.mapper.Map <Target>(product);
                target.ReferenceImages = new ReferenceImage[] { this.mapper.Map <ReferenceImage>(referenceImage) };

                return(target);
            }
            finally
            {
                await channel.ShutdownAsync();
            }
        }
        private async Task <Google.Cloud.Vision.V1.ReferenceImage> CreateReferenceImage(ProductSearchClient client, CreateReferenceImageOptions opts)
        {
            var request = new CreateReferenceImageRequest
            {
                // Get the full path of the product.
                ParentAsProductName = new ProductName(opts.ProjectID, opts.ComputeRegion, opts.ProductID),
                ReferenceImageId    = opts.ReferenceImageID,
                // Create a reference image.
                ReferenceImage = new Google.Cloud.Vision.V1.ReferenceImage
                {
                    Uri = opts.ReferenceImageURI
                }
            };

            var referenceImage = await client.CreateReferenceImageAsync(request);

            return(referenceImage);
        }