Repository: microsoft/terraform-provider-azuredevops

Issue:
Configure extensions during project deployment
---

Migrated from https://github.com/microsoft/terraform-provider-azuredevops/issues/197
Originally created by @gfmatthews on *Thu, 07 Nov 2019 18:35:02 GMT*

---
<!--- Please keep this note for the community --->

### Community Note

* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request
* Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
* If you are interested in working on this issue or have submitted a pull request, please leave a comment

<!--- Thank you for keeping this note for the community --->

### Description

We would like to be able to configure and/or install AzDo extensions through the Terraform provider.

### New or Affected Resource(s)

AzDo Extensions

### Potential Terraform Configuration

I leave the exact implementation of this idea to the project team.

```hcl
# Copy-paste your Terraform configurations here - for large Terraform configs,
# please use a service like Dropbox and share a link to the ZIP file. For
# security, you can also encrypt the files using our GPG public key.
```

### References


* #0000

Hints from issue comments:
@EliiseS: ---

Migrated from https://github.com/microsoft/terraform-provider-azuredevops/issues/197#issuecomment-624874590
Originally created by @nmiodice on *Wed, 06 May 2020 20:31:26 GMT*

---
The API to use will be this one:
https://docs.microsoft.com/en-us/rest/api/azure/devops/extensionmanagement/installed%20extensions/install%20extension%20by%20name?view=azure-devops-rest-5.1

A possible configuration may look like:
```
resource "azuredevops_extension" "e" {
    publisher_name := string
    extension_name := string
    version        := string
}
```

Solution patch:
diff --git a/azuredevops/internal/client/client.go b/azuredevops/internal/client/client.go
index d3f4f0c3..13ef9cc0 100644
--- a/azuredevops/internal/client/client.go
+++ b/azuredevops/internal/client/client.go
@@ -12,6 +12,7 @@ import (
 	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/core"
 	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/dashboard"
 	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/elastic"
+	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/extensionmanagement"
 	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/featuremanagement"
 	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/feed"
 	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/git"
@@ -61,6 +62,7 @@ type AggregatedClient struct {
 	PipelinesChecksClientExtras   pipelineschecksextras.Client
 	PolicyClient                  policy.Client
 	ElasticClient                 elastic.Client
+	ExtensionManagementClient     extensionmanagement.Client
 	ReleaseClient                 release.Client
 	ServiceEndpointClient         serviceendpoint.Client
 	TaskAgentClient               taskagent.Client
@@ -108,6 +110,12 @@ func GetAzdoClient(azdoTokenProvider func() (string, error), organizationURL str
 
 	elasticClient := elastic.NewClient(ctx, connection)
 
+	extensionManagementClient, err := extensionmanagement.NewClient(ctx, connection)
+	if err != nil {
+		log.Printf("getAzdoClient(): extensionmanagement.NewClient failed.")
+		return nil, err
+	}
+
 	dashboardClient, err := dashboard.NewClient(ctx, connection)
 	if err != nil {
 		log.Printf("getAzdoClient(): dashboardClient.NewClient failed.")
@@ -220,6 +228,7 @@ func GetAzdoClient(azdoTokenProvider func() (string, error), organizationURL str
 		DashboardClient:               dashboardClient,
 		DashboardClientExtra:          dashboardClientExtra,
 		ElasticClient:                 elasticClient,
+		ExtensionManagementClient:     extensionManagementClient,
 		GitReposClient:                gitReposClient,
 		GraphClient:                   graphClient,
 		OperationsClient:              operationsClient,
diff --git a/azuredevops/internal/service/extension/resource_extension.go b/azuredevops/internal/service/extension/resource_extension.go
new file mode 100644
index 00000000..3404b410
--- /dev/null
+++ b/azuredevops/internal/service/extension/resource_extension.go
@@ -0,0 +1,187 @@
+package extension
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"time"
+
+	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
+	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/extensionmanagement"
+	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/client"
+	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils"
+	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/converter"
+	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/utils/suppress"
+)
+
+func ResourceExtension() *schema.Resource {
+	return &schema.Resource{
+		CreateContext: resourceExtensionCreate,
+		ReadContext:   resourceExtensionRead,
+		UpdateContext: resourceExtensionUpdate,
+		DeleteContext: resourceExtensionDelete,
+		Timeouts: &schema.ResourceTimeout{
+			Create: schema.DefaultTimeout(5 * time.Minute),
+			Read:   schema.DefaultTimeout(2 * time.Minute),
+			Update: schema.DefaultTimeout(5 * time.Minute),
+			Delete: schema.DefaultTimeout(5 * time.Minute),
+		},
+		Importer: &schema.ResourceImporter{
+			StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
+				id := strings.Split(d.Id(), "/")
+				if len(id) != 2 {
+					return nil, fmt.Errorf("unexpected ID format, expected <publisherName>/<extensionName>")
+				}
+				d.Set("publisher_id", id[0])
+				d.Set("extension_id", id[1])
+				return []*schema.ResourceData{d}, nil
+			},
+		},
+		Schema: map[string]*schema.Schema{
+			"extension_id": {
+				Type:         schema.TypeString,
+				Required:     true,
+				ForceNew:     true,
+				ValidateFunc: validation.StringIsNotWhiteSpace,
+			},
+			"publisher_id": {
+				Type:             schema.TypeString,
+				Required:         true,
+				ForceNew:         true,
+				DiffSuppressFunc: suppress.CaseDifference,
+				ValidateFunc:     validation.StringIsNotWhiteSpace,
+			},
+			"disabled": {
+				Type:     schema.TypeBool,
+				Optional: true,
+				Computed: true,
+			},
+			"version": {
+				Type:     schema.TypeString,
+				Optional: true,
+				Computed: true,
+			},
+			"extension_name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"publisher_name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"scope": {
+				Type:     schema.TypeList,
+				Computed: true,
+				Elem:     &schema.Schema{Type: schema.TypeString},
+			},
+		},
+	}
+}
+
+func resourceExtensionCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+	clients := m.(*client.AggregatedClient)
+
+	publisherId := d.Get("publisher_id").(string)
+	extensionId := d.Get("extension_id").(string)
+	extension, err := clients.ExtensionManagementClient.InstallExtensionByName(ctx,
+		extensionmanagement.InstallExtensionByNameArgs{
+			PublisherName: &publisherId,
+			ExtensionName: &extensionId,
+			Version:       converter.String(d.Get("version").(string)),
+		})
+
+	if err != nil {
+		return diag.Errorf(" Installing extension for Publisher: %s, Name: %s. Error: %v", publisherId, extensionId, err)
+	}
+
+	d.SetId(fmt.Sprintf("%s/%s", *extension.PublisherId, *extension.ExtensionId))
+	return resourceExtensionRead(ctx, d, m)
+}
+
+func resourceExtensionRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+	clients := m.(*client.AggregatedClient)
+
+	publisherId := d.Get("publisher_id").(string)
+	extensionId := d.Get("extension_id").(string)
+	extension, err := clients.ExtensionManagementClient.GetInstalledExtensionByName(ctx, extensionmanagement.GetInstalledExtensionByNameArgs{
+		PublisherName: &publisherId,
+		ExtensionName: &extensionId,
+	})
+
+	if err != nil {
+		if utils.ResponseWasNotFound(err) {
+			d.SetId("")
+			return nil
+		}
+		return diag.Errorf(" Get extension for Publisher: %s, name: %s. Error: %v", publisherId, extensionId, err)
+	}
+
+	if extension != nil {
+		d.Set("extension_id", extension.ExtensionId)
+		d.Set("publisher_id", extension.PublisherId)
+		d.Set("version", extension.Version)
+		d.Set("scope", extension.Scopes)
+		d.Set("publisher_name", extension.PublisherName)
+		d.Set("extension_name", extension.ExtensionName)
+		if extension.InstallState != nil {
+			if *extension.InstallState.Flags == extensionmanagement.ExtensionStateFlagsValues.None {
+				d.Set("disabled", false)
+			} else if *extension.InstallState.Flags == extensionmanagement.ExtensionStateFlagsValues.Disabled {
+				d.Set("disabled", true)
+			} else {
+				return diag.Errorf(" Extension is in an unexpected state. Status: %s", *extension.InstallState.Flags)
+			}
+		}
+	}
+	return nil
+}
+
+func resourceExtensionUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+	clients := m.(*client.AggregatedClient)
+
+	disableRaw := d.GetRawConfig().AsValueMap()["disabled"]
+	if !disableRaw.IsNull() {
+		publisherId := d.Get("publisher_id").(string)
+		extensionId := d.Get("extension_id").(string)
+		updateArgs := extensionmanagement.UpdateInstalledExtensionArgs{
+			Extension: &extensionmanagement.InstalledExtension{
+				PublisherId: &publisherId,
+				ExtensionId: &extensionId,
+				Version:     converter.String(d.Get("version").(string)),
+				InstallState: &extensionmanagement.InstalledExtensionState{
+					Flags: converter.ToPtr(extensionmanagement.ExtensionStateFlagsValues.None),
+				},
+			},
+		}
+
+		if !disableRaw.False() {
+			updateArgs.Extension.InstallState = &extensionmanagement.InstalledExtensionState{
+				Flags: converter.ToPtr(extensionmanagement.ExtensionStateFlagsValues.Disabled),
+			}
+		}
+
+		_, err := clients.ExtensionManagementClient.UpdateInstalledExtension(ctx, updateArgs)
+		if err != nil {
+			return diag.Errorf(" Update extension for Publisher: %s, Name: %s. Error: %v", publisherId, extensionId, err)
+		}
+	}
+	return resourceExtensionRead(ctx, d, m)
+}
+
+func resourceExtensionDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
+	clients := m.(*client.AggregatedClient)
+	publisher := d.Get("publisher_id").(string)
+	name := d.Get("extension_id").(string)
+
+	err := clients.ExtensionManagementClient.UninstallExtensionByName(ctx, extensionmanagement.UninstallExtensionByNameArgs{
+		PublisherName: &publisher,
+		ExtensionName: &name,
+	})
+
+	if err != nil {
+		return diag.Errorf(" Uninstalling extension for Publisher: %s, name: %s. Error: %v", publisher, name, err)
+	}
+	return nil
+}
diff --git a/azuredevops/provider.go b/azuredevops/provider.go
index 51ccdf74..464338ee 100644
--- a/azuredevops/provider.go
+++ b/azuredevops/provider.go
@@ -16,6 +16,7 @@ import (
 	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/service/build"
 	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/service/core"
 	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/service/dashboard"
+	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/service/extension"
 	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/service/feed"
 	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/service/git"
 	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/service/graph"
@@ -61,6 +62,7 @@ func Provider() *schema.Provider {
 			"azuredevops_elastic_pool":                                taskagent.ResourceAgentPoolVMSS(),
 			"azuredevops_environment":                                 taskagent.ResourceEnvironment(),
 			"azuredevops_environment_resource_kubernetes":             taskagent.ResourceEnvironmentKubernetes(),
+			"azuredevops_extension":                                   extension.ResourceExtension(),
 			"azuredevops_feed":                                        feed.ResourceFeed(),
 			"azuredevops_feed_permission":                             feed.ResourceFeedPermission(),
 			"azuredevops_feed_retention_policy":                       feed.ResourceFeedRetentionPolicy(),
diff --git a/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/extensionmanagement/client.go b/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/extensionmanagement/client.go
new file mode 100644
index 00000000..6b753c34
--- /dev/null
+++ b/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/extensionmanagement/client.go
@@ -0,0 +1,229 @@
+// --------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+// --------------------------------------------------------------------------------------------
+// Generated file, DO NOT EDIT
+// Changes may cause incorrect behavior and will be lost if the code is regenerated.
+// --------------------------------------------------------------------------------------------
+
+package extensionmanagement
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"github.com/google/uuid"
+	"github.com/microsoft/azure-devops-go-api/azuredevops/v7"
+	"net/http"
+	"net/url"
+	"strconv"
+	"strings"
+)
+
+var ResourceAreaId, _ = uuid.Parse("6c2b0933-3600-42ae-bf8b-93d4f7e83594")
+
+type Client interface {
+	// [Preview API] Get an installed extension by its publisher and extension name.
+	GetInstalledExtensionByName(context.Context, GetInstalledExtensionByNameArgs) (*InstalledExtension, error)
+	// [Preview API] List the installed extensions in the account / project collection.
+	GetInstalledExtensions(context.Context, GetInstalledExtensionsArgs) (*[]InstalledExtension, error)
+	// [Preview API] Install the specified extension into the account / project collection.
+	InstallExtensionByName(context.Context, InstallExtensionByNameArgs) (*InstalledExtension, error)
+	// [Preview API] Uninstall the specified extension from the account / project collection.
+	UninstallExtensionByName(context.Context, UninstallExtensionByNameArgs) error
+	// [Preview API] Update an installed extension. Typically this API is used to enable or disable an extension.
+	UpdateInstalledExtension(context.Context, UpdateInstalledExtensionArgs) (*InstalledExtension, error)
+}
+
+type ClientImpl struct {
+	Client azuredevops.Client
+}
+
+func NewClient(ctx context.Context, connection *azuredevops.Connection) (Client, error) {
+	client, err := connection.GetClientByResourceAreaId(ctx, ResourceAreaId)
+	if err != nil {
+		return nil, err
+	}
+	return &ClientImpl{
+		Client: *client,
+	}, nil
+}
+
+// [Preview API] Get an installed extension by its publisher and extension name.
+func (client *ClientImpl) GetInstalledExtensionByName(ctx context.Context, args GetInstalledExtensionByNameArgs) (*InstalledExtension, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	queryParams := url.Values{}
+	if args.AssetTypes != nil {
+		listAsString := strings.Join((*args.AssetTypes)[:], ":")
+		queryParams.Add("assetTypes", listAsString)
+	}
+	locationId, _ := uuid.Parse("fb0da285-f23e-4b56-8b53-3ef5f9f6de66")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue InstalledExtension
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetInstalledExtensionByName function
+type GetInstalledExtensionByNameArgs struct {
+	// (required) Name of the publisher. Example: "fabrikam".
+	PublisherName *string
+	// (required) Name of the extension. Example: "ops-tools".
+	ExtensionName *string
+	// (optional) Determines which files are returned in the files array.  Provide the wildcard '*' to return all files, or a colon separated list to retrieve files with specific asset types.
+	AssetTypes *[]string
+}
+
+// [Preview API] List the installed extensions in the account / project collection.
+func (client *ClientImpl) GetInstalledExtensions(ctx context.Context, args GetInstalledExtensionsArgs) (*[]InstalledExtension, error) {
+	queryParams := url.Values{}
+	if args.IncludeDisabledExtensions != nil {
+		queryParams.Add("includeDisabledExtensions", strconv.FormatBool(*args.IncludeDisabledExtensions))
+	}
+	if args.IncludeErrors != nil {
+		queryParams.Add("includeErrors", strconv.FormatBool(*args.IncludeErrors))
+	}
+	if args.AssetTypes != nil {
+		listAsString := strings.Join((*args.AssetTypes)[:], ":")
+		queryParams.Add("assetTypes", listAsString)
+	}
+	if args.IncludeInstallationIssues != nil {
+		queryParams.Add("includeInstallationIssues", strconv.FormatBool(*args.IncludeInstallationIssues))
+	}
+	locationId, _ := uuid.Parse("275424d0-c844-4fe2-bda6-04933a1357d8")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", nil, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue []InstalledExtension
+	err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetInstalledExtensions function
+type GetInstalledExtensionsArgs struct {
+	// (optional) If true (the default), include disabled extensions in the results.
+	IncludeDisabledExtensions *bool
+	// (optional) If true, include installed extensions with errors.
+	IncludeErrors *bool
+	// (optional) Determines which files are returned in the files array.  Provide the wildcard '*' to return all files, or a colon separated list to retrieve files with specific asset types.
+	AssetTypes *[]string
+	// (optional)
+	IncludeInstallationIssues *bool
+}
+
+// [Preview API] Install the specified extension into the account / project collection.
+func (client *ClientImpl) InstallExtensionByName(ctx context.Context, args InstallExtensionByNameArgs) (*InstalledExtension, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.Version != nil && *args.Version != "" {
+		routeValues["version"] = *args.Version
+	}
+
+	locationId, _ := uuid.Parse("fb0da285-f23e-4b56-8b53-3ef5f9f6de66")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue InstalledExtension
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the InstallExtensionByName function
+type InstallExtensionByNameArgs struct {
+	// (required) Name of the publisher. Example: "fabrikam".
+	PublisherName *string
+	// (required) Name of the extension. Example: "ops-tools".
+	ExtensionName *string
+	// (optional)
+	Version *string
+}
+
+// [Preview API] Uninstall the specified extension from the account / project collection.
+func (client *ClientImpl) UninstallExtensionByName(ctx context.Context, args UninstallExtensionByNameArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	queryParams := url.Values{}
+	if args.Reason != nil {
+		queryParams.Add("reason", *args.Reason)
+	}
+	if args.ReasonCode != nil {
+		queryParams.Add("reasonCode", *args.ReasonCode)
+	}
+	locationId, _ := uuid.Parse("fb0da285-f23e-4b56-8b53-3ef5f9f6de66")
+	_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the UninstallExtensionByName function
+type UninstallExtensionByNameArgs struct {
+	// (required) Name of the publisher. Example: "fabrikam".
+	PublisherName *string
+	// (required) Name of the extension. Example: "ops-tools".
+	ExtensionName *string
+	// (optional)
+	Reason *string
+	// (optional)
+	ReasonCode *string
+}
+
+// [Preview API] Update an installed extension. Typically this API is used to enable or disable an extension.
+func (client *ClientImpl) UpdateInstalledExtension(ctx context.Context, args UpdateInstalledExtensionArgs) (*InstalledExtension, error) {
+	if args.Extension == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Extension"}
+	}
+	body, marshalErr := json.Marshal(*args.Extension)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("275424d0-c844-4fe2-bda6-04933a1357d8")
+	resp, err := client.Client.Send(ctx, http.MethodPatch, locationId, "7.1-preview.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue InstalledExtension
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdateInstalledExtension function
+type UpdateInstalledExtensionArgs struct {
+	// (required)
+	Extension *InstalledExtension
+}
diff --git a/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/extensionmanagement/models.go b/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/extensionmanagement/models.go
new file mode 100644
index 00000000..0f3818eb
--- /dev/null
+++ b/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/extensionmanagement/models.go
@@ -0,0 +1,873 @@
+// --------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+// --------------------------------------------------------------------------------------------
+// Generated file, DO NOT EDIT
+// Changes may cause incorrect behavior and will be lost if the code is regenerated.
+// --------------------------------------------------------------------------------------------
+
+package extensionmanagement
+
+import (
+	"github.com/google/uuid"
+	"github.com/microsoft/azure-devops-go-api/azuredevops/v7"
+	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/gallery"
+	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/webapi"
+)
+
+// How the acquisition is assigned
+type AcquisitionAssignmentType string
+
+type acquisitionAssignmentTypeValuesType struct {
+	None AcquisitionAssignmentType
+	Me   AcquisitionAssignmentType
+	All  AcquisitionAssignmentType
+}
+
+var AcquisitionAssignmentTypeValues = acquisitionAssignmentTypeValuesType{
+	None: "none",
+	// Just assign for me
+	Me: "me",
+	// Assign for all users in the account
+	All: "all",
+}
+
+type AcquisitionOperation struct {
+	// State of the AcquisitionOperation for the current user
+	OperationState *AcquisitionOperationState `json:"operationState,omitempty"`
+	// AcquisitionOperationType: install, request, buy, etc...
+	OperationType *AcquisitionOperationType `json:"operationType,omitempty"`
+	// Optional reason to justify current state. Typically used with Disallow state.
+	Reason *string `json:"reason,omitempty"`
+	// List of reasons indicating why the operation is not allowed.
+	Reasons *[]AcquisitionOperationDisallowReason `json:"reasons,omitempty"`
+}
+
+type AcquisitionOperationDisallowReason struct {
+	// User-friendly message clarifying the reason for disallowance
+	Message *string `json:"message,omitempty"`
+	// Type of reason for disallowance - AlreadyInstalled, UnresolvedDemand, etc.
+	Type *string `json:"type,omitempty"`
+}
+
+type AcquisitionOperationState string
+
+type acquisitionOperationStateValuesType struct {
+	Disallow  AcquisitionOperationState
+	Allow     AcquisitionOperationState
+	Completed AcquisitionOperationState
+}
+
+var AcquisitionOperationStateValues = acquisitionOperationStateValuesType{
+	// Not allowed to use this AcquisitionOperation
+	Disallow: "disallow",
+	// Allowed to use this AcquisitionOperation
+	Allow: "allow",
+	// Operation has already been completed and is no longer available
+	Completed: "completed",
+}
+
+// Set of different types of operations that can be requested.
+type AcquisitionOperationType string
+
+type acquisitionOperationTypeValuesType struct {
+	Get             AcquisitionOperationType
+	Install         AcquisitionOperationType
+	Buy             AcquisitionOperationType
+	Try             AcquisitionOperationType
+	Request         AcquisitionOperationType
+	None            AcquisitionOperationType
+	PurchaseRequest AcquisitionOperationType
+}
+
+var AcquisitionOperationTypeValues = acquisitionOperationTypeValuesType{
+	// Not yet used
+	Get: "get",
+	// Install this extension into the host provided
+	Install: "install",
+	// Buy licenses for this extension and install into the host provided
+	Buy: "buy",
+	// Try this extension
+	Try: "try",
+	// Request this extension for installation
+	Request: "request",
+	// No action found
+	None: "none",
+	// Request admins for purchasing extension
+	PurchaseRequest: "purchaseRequest",
+}
+
+// Market item acquisition options (install, buy, etc) for an installation target.
+type AcquisitionOptions struct {
+	// Default Operation for the ItemId in this target
+	DefaultOperation *AcquisitionOperation `json:"defaultOperation,omitempty"`
+	// The item id that this options refer to
+	ItemId *string `json:"itemId,omitempty"`
+	// Operations allowed for the ItemId in this target
+	Operations *[]AcquisitionOperation `json:"operations,omitempty"`
+	// Additional properties which can be added to the request.
+	Properties interface{} `json:"properties,omitempty"`
+	// The target that this options refer to
+	Target *string `json:"target,omitempty"`
+}
+
+// Representation of a ContributionNode that can be used for serialized to clients.
+type ClientContribution struct {
+	// Description of the contribution/type
+	Description *string `json:"description,omitempty"`
+	// Fully qualified identifier of the contribution/type
+	Id *string `json:"id,omitempty"`
+	// Includes is a set of contributions that should have this contribution included in their targets list.
+	Includes *[]string `json:"includes,omitempty"`
+	// Properties/attributes of this contribution
+	Properties interface{} `json:"properties,omitempty"`
+	// The ids of the contribution(s) that this contribution targets. (parent contributions)
+	Targets *[]string `json:"targets,omitempty"`
+	// Id of the Contribution Type
+	Type *string `json:"type,omitempty"`
+}
+
+// Representation of a ContributionNode that can be used for serialized to clients.
+type ClientContributionNode struct {
+	// Contribution associated with this node.
+	Contribution *ClientContribution `json:"contribution,omitempty"`
+	// List of ids for contributions which are children to the current contribution.
+	Children *[]string `json:"children,omitempty"`
+	// List of ids for contributions which are parents to the current contribution.
+	Parents *[]string `json:"parents,omitempty"`
+}
+
+type ClientContributionProviderDetails struct {
+	// Friendly name for the provider.
+	DisplayName *string `json:"displayName,omitempty"`
+	// Unique identifier for this provider. The provider name can be used to cache the contribution data and refer back to it when looking for changes
+	Name *string `json:"name,omitempty"`
+	// Properties associated with the provider
+	Properties *map[string]string `json:"properties,omitempty"`
+	// Version of contributions associated with this contribution provider.
+	Version *string `json:"version,omitempty"`
+}
+
+// A client data provider are the details needed to make the data provider request from the client.
+type ClientDataProviderQuery struct {
+	// Contextual information to pass to the data providers
+	Context *DataProviderContext `json:"context,omitempty"`
+	// The contribution ids of the data providers to resolve
+	ContributionIds *[]string `json:"contributionIds,omitempty"`
+	// The Id of the service instance type that should be communicated with in order to resolve the data providers from the client given the query values.
+	QueryServiceInstanceType *uuid.UUID `json:"queryServiceInstanceType,omitempty"`
+}
+
+// An individual contribution made by an extension
+type Contribution struct {
+	// Description of the contribution/type
+	Description *string `json:"description,omitempty"`
+	// Fully qualified identifier of the contribution/type
+	Id *string `json:"id,omitempty"`
+	// VisibleTo can be used to restrict whom can reference a given contribution/type. This value should be a list of publishers or extensions access is restricted too.  Examples: "ms" - Means only the "ms" publisher can reference this. "ms.vss-web" - Means only the "vss-web" extension from the "ms" publisher can reference this.
+	VisibleTo *[]string `json:"visibleTo,omitempty"`
+	// List of constraints (filters) that should be applied to the availability of this contribution
+	Constraints *[]ContributionConstraint `json:"constraints,omitempty"`
+	// Includes is a set of contributions that should have this contribution included in their targets list.
+	Includes *[]string `json:"includes,omitempty"`
+	// Properties/attributes of this contribution
+	Properties interface{} `json:"properties,omitempty"`
+	// List of demanded claims in order for the user to see this contribution (like anonymous, public, member...).
+	RestrictedTo *[]string `json:"restrictedTo,omitempty"`
+	// The ids of the contribution(s) that this contribution targets. (parent contributions)
+	Targets *[]string `json:"targets,omitempty"`
+	// Id of the Contribution Type
+	Type *string `json:"type,omitempty"`
+}
+
+// Base class shared by contributions and contribution types
+type ContributionBase struct {
+	// Description of the contribution/type
+	Description *string `json:"description,omitempty"`
+	// Fully qualified identifier of the contribution/type
+	Id *string `json:"id,omitempty"`
+	// VisibleTo can be used to restrict whom can reference a given contribution/type. This value should be a list of publishers or extensions access is restricted too.  Examples: "ms" - Means only the "ms" publisher can reference this. "ms.vss-web" - Means only the "vss-web" extension from the "ms" publisher can reference this.
+	VisibleTo *[]string `json:"visibleTo,omitempty"`
+}
+
+// Specifies a constraint that can be used to dynamically include/exclude a given contribution
+type ContributionConstraint struct {
+	// An optional property that can be specified to group constraints together. All constraints within a group are AND'd together (all must be evaluate to True in order for the contribution to be included). Different groups of constraints are OR'd (only one group needs to evaluate to True for the contribution to be included).
+	Group *int `json:"group,omitempty"`
+	// Fully qualified identifier of a shared constraint
+	Id *string `json:"id,omitempty"`
+	// If true, negate the result of the filter (include the contribution if the applied filter returns false instead of true)
+	Inverse *bool `json:"inverse,omitempty"`
+	// Name of the IContributionFilter plugin
+	Name *string `json:"name,omitempty"`
+	// Properties that are fed to the contribution filter class
+	Properties interface{} `json:"properties,omitempty"`
+	// Constraints can be optionally be applied to one or more of the relationships defined in the contribution. If no relationships are defined then all relationships are associated with the constraint. This means the default behaviour will eliminate the contribution from the tree completely if the constraint is applied.
+	Relationships *[]string `json:"relationships,omitempty"`
+}
+
+// Represents different ways of including contributions based on licensing
+type ContributionLicensingBehaviorType string
+
+type contributionLicensingBehaviorTypeValuesType struct {
+	OnlyIfLicensed   ContributionLicensingBehaviorType
+	OnlyIfUnlicensed ContributionLicensingBehaviorType
+	AlwaysInclude    ContributionLicensingBehaviorType
+}
+
+var ContributionLicensingBehaviorTypeValues = contributionLicensingBehaviorTypeValuesType{
+	// Default value - only include the contribution if the user is licensed for the extension
+	OnlyIfLicensed: "onlyIfLicensed",
+	// Only include the contribution if the user is NOT licensed for the extension
+	OnlyIfUnlicensed: "onlyIfUnlicensed",
+	// Always include the contribution regardless of whether or not the user is licensed for the extension
+	AlwaysInclude: "alwaysInclude",
+}
+
+// A query that can be issued for contribution nodes
+type ContributionNodeQuery struct {
+	// The contribution ids of the nodes to find.
+	ContributionIds *[]string `json:"contributionIds,omitempty"`
+	// Contextual information that can be leveraged by contribution constraints
+	DataProviderContext *DataProviderContext `json:"dataProviderContext,omitempty"`
+	// Indicator if contribution provider details should be included in the result.
+	IncludeProviderDetails *bool `json:"includeProviderDetails,omitempty"`
+	// Query options tpo be used when fetching ContributionNodes
+	QueryOptions *ContributionQueryOptions `json:"queryOptions,omitempty"`
+}
+
+// Result of a contribution node query.  Wraps the resulting contribution nodes and provider details.
+type ContributionNodeQueryResult struct {
+	// Map of contribution ids to corresponding node.
+	Nodes *map[string]ClientContributionNode `json:"nodes,omitempty"`
+	// Map of provider ids to the corresponding provider details object.
+	ProviderDetails *map[string]ClientContributionProviderDetails `json:"providerDetails,omitempty"`
+}
+
+// Description about a property of a contribution type
+type ContributionPropertyDescription struct {
+	// Description of the property
+	Description *string `json:"description,omitempty"`
+	// Name of the property
+	Name *string `json:"name,omitempty"`
+	// True if this property is required
+	Required *bool `json:"required,omitempty"`
+	// The type of value used for this property
+	Type *ContributionPropertyType `json:"type,omitempty"`
+}
+
+// [Flags] The type of value used for a property
+type ContributionPropertyType string
+
+type contributionPropertyTypeValuesType struct {
+	Unknown    ContributionPropertyType
+	String     ContributionPropertyType
+	Uri        ContributionPropertyType
+	Guid       ContributionPropertyType
+	Boolean    ContributionPropertyType
+	Integer    ContributionPropertyType
+	Double     ContributionPropertyType
+	DateTime   ContributionPropertyType
+	Dictionary ContributionPropertyType
+	Array      ContributionPropertyType
+	Object     ContributionPropertyType
+}
+
+var ContributionPropertyTypeValues = contributionPropertyTypeValuesType{
+	// Contribution type is unknown (value may be anything)
+	Unknown: "unknown",
+	// Value is a string
+	String: "string",
+	// Value is a Uri
+	Uri: "uri",
+	// Value is a GUID
+	Guid: "guid",
+	// Value is True or False
+	Boolean: "boolean",
+	// Value is an integer
+	Integer: "integer",
+	// Value is a double
+	Double: "double",
+	// Value is a DateTime object
+	DateTime: "dateTime",
+	// Value is a generic Dictionary/JObject/property bag
+	Dictionary: "dictionary",
+	// Value is an array
+	Array: "array",
+	// Value is an arbitrary/custom object
+	Object: "object",
+}
+
+type ContributionProviderDetails struct {
+	// Friendly name for the provider.
+	DisplayName *string `json:"displayName,omitempty"`
+	// Unique identifier for this provider. The provider name can be used to cache the contribution data and refer back to it when looking for changes
+	Name *string `json:"name,omitempty"`
+	// Properties associated with the provider
+	Properties *map[string]string `json:"properties,omitempty"`
+	// Version of contributions associated with this contribution provider.
+	Version *string `json:"version,omitempty"`
+}
+
+// [Flags] Options that control the contributions to include in a query
+type ContributionQueryOptions string
+
+type contributionQueryOptionsValuesType struct {
+	None              ContributionQueryOptions
+	IncludeSelf       ContributionQueryOptions
+	IncludeChildren   ContributionQueryOptions
+	IncludeSubTree    ContributionQueryOptions
+	IncludeAll        ContributionQueryOptions
+	IgnoreConstraints ContributionQueryOptions
+}
+
+var ContributionQueryOptionsValues = contributionQueryOptionsValuesType{
+	None: "none",
+	// Include the direct contributions that have the ids queried.
+	IncludeSelf: "includeSelf",
+	// Include the contributions that directly target the contributions queried.
+	IncludeChildren: "includeChildren",
+	// Include the contributions from the entire sub-tree targeting the contributions queried.
+	IncludeSubTree: "includeSubTree",
+	// Include the contribution being queried as well as all contributions that target them recursively.
+	IncludeAll: "includeAll",
+	// Some callers may want the entire tree back without constraint evaluation being performed.
+	IgnoreConstraints: "ignoreConstraints",
+}
+
+// A contribution type, given by a json schema
+type ContributionType struct {
+	// Description of the contribution/type
+	Description *string `json:"description,omitempty"`
+	// Fully qualified identifier of the contribution/type
+	Id *string `json:"id,omitempty"`
+	// VisibleTo can be used to restrict whom can reference a given contribution/type. This value should be a list of publishers or extensions access is restricted too.  Examples: "ms" - Means only the "ms" publisher can reference this. "ms.vss-web" - Means only the "vss-web" extension from the "ms" publisher can reference this.
+	VisibleTo *[]string `json:"visibleTo,omitempty"`
+	// Controls whether or not contributions of this type have the type indexed for queries. This allows clients to find all extensions that have a contribution of this type.  NOTE: Only TrustedPartners are allowed to specify indexed contribution types.
+	Indexed *bool `json:"indexed,omitempty"`
+	// Friendly name of the contribution/type
+	Name *string `json:"name,omitempty"`
+	// Describes the allowed properties for this contribution type
+	Properties *map[string]ContributionPropertyDescription `json:"properties,omitempty"`
+}
+
+// Contextual information that data providers can examine when populating their data
+type DataProviderContext struct {
+	// Generic property bag that contains context-specific properties that data providers can use when populating their data dictionary
+	Properties *map[string]interface{} `json:"properties,omitempty"`
+}
+
+type DataProviderExceptionDetails struct {
+	// The type of the exception that was thrown.
+	ExceptionType *string `json:"exceptionType,omitempty"`
+	// Message that is associated with the exception.
+	Message *string `json:"message,omitempty"`
+	// The StackTrace from the exception turned into a string.
+	StackTrace *string `json:"stackTrace,omitempty"`
+}
+
+// A query that can be issued for data provider data
+type DataProviderQuery struct {
+	// Contextual information to pass to the data providers
+	Context *DataProviderContext `json:"context,omitempty"`
+	// The contribution ids of the data providers to resolve
+	ContributionIds *[]string `json:"contributionIds,omitempty"`
+}
+
+// Result structure from calls to GetDataProviderData
+type DataProviderResult struct {
+	// This is the set of data providers that were requested, but either they were defined as client providers, or as remote providers that failed and may be retried by the client.
+	ClientProviders *map[string]ClientDataProviderQuery `json:"clientProviders,omitempty"`
+	// Property bag of data keyed off of the data provider contribution id
+	Data *map[string]interface{} `json:"data,omitempty"`
+	// Set of exceptions that occurred resolving the data providers.
+	Exceptions *map[string]DataProviderExceptionDetails `json:"exceptions,omitempty"`
+	// List of data providers resolved in the data-provider query
+	ResolvedProviders *[]ResolvedDataProvider `json:"resolvedProviders,omitempty"`
+	// Scope name applied to this data provider result.
+	ScopeName *string `json:"scopeName,omitempty"`
+	// Scope value applied to this data provider result.
+	ScopeValue *string `json:"scopeValue,omitempty"`
+	// Property bag of shared data that was contributed to by any of the individual data providers
+	SharedData *map[string]interface{} `json:"sharedData,omitempty"`
+}
+
+// Data bag that any data provider can contribute to. This shared dictionary is returned in the data provider result.
+type DataProviderSharedData struct {
+}
+
+// Contract for handling the extension acquisition process
+type ExtensionAcquisitionRequest struct {
+	// How the item is being assigned
+	AssignmentType *AcquisitionAssignmentType `json:"assignmentType,omitempty"`
+	// The id of the subscription used for purchase
+	BillingId *string `json:"billingId,omitempty"`
+	// The marketplace id (publisherName.extensionName) for the item
+	ItemId *string `json:"itemId,omitempty"`
+	// The type of operation, such as install, request, purchase
+	OperationType *AcquisitionOperationType `json:"operationType,omitempty"`
+	// Additional properties which can be added to the request.
+	Properties interface{} `json:"properties,omitempty"`
+	// How many licenses should be purchased
+	Quantity *int `json:"quantity,omitempty"`
+}
+
+// Audit log for an extension
+type ExtensionAuditLog struct {
+	// Collection of audit log entries
+	Entries *[]ExtensionAuditLogEntry `json:"entries,omitempty"`
+	// Extension that the change was made for
+	ExtensionName *string `json:"extensionName,omitempty"`
+	// Publisher that the extension is part of
+	PublisherName *string `json:"publisherName,omitempty"`
+}
+
+// An audit log entry for an extension
+type ExtensionAuditLogEntry struct {
+	// Change that was made to extension
+	AuditAction *string `json:"auditAction,omitempty"`
+	// Date at which the change was made
+	AuditDate *azuredevops.Time `json:"auditDate,omitempty"`
+	// Extra information about the change
+	Comment *string `json:"comment,omitempty"`
+	// Represents the user who made the change
+	UpdatedBy *webapi.IdentityRef `json:"updatedBy,omitempty"`
+}
+
+type ExtensionAuthorization struct {
+	Id     *uuid.UUID `json:"id,omitempty"`
+	Scopes *[]string  `json:"scopes,omitempty"`
+}
+
+// Represents a single collection for extension data documents
+type ExtensionDataCollection struct {
+	// The name of the collection
+	CollectionName *string `json:"collectionName,omitempty"`
+	// A list of documents belonging to the collection
+	Documents *[]interface{} `json:"documents,omitempty"`
+	// The type of the collection's scope, such as Default or User
+	ScopeType *string `json:"scopeType,omitempty"`
+	// The value of the collection's scope, such as Current or Me
+	ScopeValue *string `json:"scopeValue,omitempty"`
+}
+
+// Represents a query to receive a set of extension data collections
+type ExtensionDataCollectionQuery struct {
+	// A list of collections to query
+	Collections *[]ExtensionDataCollection `json:"collections,omitempty"`
+}
+
+type ExtensionEvent struct {
+	// The extension which has been updated
+	Extension *gallery.PublishedExtension `json:"extension,omitempty"`
+	// The current version of the extension that was updated
+	ExtensionVersion *string `json:"extensionVersion,omitempty"`
+	// Name of the collection for which the extension was requested
+	Host *ExtensionHost `json:"host,omitempty"`
+	// Gallery host url
+	Links *ExtensionEventUrls `json:"links,omitempty"`
+	// Represents the user who initiated the update
+	ModifiedBy *webapi.IdentityRef `json:"modifiedBy,omitempty"`
+	// The type of update that was made
+	UpdateType *ExtensionUpdateType `json:"updateType,omitempty"`
+}
+
+// Base class for an event callback for an extension
+type ExtensionEventCallback struct {
+	// The uri of the endpoint that is hit when an event occurs
+	Uri *string `json:"uri,omitempty"`
+}
+
+// Collection of event callbacks - endpoints called when particular extension events occur.
+type ExtensionEventCallbackCollection struct {
+	// Optional.  Defines an endpoint that gets called via a POST request to notify that an extension disable has occurred.
+	PostDisable *ExtensionEventCallback `json:"postDisable,omitempty"`
+	// Optional.  Defines an endpoint that gets called via a POST request to notify that an extension enable has occurred.
+	PostEnable *ExtensionEventCallback `json:"postEnable,omitempty"`
+	// Optional.  Defines an endpoint that gets called via a POST request to notify that an extension install has completed.
+	PostInstall *ExtensionEventCallback `json:"postInstall,omitempty"`
+	// Optional.  Defines an endpoint that gets called via a POST request to notify that an extension uninstall has occurred.
+	PostUninstall *ExtensionEventCallback `json:"postUninstall,omitempty"`
+	// Optional.  Defines an endpoint that gets called via a POST request to notify that an extension update has occurred.
+	PostUpdate *ExtensionEventCallback `json:"postUpdate,omitempty"`
+	// Optional.  Defines an endpoint that gets called via a POST request to notify that an extension install is about to occur.  Response indicates whether to proceed or abort.
+	PreInstall *ExtensionEventCallback `json:"preInstall,omitempty"`
+	// For multi-version extensions, defines an endpoint that gets called via an OPTIONS request to determine the particular version of the extension to be used
+	VersionCheck *ExtensionEventCallback `json:"versionCheck,omitempty"`
+}
+
+type ExtensionEventUrls struct {
+	// Url of the extension icon
+	ExtensionIcon *string `json:"extensionIcon,omitempty"`
+	// Link to view the extension details page
+	ExtensionPage *string `json:"extensionPage,omitempty"`
+	// Url of the extension management page
+	ManageExtensionsPage *string `json:"manageExtensionsPage,omitempty"`
+}
+
+// [Flags] Set of flags applied to extensions that are relevant to contribution consumers
+type ExtensionFlags string
+
+type extensionFlagsValuesType struct {
+	BuiltIn ExtensionFlags
+	Trusted ExtensionFlags
+}
+
+var ExtensionFlagsValues = extensionFlagsValuesType{
+	// A built-in extension is installed for all VSTS accounts by default
+	BuiltIn: "builtIn",
+	// The extension comes from a fully-trusted publisher
+	Trusted: "trusted",
+}
+
+type ExtensionHost struct {
+	Id   *uuid.UUID `json:"id,omitempty"`
+	Name *string    `json:"name,omitempty"`
+}
+
+// How an extension should handle including contributions based on licensing
+type ExtensionLicensing struct {
+	// A list of contributions which deviate from the default licensing behavior
+	Overrides *[]LicensingOverride `json:"overrides,omitempty"`
+}
+
+// Base class for extension properties which are shared by the extension manifest and the extension model
+type ExtensionManifest struct {
+	// Uri used as base for other relative uri's defined in extension
+	BaseUri *string `json:"baseUri,omitempty"`
+	// List of shared constraints defined by this extension
+	Constraints *[]ContributionConstraint `json:"constraints,omitempty"`
+	// List of contributions made by this extension
+	Contributions *[]Contribution `json:"contributions,omitempty"`
+	// List of contribution types defined by this extension
+	ContributionTypes *[]ContributionType `json:"contributionTypes,omitempty"`
+	// List of explicit demands required by this extension
+	Demands *[]string `json:"demands,omitempty"`
+	// Collection of endpoints that get called when particular extension events occur
+	EventCallbacks *ExtensionEventCallbackCollection `json:"eventCallbacks,omitempty"`
+	// Secondary location that can be used as base for other relative uri's defined in extension
+	FallbackBaseUri *string `json:"fallbackBaseUri,omitempty"`
+	// Language Culture Name set by the Gallery
+	Language *string `json:"language,omitempty"`
+	// How this extension behaves with respect to licensing
+	Licensing *ExtensionLicensing `json:"licensing,omitempty"`
+	// Version of the extension manifest format/content
+	ManifestVersion *float64 `json:"manifestVersion,omitempty"`
+	// Default user claims applied to all contributions (except the ones which have been specified restrictedTo explicitly) to control the visibility of a contribution.
+	RestrictedTo *[]string `json:"restrictedTo,omitempty"`
+	// List of all oauth scopes required by this extension
+	Scopes *[]string `json:"scopes,omitempty"`
+	// The ServiceInstanceType(Guid) of the VSTS service that must be available to an account in order for the extension to be installed
+	ServiceInstanceType *uuid.UUID `json:"serviceInstanceType,omitempty"`
+}
+
+// A request for an extension (to be installed or have a license assigned)
+type ExtensionRequest struct {
+	// Required message supplied if the request is rejected
+	RejectMessage *string `json:"rejectMessage,omitempty"`
+	// Date at which the request was made
+	RequestDate *azuredevops.Time `json:"requestDate,omitempty"`
+	// Represents the user who made the request
+	RequestedBy *webapi.IdentityRef `json:"requestedBy,omitempty"`
+	// Optional message supplied by the requester justifying the request
+	RequestMessage *string `json:"requestMessage,omitempty"`
+	// Represents the state of the request
+	RequestState *ExtensionRequestState `json:"requestState,omitempty"`
+	// Date at which the request was resolved
+	ResolveDate *azuredevops.Time `json:"resolveDate,omitempty"`
+	// Represents the user who resolved the request
+	ResolvedBy *webapi.IdentityRef `json:"resolvedBy,omitempty"`
+}
+
+type ExtensionRequestEvent struct {
+	// The extension which has been requested
+	Extension *gallery.PublishedExtension `json:"extension,omitempty"`
+	// Information about the host for which this extension is requested
+	Host *ExtensionHost `json:"host,omitempty"`
+	// Name of the collection for which the extension was requested
+	HostName *string `json:"hostName,omitempty"`
+	// Gallery host url
+	Links *ExtensionRequestUrls `json:"links,omitempty"`
+	// The extension request object
+	Request *ExtensionRequest `json:"request,omitempty"`
+	// The type of update that was made
+	UpdateType *ExtensionRequestUpdateType `json:"updateType,omitempty"`
+}
+
+type ExtensionRequestsEvent struct {
+	// The extension which has been requested
+	Extension *gallery.PublishedExtension `json:"extension,omitempty"`
+	// Information about the host for which this extension is requested
+	Host *ExtensionHost `json:"host,omitempty"`
+	// Gallery host url
+	Links *ExtensionRequestUrls `json:"links,omitempty"`
+	// The extension request object
+	Requests *[]ExtensionRequest `json:"requests,omitempty"`
+	// The type of update that was made
+	UpdateType *ExtensionRequestUpdateType `json:"updateType,omitempty"`
+}
+
+// Represents the state of an extension request
+type ExtensionRequestState string
+
+type extensionRequestStateValuesType struct {
+	Open     ExtensionRequestState
+	Accepted ExtensionRequestState
+	Rejected ExtensionRequestState
+}
+
+var ExtensionRequestStateValues = extensionRequestStateValuesType{
+	// The request has been opened, but not yet responded to
+	Open: "open",
+	// The request was accepted (extension installed or license assigned)
+	Accepted: "accepted",
+	// The request was rejected (extension not installed or license not assigned)
+	Rejected: "rejected",
+}
+
+type ExtensionRequestUpdateType string
+
+type extensionRequestUpdateTypeValuesType struct {
+	Created  ExtensionRequestUpdateType
+	Approved ExtensionRequestUpdateType
+	Rejected ExtensionRequestUpdateType
+	Deleted  ExtensionRequestUpdateType
+}
+
+var ExtensionRequestUpdateTypeValues = extensionRequestUpdateTypeValuesType{
+	Created:  "created",
+	Approved: "approved",
+	Rejected: "rejected",
+	Deleted:  "deleted",
+}
+
+type ExtensionRequestUrls struct {
+	// Url of the extension icon
+	ExtensionIcon *string `json:"extensionIcon,omitempty"`
+	// Link to view the extension details page
+	ExtensionPage *string `json:"extensionPage,omitempty"`
+	// Link to view the extension request
+	RequestPage *string `json:"requestPage,omitempty"`
+}
+
+// The state of an extension
+type ExtensionState struct {
+	// States of an installed extension
+	Flags *ExtensionStateFlags `json:"flags,omitempty"`
+	// List of installation issues
+	InstallationIssues *[]InstalledExtensionStateIssue `json:"installationIssues,omitempty"`
+	// The time at which this installation was last updated
+	LastUpdated   *azuredevops.Time `json:"lastUpdated,omitempty"`
+	ExtensionName *string           `json:"extensionName,omitempty"`
+	// The time at which the version was last checked
+	LastVersionCheck *azuredevops.Time `json:"lastVersionCheck,omitempty"`
+	PublisherName    *string           `json:"publisherName,omitempty"`
+	Version          *string           `json:"version,omitempty"`
+}
+
+// [Flags] States of an extension Note:  If you add value to this enum, you need to do 2 other things.  First add the back compat enum in value src\Vssf\Sdk\Server\Contributions\InstalledExtensionMessage.cs.  Second, you can not send the new value on the message bus.  You need to remove it from the message bus event prior to being sent.
+type ExtensionStateFlags string
+
+type extensionStateFlagsValuesType struct {
+	None                 ExtensionStateFlags
+	Disabled             ExtensionStateFlags
+	BuiltIn              ExtensionStateFlags
+	MultiVersion         ExtensionStateFlags
+	UnInstalled          ExtensionStateFlags
+	VersionCheckError    ExtensionStateFlags
+	Trusted              ExtensionStateFlags
+	Error                ExtensionStateFlags
+	NeedsReauthorization ExtensionStateFlags
+	AutoUpgradeError     ExtensionStateFlags
+	Warning              ExtensionStateFlags
+}
+
+var ExtensionStateFlagsValues = extensionStateFlagsValuesType{
+	// No flags set
+	None: "none",
+	// Extension is disabled
+	Disabled: "disabled",
+	// Extension is a built in
+	BuiltIn: "builtIn",
+	// Extension has multiple versions
+	MultiVersion: "multiVersion",
+	// Extension is not installed.  This is for builtin extensions only and can not otherwise be set.
+	UnInstalled: "unInstalled",
+	// Error performing version check
+	VersionCheckError: "versionCheckError",
+	// Trusted extensions are ones that are given special capabilities. These tend to come from Microsoft and can't be published by the general public.  Note: BuiltIn extensions are always trusted.
+	Trusted: "trusted",
+	// Extension is currently in an error state
+	Error: "error",
+	// Extension scopes have changed and the extension requires re-authorization
+	NeedsReauthorization: "needsReauthorization",
+	// Error performing auto-upgrade. For example, if the new version has demands not supported the extension cannot be auto-upgraded.
+	AutoUpgradeError: "autoUpgradeError",
+	// Extension is currently in a warning state, that can cause a degraded experience. The degraded experience can be caused for example by some installation issues detected such as implicit demands not supported.
+	Warning: "warning",
+}
+
+type ExtensionUpdateType string
+
+type extensionUpdateTypeValuesType struct {
+	Installed      ExtensionUpdateType
+	Uninstalled    ExtensionUpdateType
+	Enabled        ExtensionUpdateType
+	Disabled       ExtensionUpdateType
+	VersionUpdated ExtensionUpdateType
+	ActionRequired ExtensionUpdateType
+	ActionResolved ExtensionUpdateType
+}
+
+var ExtensionUpdateTypeValues = extensionUpdateTypeValuesType{
+	Installed:      "installed",
+	Uninstalled:    "uninstalled",
+	Enabled:        "enabled",
+	Disabled:       "disabled",
+	VersionUpdated: "versionUpdated",
+	ActionRequired: "actionRequired",
+	ActionResolved: "actionResolved",
+}
+
+type ExtensionUrls struct {
+	// Url of the extension icon
+	ExtensionIcon *string `json:"extensionIcon,omitempty"`
+	// Link to view the extension details page
+	ExtensionPage *string `json:"extensionPage,omitempty"`
+}
+
+// Represents a VSTS extension along with its installation state
+type InstalledExtension struct {
+	// Uri used as base for other relative uri's defined in extension
+	BaseUri *string `json:"baseUri,omitempty"`
+	// List of shared constraints defined by this extension
+	Constraints *[]ContributionConstraint `json:"constraints,omitempty"`
+	// List of contributions made by this extension
+	Contributions *[]Contribution `json:"contributions,omitempty"`
+	// List of contribution types defined by this extension
+	ContributionTypes *[]ContributionType `json:"contributionTypes,omitempty"`
+	// List of explicit demands required by this extension
+	Demands *[]string `json:"demands,omitempty"`
+	// Collection of endpoints that get called when particular extension events occur
+	EventCallbacks *ExtensionEventCallbackCollection `json:"eventCallbacks,omitempty"`
+	// Secondary location that can be used as base for other relative uri's defined in extension
+	FallbackBaseUri *string `json:"fallbackBaseUri,omitempty"`
+	// Language Culture Name set by the Gallery
+	Language *string `json:"language,omitempty"`
+	// How this extension behaves with respect to licensing
+	Licensing *ExtensionLicensing `json:"licensing,omitempty"`
+	// Version of the extension manifest format/content
+	ManifestVersion *float64 `json:"manifestVersion,omitempty"`
+	// Default user claims applied to all contributions (except the ones which have been specified restrictedTo explicitly) to control the visibility of a contribution.
+	RestrictedTo *[]string `json:"restrictedTo,omitempty"`
+	// List of all oauth scopes required by this extension
+	Scopes *[]string `json:"scopes,omitempty"`
+	// The ServiceInstanceType(Guid) of the VSTS service that must be available to an account in order for the extension to be installed
+	ServiceInstanceType *uuid.UUID `json:"serviceInstanceType,omitempty"`
+	// The friendly extension id for this extension - unique for a given publisher.
+	ExtensionId *string `json:"extensionId,omitempty"`
+	// The display name of the extension.
+	ExtensionName *string `json:"extensionName,omitempty"`
+	// This is the set of files available from the extension.
+	Files *[]gallery.ExtensionFile `json:"files,omitempty"`
+	// Extension flags relevant to contribution consumers
+	Flags *ExtensionFlags `json:"flags,omitempty"`
+	// Information about this particular installation of the extension
+	InstallState *InstalledExtensionState `json:"installState,omitempty"`
+	// This represents the date/time the extensions was last updated in the gallery. This doesnt mean this version was updated the value represents changes to any and all versions of the extension.
+	LastPublished *azuredevops.Time `json:"lastPublished,omitempty"`
+	// Unique id of the publisher of this extension
+	PublisherId *string `json:"publisherId,omitempty"`
+	// The display name of the publisher
+	PublisherName *string `json:"publisherName,omitempty"`
+	// Unique id for this extension (the same id is used for all versions of a single extension)
+	RegistrationId *uuid.UUID `json:"registrationId,omitempty"`
+	// Version of this extension
+	Version *string `json:"version,omitempty"`
+}
+
+type InstalledExtensionQuery struct {
+	AssetTypes *[]string                      `json:"assetTypes,omitempty"`
+	Monikers   *[]gallery.ExtensionIdentifier `json:"monikers,omitempty"`
+}
+
+// The state of an installed extension
+type InstalledExtensionState struct {
+	// States of an installed extension
+	Flags *ExtensionStateFlags `json:"flags,omitempty"`
+	// List of installation issues
+	InstallationIssues *[]InstalledExtensionStateIssue `json:"installationIssues,omitempty"`
+	// The time at which this installation was last updated
+	LastUpdated *azuredevops.Time `json:"lastUpdated,omitempty"`
+}
+
+// Represents an installation issue
+type InstalledExtensionStateIssue struct {
+	// The error message
+	Message *string `json:"message,omitempty"`
+	// Source of the installation issue, for example  "Demands"
+	Source *string `json:"source,omitempty"`
+	// Installation issue type (Warning, Error)
+	Type *InstalledExtensionStateIssueType `json:"type,omitempty"`
+}
+
+// Installation issue type (Warning, Error)
+type InstalledExtensionStateIssueType string
+
+type installedExtensionStateIssueTypeValuesType struct {
+	Warning InstalledExtensionStateIssueType
+	Error   InstalledExtensionStateIssueType
+}
+
+var InstalledExtensionStateIssueTypeValues = installedExtensionStateIssueTypeValuesType{
+	// Represents an installation warning, for example an implicit demand not supported
+	Warning: "warning",
+	// Represents an installation error, for example an explicit demand not supported
+	Error: "error",
+}
+
+// Maps a contribution to a licensing behavior
+type LicensingOverride struct {
+	// How the inclusion of this contribution should change based on licensing
+	Behavior *ContributionLicensingBehaviorType `json:"behavior,omitempty"`
+	// Fully qualified contribution id which we want to define licensing behavior for
+	Id *string `json:"id,omitempty"`
+}
+
+// A request for an extension (to be installed or have a license assigned)
+type RequestedExtension struct {
+	// The unique name of the extension
+	ExtensionName *string `json:"extensionName,omitempty"`
+	// A list of each request for the extension
+	ExtensionRequests *[]ExtensionRequest `json:"extensionRequests,omitempty"`
+	// DisplayName of the publisher that owns the extension being published.
+	PublisherDisplayName *string `json:"publisherDisplayName,omitempty"`
+	// Represents the Publisher of the requested extension
+	PublisherName *string `json:"publisherName,omitempty"`
+	// The total number of requests for an extension
+	RequestCount *int `json:"requestCount,omitempty"`
+}
+
+// Entry for a specific data provider's resulting data
+type ResolvedDataProvider struct {
+	// The total time the data provider took to resolve its data (in milliseconds)
+	Duration *float32 `json:"duration,omitempty"`
+	Error    *string  `json:"error,omitempty"`
+	Id       *string  `json:"id,omitempty"`
+}
+
+type Scope struct {
+	Description *string `json:"description,omitempty"`
+	Title       *string `json:"title,omitempty"`
+	Value       *string `json:"value,omitempty"`
+}
+
+// Information about the extension
+type SupportedExtension struct {
+	// Unique Identifier for this extension
+	Extension *string `json:"extension,omitempty"`
+	// Unique Identifier for this publisher
+	Publisher *string `json:"publisher,omitempty"`
+	// Supported version for this extension
+	Version *string `json:"version,omitempty"`
+}
diff --git a/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/gallery/client.go b/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/gallery/client.go
new file mode 100644
index 00000000..e87376e2
--- /dev/null
+++ b/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/gallery/client.go
@@ -0,0 +1,3358 @@
+// --------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+// --------------------------------------------------------------------------------------------
+// Generated file, DO NOT EDIT
+// Changes may cause incorrect behavior and will be lost if the code is regenerated.
+// --------------------------------------------------------------------------------------------
+
+package gallery
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"github.com/google/uuid"
+	"github.com/microsoft/azure-devops-go-api/azuredevops/v7"
+	"io"
+	"net/http"
+	"net/url"
+	"strconv"
+)
+
+var ResourceAreaId, _ = uuid.Parse("69d21c00-f135-441b-b5ce-3626378e0819")
+
+type Client interface {
+	// [Preview API]
+	AddAssetForEditExtensionDraft(context.Context, AddAssetForEditExtensionDraftArgs) (*ExtensionDraftAsset, error)
+	// [Preview API]
+	AddAssetForNewExtensionDraft(context.Context, AddAssetForNewExtensionDraftArgs) (*ExtensionDraftAsset, error)
+	// [Preview API]
+	AssociateAzurePublisher(context.Context, AssociateAzurePublisherArgs) (*AzurePublisher, error)
+	// [Preview API]
+	CreateCategory(context.Context, CreateCategoryArgs) (*ExtensionCategory, error)
+	// [Preview API]
+	CreateDraftForEditExtension(context.Context, CreateDraftForEditExtensionArgs) (*ExtensionDraft, error)
+	// [Preview API]
+	CreateDraftForNewExtension(context.Context, CreateDraftForNewExtensionArgs) (*ExtensionDraft, error)
+	// [Preview API]
+	CreateExtension(context.Context, CreateExtensionArgs) (*PublishedExtension, error)
+	// [Preview API]
+	CreateExtensionWithPublisher(context.Context, CreateExtensionWithPublisherArgs) (*PublishedExtension, error)
+	// [Preview API]
+	CreatePublisher(context.Context, CreatePublisherArgs) (*Publisher, error)
+	// [Preview API] Creates a new question for an extension.
+	CreateQuestion(context.Context, CreateQuestionArgs) (*Question, error)
+	// [Preview API] Creates a new response for a given question for an extension.
+	CreateResponse(context.Context, CreateResponseArgs) (*Response, error)
+	// [Preview API] Creates a new review for an extension
+	CreateReview(context.Context, CreateReviewArgs) (*Review, error)
+	// [Preview API]
+	CreateSupportRequest(context.Context, CreateSupportRequestArgs) error
+	// [Preview API]
+	DeleteExtension(context.Context, DeleteExtensionArgs) error
+	// [Preview API]
+	DeleteExtensionById(context.Context, DeleteExtensionByIdArgs) error
+	// [Preview API]
+	DeletePublisher(context.Context, DeletePublisherArgs) error
+	// [Preview API] Delete publisher asset like logo
+	DeletePublisherAsset(context.Context, DeletePublisherAssetArgs) error
+	// [Preview API] Deletes an existing question and all its associated responses for an extension. (soft delete)
+	DeleteQuestion(context.Context, DeleteQuestionArgs) error
+	// [Preview API] Deletes a response for an extension. (soft delete)
+	DeleteResponse(context.Context, DeleteResponseArgs) error
+	// [Preview API] Deletes a review
+	DeleteReview(context.Context, DeleteReviewArgs) error
+	// [Preview API]
+	ExtensionValidator(context.Context, ExtensionValidatorArgs) error
+	// [Preview API]
+	FetchDomainToken(context.Context, FetchDomainTokenArgs) (*string, error)
+	// [Preview API]
+	GenerateKey(context.Context, GenerateKeyArgs) error
+	// [Preview API]
+	GetAcquisitionOptions(context.Context, GetAcquisitionOptionsArgs) (*AcquisitionOptions, error)
+	// [Preview API]
+	GetAsset(context.Context, GetAssetArgs) (io.ReadCloser, error)
+	// [Preview API]
+	GetAssetAuthenticated(context.Context, GetAssetAuthenticatedArgs) (io.ReadCloser, error)
+	// [Preview API]
+	GetAssetByName(context.Context, GetAssetByNameArgs) (io.ReadCloser, error)
+	// [Preview API]
+	GetAssetFromEditExtensionDraft(context.Context, GetAssetFromEditExtensionDraftArgs) (io.ReadCloser, error)
+	// [Preview API]
+	GetAssetFromNewExtensionDraft(context.Context, GetAssetFromNewExtensionDraftArgs) (io.ReadCloser, error)
+	// [Preview API]
+	GetAssetWithToken(context.Context, GetAssetWithTokenArgs) (io.ReadCloser, error)
+	// [Preview API]
+	GetCategories(context.Context, GetCategoriesArgs) (*[]string, error)
+	// [Preview API]
+	GetCategoryDetails(context.Context, GetCategoryDetailsArgs) (*CategoriesResult, error)
+	// [Preview API]
+	GetCategoryTree(context.Context, GetCategoryTreeArgs) (*ProductCategory, error)
+	// [Preview API]
+	GetCertificate(context.Context, GetCertificateArgs) (io.ReadCloser, error)
+	// [Preview API]
+	GetContentVerificationLog(context.Context, GetContentVerificationLogArgs) (io.ReadCloser, error)
+	// [Preview API]
+	GetExtension(context.Context, GetExtensionArgs) (*PublishedExtension, error)
+	// [Preview API]
+	GetExtensionById(context.Context, GetExtensionByIdArgs) (*PublishedExtension, error)
+	// [Preview API]
+	GetExtensionDailyStats(context.Context, GetExtensionDailyStatsArgs) (*ExtensionDailyStats, error)
+	// [Preview API] This route/location id only supports HTTP POST anonymously, so that the page view daily stat can be incremented from Marketplace client. Trying to call GET on this route should result in an exception. Without this explicit implementation, calling GET on this public route invokes the above GET implementation GetExtensionDailyStats.
+	GetExtensionDailyStatsAnonymous(context.Context, GetExtensionDailyStatsAnonymousArgs) (*ExtensionDailyStats, error)
+	// [Preview API] Get install/uninstall events of an extension. If both count and afterDate parameters are specified, count takes precedence.
+	GetExtensionEvents(context.Context, GetExtensionEventsArgs) (*ExtensionEvents, error)
+	// [Preview API] Returns extension reports
+	GetExtensionReports(context.Context, GetExtensionReportsArgs) (interface{}, error)
+	// [Preview API] Get all setting entries for the given user/all-users scope
+	GetGalleryUserSettings(context.Context, GetGalleryUserSettingsArgs) (*map[string]interface{}, error)
+	// [Preview API] This endpoint gets hit when you download a VSTS extension from the Web UI
+	GetPackage(context.Context, GetPackageArgs) (io.ReadCloser, error)
+	// [Preview API]
+	GetPublisher(context.Context, GetPublisherArgs) (*Publisher, error)
+	// [Preview API] Get publisher asset like logo as a stream
+	GetPublisherAsset(context.Context, GetPublisherAssetArgs) (io.ReadCloser, error)
+	// [Preview API]
+	GetPublisherWithoutToken(context.Context, GetPublisherWithoutTokenArgs) (*Publisher, error)
+	// [Preview API] Returns a list of questions with their responses associated with an extension.
+	GetQuestions(context.Context, GetQuestionsArgs) (*QuestionsResult, error)
+	// [Preview API] Returns a list of reviews associated with an extension
+	GetReviews(context.Context, GetReviewsArgs) (*ReviewsResult, error)
+	// [Preview API] Returns a summary of the reviews
+	GetReviewsSummary(context.Context, GetReviewsSummaryArgs) (*ReviewSummary, error)
+	// [Preview API]
+	GetRootCategories(context.Context, GetRootCategoriesArgs) (*ProductCategoriesResult, error)
+	// [Preview API]
+	GetSigningKey(context.Context, GetSigningKeyArgs) (*string, error)
+	// [Preview API]
+	GetVerificationLog(context.Context, GetVerificationLogArgs) (io.ReadCloser, error)
+	// [Preview API] Increments a daily statistic associated with the extension
+	IncrementExtensionDailyStat(context.Context, IncrementExtensionDailyStatArgs) error
+	// [Preview API]
+	PerformEditExtensionDraftOperation(context.Context, PerformEditExtensionDraftOperationArgs) (*ExtensionDraft, error)
+	// [Preview API]
+	PerformNewExtensionDraftOperation(context.Context, PerformNewExtensionDraftOperationArgs) (*ExtensionDraft, error)
+	// [Preview API] API endpoint to publish extension install/uninstall events. This is meant to be invoked by EMS only for sending us data related to install/uninstall of an extension.
+	PublishExtensionEvents(context.Context, PublishExtensionEventsArgs) error
+	// [Preview API]
+	QueryAssociatedAzurePublisher(context.Context, QueryAssociatedAzurePublisherArgs) (*AzurePublisher, error)
+	// [Preview API]
+	QueryExtensions(context.Context, QueryExtensionsArgs) (*ExtensionQueryResult, error)
+	// [Preview API]
+	QueryPublishers(context.Context, QueryPublishersArgs) (*PublisherQueryResult, error)
+	// [Preview API] Flags a concern with an existing question for an extension.
+	ReportQuestion(context.Context, ReportQuestionArgs) (*Concern, error)
+	// [Preview API]
+	RequestAcquisition(context.Context, RequestAcquisitionArgs) (*ExtensionAcquisitionRequest, error)
+	// [Preview API] Send Notification
+	SendNotifications(context.Context, SendNotificationsArgs) error
+	// [Preview API] Set all setting entries for the given user/all-users scope
+	SetGalleryUserSettings(context.Context, SetGalleryUserSettingsArgs) error
+	// [Preview API]
+	ShareExtension(context.Context, ShareExtensionArgs) error
+	// [Preview API]
+	ShareExtensionById(context.Context, ShareExtensionByIdArgs) error
+	// [Preview API]
+	ShareExtensionWithHost(context.Context, ShareExtensionWithHostArgs) error
+	// [Preview API]
+	UnshareExtension(context.Context, UnshareExtensionArgs) error
+	// [Preview API]
+	UnshareExtensionById(context.Context, UnshareExtensionByIdArgs) error
+	// [Preview API]
+	UnshareExtensionWithHost(context.Context, UnshareExtensionWithHostArgs) error
+	// [Preview API] REST endpoint to update an extension.
+	UpdateExtension(context.Context, UpdateExtensionArgs) (*PublishedExtension, error)
+	// [Preview API]
+	UpdateExtensionById(context.Context, UpdateExtensionByIdArgs) (*PublishedExtension, error)
+	// [Preview API]
+	UpdateExtensionProperties(context.Context, UpdateExtensionPropertiesArgs) (*PublishedExtension, error)
+	// [Preview API]
+	UpdateExtensionStatistics(context.Context, UpdateExtensionStatisticsArgs) error
+	// [Preview API]
+	UpdatePayloadInDraftForEditExtension(context.Context, UpdatePayloadInDraftForEditExtensionArgs) (*ExtensionDraft, error)
+	// [Preview API]
+	UpdatePayloadInDraftForNewExtension(context.Context, UpdatePayloadInDraftForNewExtensionArgs) (*ExtensionDraft, error)
+	// [Preview API]
+	UpdatePublisher(context.Context, UpdatePublisherArgs) (*Publisher, error)
+	// [Preview API] Update publisher asset like logo. It accepts asset file as an octet stream and file name is passed in header values.
+	UpdatePublisherAsset(context.Context, UpdatePublisherAssetArgs) (*map[string]string, error)
+	// [Preview API] Endpoint to add/modify publisher membership. Currently Supports only addition/modification of 1 user at a time Works only for adding members of same tenant.
+	UpdatePublisherMembers(context.Context, UpdatePublisherMembersArgs) (*[]PublisherRoleAssignment, error)
+	// [Preview API] Updates an existing question for an extension.
+	UpdateQuestion(context.Context, UpdateQuestionArgs) (*Question, error)
+	// [Preview API] Updates an existing response for a given question for an extension.
+	UpdateResponse(context.Context, UpdateResponseArgs) (*Response, error)
+	// [Preview API] Updates or Flags a review
+	UpdateReview(context.Context, UpdateReviewArgs) (*ReviewPatch, error)
+	// [Preview API]
+	UpdateVSCodeWebExtensionStatistics(context.Context, UpdateVSCodeWebExtensionStatisticsArgs) error
+	// [Preview API]
+	VerifyDomainToken(context.Context, VerifyDomainTokenArgs) error
+}
+
+type ClientImpl struct {
+	Client azuredevops.Client
+}
+
+func NewClient(ctx context.Context, connection *azuredevops.Connection) (Client, error) {
+	client, err := connection.GetClientByResourceAreaId(ctx, ResourceAreaId)
+	if err != nil {
+		return nil, err
+	}
+	return &ClientImpl{
+		Client: *client,
+	}, nil
+}
+
+// [Preview API]
+func (client *ClientImpl) AddAssetForEditExtensionDraft(ctx context.Context, args AddAssetForEditExtensionDraftArgs) (*ExtensionDraftAsset, error) {
+	if args.UploadStream == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.UploadStream"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.DraftId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.DraftId"}
+	}
+	routeValues["draftId"] = (*args.DraftId).String()
+	if args.AssetType == nil || *args.AssetType == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AssetType"}
+	}
+	routeValues["assetType"] = *args.AssetType
+
+	locationId, _ := uuid.Parse("f1db9c47-6619-4998-a7e5-d7f9f41a4617")
+	resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "7.1-preview.1", routeValues, nil, args.UploadStream, "application/octet-stream", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionDraftAsset
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the AddAssetForEditExtensionDraft function
+type AddAssetForEditExtensionDraftArgs struct {
+	// (required) Stream to upload
+	UploadStream io.Reader
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	DraftId *uuid.UUID
+	// (required)
+	AssetType *string
+}
+
+// [Preview API]
+func (client *ClientImpl) AddAssetForNewExtensionDraft(ctx context.Context, args AddAssetForNewExtensionDraftArgs) (*ExtensionDraftAsset, error) {
+	if args.UploadStream == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.UploadStream"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.DraftId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.DraftId"}
+	}
+	routeValues["draftId"] = (*args.DraftId).String()
+	if args.AssetType == nil || *args.AssetType == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AssetType"}
+	}
+	routeValues["assetType"] = *args.AssetType
+
+	locationId, _ := uuid.Parse("88c0b1c8-b4f1-498a-9b2a-8446ef9f32e7")
+	resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "7.1-preview.1", routeValues, nil, args.UploadStream, "application/octet-stream", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionDraftAsset
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the AddAssetForNewExtensionDraft function
+type AddAssetForNewExtensionDraftArgs struct {
+	// (required) Stream to upload
+	UploadStream io.Reader
+	// (required)
+	PublisherName *string
+	// (required)
+	DraftId *uuid.UUID
+	// (required)
+	AssetType *string
+}
+
+// [Preview API]
+func (client *ClientImpl) AssociateAzurePublisher(ctx context.Context, args AssociateAzurePublisherArgs) (*AzurePublisher, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	queryParams := url.Values{}
+	if args.AzurePublisherId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "azurePublisherId"}
+	}
+	queryParams.Add("azurePublisherId", *args.AzurePublisherId)
+	locationId, _ := uuid.Parse("efd202a6-9d87-4ebc-9229-d2b8ae2fdb6d")
+	resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue AzurePublisher
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the AssociateAzurePublisher function
+type AssociateAzurePublisherArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	AzurePublisherId *string
+}
+
+// [Preview API]
+func (client *ClientImpl) CreateCategory(ctx context.Context, args CreateCategoryArgs) (*ExtensionCategory, error) {
+	if args.Category == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Category"}
+	}
+	body, marshalErr := json.Marshal(*args.Category)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("476531a3-7024-4516-a76a-ed64d3008ad6")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionCategory
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the CreateCategory function
+type CreateCategoryArgs struct {
+	// (required)
+	Category *ExtensionCategory
+}
+
+// [Preview API]
+func (client *ClientImpl) CreateDraftForEditExtension(ctx context.Context, args CreateDraftForEditExtensionArgs) (*ExtensionDraft, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	locationId, _ := uuid.Parse("02b33873-4e61-496e-83a2-59d1df46b7d8")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionDraft
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the CreateDraftForEditExtension function
+type CreateDraftForEditExtensionArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) CreateDraftForNewExtension(ctx context.Context, args CreateDraftForNewExtensionArgs) (*ExtensionDraft, error) {
+	if args.UploadStream == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.UploadStream"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	additionalHeaders := make(map[string]string)
+	if args.Product != nil {
+		additionalHeaders["X-Market-UploadFileProduct"] = *args.Product
+	}
+	if args.FileName != nil {
+		additionalHeaders["X-Market-UploadFileName"] = *args.FileName
+	}
+	locationId, _ := uuid.Parse("b3ab127d-ebb9-4d22-b611-4e09593c8d79")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, nil, args.UploadStream, "application/octet-stream", "application/json", additionalHeaders)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionDraft
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the CreateDraftForNewExtension function
+type CreateDraftForNewExtensionArgs struct {
+	// (required) Stream to upload
+	UploadStream io.Reader
+	// (required)
+	PublisherName *string
+	// (required) Header to pass the product type of the payload file
+	Product *string
+	// (optional) Header to pass the filename of the uploaded data
+	FileName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) CreateExtension(ctx context.Context, args CreateExtensionArgs) (*PublishedExtension, error) {
+	if args.UploadStream == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.UploadStream"}
+	}
+	queryParams := url.Values{}
+	if args.ExtensionType != nil {
+		queryParams.Add("extensionType", *args.ExtensionType)
+	}
+	if args.ReCaptchaToken != nil {
+		queryParams.Add("reCaptchaToken", *args.ReCaptchaToken)
+	}
+	locationId, _ := uuid.Parse("a41192c8-9525-4b58-bc86-179fa549d80d")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.2", nil, queryParams, args.UploadStream, "application/octet-stream", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue PublishedExtension
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the CreateExtension function
+type CreateExtensionArgs struct {
+	// (required) Stream to upload
+	UploadStream io.Reader
+	// (optional)
+	ExtensionType *string
+	// (optional)
+	ReCaptchaToken *string
+}
+
+// [Preview API]
+func (client *ClientImpl) CreateExtensionWithPublisher(ctx context.Context, args CreateExtensionWithPublisherArgs) (*PublishedExtension, error) {
+	if args.UploadStream == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.UploadStream"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	queryParams := url.Values{}
+	if args.ExtensionType != nil {
+		queryParams.Add("extensionType", *args.ExtensionType)
+	}
+	if args.ReCaptchaToken != nil {
+		queryParams.Add("reCaptchaToken", *args.ReCaptchaToken)
+	}
+	locationId, _ := uuid.Parse("e11ea35a-16fe-4b80-ab11-c4cab88a0966")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.2", routeValues, queryParams, args.UploadStream, "application/octet-stream", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue PublishedExtension
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the CreateExtensionWithPublisher function
+type CreateExtensionWithPublisherArgs struct {
+	// (required) Stream to upload
+	UploadStream io.Reader
+	// (required)
+	PublisherName *string
+	// (optional)
+	ExtensionType *string
+	// (optional)
+	ReCaptchaToken *string
+}
+
+// [Preview API]
+func (client *ClientImpl) CreatePublisher(ctx context.Context, args CreatePublisherArgs) (*Publisher, error) {
+	if args.Publisher == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Publisher"}
+	}
+	body, marshalErr := json.Marshal(*args.Publisher)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("4ddec66a-e4f6-4f5d-999e-9e77710d7ff4")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue Publisher
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the CreatePublisher function
+type CreatePublisherArgs struct {
+	// (required)
+	Publisher *Publisher
+}
+
+// [Preview API] Creates a new question for an extension.
+func (client *ClientImpl) CreateQuestion(ctx context.Context, args CreateQuestionArgs) (*Question, error) {
+	if args.Question == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Question"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	body, marshalErr := json.Marshal(*args.Question)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("6d1d9741-eca8-4701-a3a5-235afc82dfa4")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue Question
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the CreateQuestion function
+type CreateQuestionArgs struct {
+	// (required) Question to be created for the extension.
+	Question *Question
+	// (required) Name of the publisher who published the extension.
+	PublisherName *string
+	// (required) Name of the extension.
+	ExtensionName *string
+}
+
+// [Preview API] Creates a new response for a given question for an extension.
+func (client *ClientImpl) CreateResponse(ctx context.Context, args CreateResponseArgs) (*Response, error) {
+	if args.Response == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Response"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.QuestionId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.QuestionId"}
+	}
+	routeValues["questionId"] = strconv.FormatUint(*args.QuestionId, 10)
+
+	body, marshalErr := json.Marshal(*args.Response)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("7f8ae5e0-46b0-438f-b2e8-13e8513517bd")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue Response
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the CreateResponse function
+type CreateResponseArgs struct {
+	// (required) Response to be created for the extension.
+	Response *Response
+	// (required) Name of the publisher who published the extension.
+	PublisherName *string
+	// (required) Name of the extension.
+	ExtensionName *string
+	// (required) Identifier of the question for which response is to be created for the extension.
+	QuestionId *uint64
+}
+
+// [Preview API] Creates a new review for an extension
+func (client *ClientImpl) CreateReview(ctx context.Context, args CreateReviewArgs) (*Review, error) {
+	if args.Review == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Review"}
+	}
+	routeValues := make(map[string]string)
+	if args.PubName == nil || *args.PubName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PubName"}
+	}
+	routeValues["pubName"] = *args.PubName
+	if args.ExtName == nil || *args.ExtName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtName"}
+	}
+	routeValues["extName"] = *args.ExtName
+
+	body, marshalErr := json.Marshal(*args.Review)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("e6e85b9d-aa70-40e6-aa28-d0fbf40b91a3")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue Review
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the CreateReview function
+type CreateReviewArgs struct {
+	// (required) Review to be created for the extension
+	Review *Review
+	// (required) Name of the publisher who published the extension
+	PubName *string
+	// (required) Name of the extension
+	ExtName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) CreateSupportRequest(ctx context.Context, args CreateSupportRequestArgs) error {
+	if args.CustomerSupportRequest == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.CustomerSupportRequest"}
+	}
+	body, marshalErr := json.Marshal(*args.CustomerSupportRequest)
+	if marshalErr != nil {
+		return marshalErr
+	}
+	locationId, _ := uuid.Parse("8eded385-026a-4c15-b810-b8eb402771f1")
+	_, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the CreateSupportRequest function
+type CreateSupportRequestArgs struct {
+	// (required)
+	CustomerSupportRequest *CustomerSupportRequest
+}
+
+// [Preview API]
+func (client *ClientImpl) DeleteExtension(ctx context.Context, args DeleteExtensionArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	queryParams := url.Values{}
+	if args.Version != nil {
+		queryParams.Add("version", *args.Version)
+	}
+	locationId, _ := uuid.Parse("e11ea35a-16fe-4b80-ab11-c4cab88a0966")
+	_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "7.1-preview.2", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the DeleteExtension function
+type DeleteExtensionArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (optional)
+	Version *string
+}
+
+// [Preview API]
+func (client *ClientImpl) DeleteExtensionById(ctx context.Context, args DeleteExtensionByIdArgs) error {
+	routeValues := make(map[string]string)
+	if args.ExtensionId == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.ExtensionId"}
+	}
+	routeValues["extensionId"] = (*args.ExtensionId).String()
+
+	queryParams := url.Values{}
+	if args.Version != nil {
+		queryParams.Add("version", *args.Version)
+	}
+	locationId, _ := uuid.Parse("a41192c8-9525-4b58-bc86-179fa549d80d")
+	_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "7.1-preview.2", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the DeleteExtensionById function
+type DeleteExtensionByIdArgs struct {
+	// (required)
+	ExtensionId *uuid.UUID
+	// (optional)
+	Version *string
+}
+
+// [Preview API]
+func (client *ClientImpl) DeletePublisher(ctx context.Context, args DeletePublisherArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	locationId, _ := uuid.Parse("4ddec66a-e4f6-4f5d-999e-9e77710d7ff4")
+	_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the DeletePublisher function
+type DeletePublisherArgs struct {
+	// (required)
+	PublisherName *string
+}
+
+// [Preview API] Delete publisher asset like logo
+func (client *ClientImpl) DeletePublisherAsset(ctx context.Context, args DeletePublisherAssetArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	queryParams := url.Values{}
+	if args.AssetType != nil {
+		queryParams.Add("assetType", *args.AssetType)
+	}
+	locationId, _ := uuid.Parse("21143299-34f9-4c62-8ca8-53da691192f9")
+	_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the DeletePublisherAsset function
+type DeletePublisherAssetArgs struct {
+	// (required) Internal name of the publisher
+	PublisherName *string
+	// (optional) Type of asset. Default value is 'logo'.
+	AssetType *string
+}
+
+// [Preview API] Deletes an existing question and all its associated responses for an extension. (soft delete)
+func (client *ClientImpl) DeleteQuestion(ctx context.Context, args DeleteQuestionArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.QuestionId == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.QuestionId"}
+	}
+	routeValues["questionId"] = strconv.FormatUint(*args.QuestionId, 10)
+
+	locationId, _ := uuid.Parse("6d1d9741-eca8-4701-a3a5-235afc82dfa4")
+	_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the DeleteQuestion function
+type DeleteQuestionArgs struct {
+	// (required) Name of the publisher who published the extension.
+	PublisherName *string
+	// (required) Name of the extension.
+	ExtensionName *string
+	// (required) Identifier of the question to be deleted for the extension.
+	QuestionId *uint64
+}
+
+// [Preview API] Deletes a response for an extension. (soft delete)
+func (client *ClientImpl) DeleteResponse(ctx context.Context, args DeleteResponseArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.QuestionId == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.QuestionId"}
+	}
+	routeValues["questionId"] = strconv.FormatUint(*args.QuestionId, 10)
+	if args.ResponseId == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.ResponseId"}
+	}
+	routeValues["responseId"] = strconv.FormatUint(*args.ResponseId, 10)
+
+	locationId, _ := uuid.Parse("7f8ae5e0-46b0-438f-b2e8-13e8513517bd")
+	_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the DeleteResponse function
+type DeleteResponseArgs struct {
+	// (required) Name of the publisher who published the extension.
+	PublisherName *string
+	// (required) Name of the extension.
+	ExtensionName *string
+	// (required) Identifies the question whose response is to be deleted.
+	QuestionId *uint64
+	// (required) Identifies the response to be deleted.
+	ResponseId *uint64
+}
+
+// [Preview API] Deletes a review
+func (client *ClientImpl) DeleteReview(ctx context.Context, args DeleteReviewArgs) error {
+	routeValues := make(map[string]string)
+	if args.PubName == nil || *args.PubName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PubName"}
+	}
+	routeValues["pubName"] = *args.PubName
+	if args.ExtName == nil || *args.ExtName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtName"}
+	}
+	routeValues["extName"] = *args.ExtName
+	if args.ReviewId == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.ReviewId"}
+	}
+	routeValues["reviewId"] = strconv.FormatUint(*args.ReviewId, 10)
+
+	locationId, _ := uuid.Parse("e6e85b9d-aa70-40e6-aa28-d0fbf40b91a3")
+	_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the DeleteReview function
+type DeleteReviewArgs struct {
+	// (required) Name of the publisher who published the extension
+	PubName *string
+	// (required) Name of the extension
+	ExtName *string
+	// (required) Id of the review which needs to be updated
+	ReviewId *uint64
+}
+
+// [Preview API]
+func (client *ClientImpl) ExtensionValidator(ctx context.Context, args ExtensionValidatorArgs) error {
+	if args.AzureRestApiRequestModel == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.AzureRestApiRequestModel"}
+	}
+	body, marshalErr := json.Marshal(*args.AzureRestApiRequestModel)
+	if marshalErr != nil {
+		return marshalErr
+	}
+	locationId, _ := uuid.Parse("05e8a5e1-8c59-4c2c-8856-0ff087d1a844")
+	_, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the ExtensionValidator function
+type ExtensionValidatorArgs struct {
+	// (required)
+	AzureRestApiRequestModel *AzureRestApiRequestModel
+}
+
+// [Preview API]
+func (client *ClientImpl) FetchDomainToken(ctx context.Context, args FetchDomainTokenArgs) (*string, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	locationId, _ := uuid.Parse("67a609ef-fa74-4b52-8664-78d76f7b3634")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue string
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the FetchDomainToken function
+type FetchDomainTokenArgs struct {
+	// (required)
+	PublisherName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GenerateKey(ctx context.Context, args GenerateKeyArgs) error {
+	routeValues := make(map[string]string)
+	if args.KeyType == nil || *args.KeyType == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.KeyType"}
+	}
+	routeValues["keyType"] = *args.KeyType
+
+	queryParams := url.Values{}
+	if args.ExpireCurrentSeconds != nil {
+		queryParams.Add("expireCurrentSeconds", strconv.Itoa(*args.ExpireCurrentSeconds))
+	}
+	locationId, _ := uuid.Parse("92ed5cf4-c38b-465a-9059-2f2fb7c624b5")
+	_, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the GenerateKey function
+type GenerateKeyArgs struct {
+	// (required)
+	KeyType *string
+	// (optional)
+	ExpireCurrentSeconds *int
+}
+
+// [Preview API]
+func (client *ClientImpl) GetAcquisitionOptions(ctx context.Context, args GetAcquisitionOptionsArgs) (*AcquisitionOptions, error) {
+	routeValues := make(map[string]string)
+	if args.ItemId == nil || *args.ItemId == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ItemId"}
+	}
+	routeValues["itemId"] = *args.ItemId
+
+	queryParams := url.Values{}
+	if args.InstallationTarget == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "installationTarget"}
+	}
+	queryParams.Add("installationTarget", *args.InstallationTarget)
+	if args.TestCommerce != nil {
+		queryParams.Add("testCommerce", strconv.FormatBool(*args.TestCommerce))
+	}
+	if args.IsFreeOrTrialInstall != nil {
+		queryParams.Add("isFreeOrTrialInstall", strconv.FormatBool(*args.IsFreeOrTrialInstall))
+	}
+	locationId, _ := uuid.Parse("9d0a0105-075e-4760-aa15-8bcf54d1bd7d")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue AcquisitionOptions
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetAcquisitionOptions function
+type GetAcquisitionOptionsArgs struct {
+	// (required)
+	ItemId *string
+	// (required)
+	InstallationTarget *string
+	// (optional)
+	TestCommerce *bool
+	// (optional)
+	IsFreeOrTrialInstall *bool
+}
+
+// [Preview API]
+func (client *ClientImpl) GetAsset(ctx context.Context, args GetAssetArgs) (io.ReadCloser, error) {
+	routeValues := make(map[string]string)
+	if args.ExtensionId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ExtensionId"}
+	}
+	routeValues["extensionId"] = (*args.ExtensionId).String()
+	if args.Version == nil || *args.Version == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Version"}
+	}
+	routeValues["version"] = *args.Version
+	if args.AssetType == nil || *args.AssetType == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AssetType"}
+	}
+	routeValues["assetType"] = *args.AssetType
+
+	queryParams := url.Values{}
+	if args.AccountToken != nil {
+		queryParams.Add("accountToken", *args.AccountToken)
+	}
+	if args.AcceptDefault != nil {
+		queryParams.Add("acceptDefault", strconv.FormatBool(*args.AcceptDefault))
+	}
+	additionalHeaders := make(map[string]string)
+	if args.AccountTokenHeader != nil {
+		additionalHeaders["X-Market-AccountToken"] = *args.AccountTokenHeader
+	}
+	locationId, _ := uuid.Parse("5d545f3d-ef47-488b-8be3-f5ee1517856c")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/octet-stream", additionalHeaders)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Body, err
+}
+
+// Arguments for the GetAsset function
+type GetAssetArgs struct {
+	// (required)
+	ExtensionId *uuid.UUID
+	// (required)
+	Version *string
+	// (required)
+	AssetType *string
+	// (optional)
+	AccountToken *string
+	// (optional)
+	AcceptDefault *bool
+	// (optional) Header to pass the account token
+	AccountTokenHeader *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetAssetAuthenticated(ctx context.Context, args GetAssetAuthenticatedArgs) (io.ReadCloser, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.Version == nil || *args.Version == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Version"}
+	}
+	routeValues["version"] = *args.Version
+	if args.AssetType == nil || *args.AssetType == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AssetType"}
+	}
+	routeValues["assetType"] = *args.AssetType
+
+	queryParams := url.Values{}
+	if args.AccountToken != nil {
+		queryParams.Add("accountToken", *args.AccountToken)
+	}
+	additionalHeaders := make(map[string]string)
+	if args.AccountTokenHeader != nil {
+		additionalHeaders["X-Market-AccountToken"] = *args.AccountTokenHeader
+	}
+	locationId, _ := uuid.Parse("506aff36-2622-4f70-8063-77cce6366d20")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/octet-stream", additionalHeaders)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Body, err
+}
+
+// Arguments for the GetAssetAuthenticated function
+type GetAssetAuthenticatedArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	Version *string
+	// (required)
+	AssetType *string
+	// (optional)
+	AccountToken *string
+	// (optional) Header to pass the account token
+	AccountTokenHeader *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetAssetByName(ctx context.Context, args GetAssetByNameArgs) (io.ReadCloser, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.Version == nil || *args.Version == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Version"}
+	}
+	routeValues["version"] = *args.Version
+	if args.AssetType == nil || *args.AssetType == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AssetType"}
+	}
+	routeValues["assetType"] = *args.AssetType
+
+	queryParams := url.Values{}
+	if args.AccountToken != nil {
+		queryParams.Add("accountToken", *args.AccountToken)
+	}
+	if args.AcceptDefault != nil {
+		queryParams.Add("acceptDefault", strconv.FormatBool(*args.AcceptDefault))
+	}
+	additionalHeaders := make(map[string]string)
+	if args.AccountTokenHeader != nil {
+		additionalHeaders["X-Market-AccountToken"] = *args.AccountTokenHeader
+	}
+	locationId, _ := uuid.Parse("7529171f-a002-4180-93ba-685f358a0482")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/octet-stream", additionalHeaders)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Body, err
+}
+
+// Arguments for the GetAssetByName function
+type GetAssetByNameArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	Version *string
+	// (required)
+	AssetType *string
+	// (optional)
+	AccountToken *string
+	// (optional)
+	AcceptDefault *bool
+	// (optional) Header to pass the account token
+	AccountTokenHeader *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetAssetFromEditExtensionDraft(ctx context.Context, args GetAssetFromEditExtensionDraftArgs) (io.ReadCloser, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.DraftId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.DraftId"}
+	}
+	routeValues["draftId"] = (*args.DraftId).String()
+	if args.AssetType == nil || *args.AssetType == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AssetType"}
+	}
+	routeValues["assetType"] = *args.AssetType
+
+	queryParams := url.Values{}
+	if args.ExtensionName == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "extensionName"}
+	}
+	queryParams.Add("extensionName", *args.ExtensionName)
+	locationId, _ := uuid.Parse("88c0b1c8-b4f1-498a-9b2a-8446ef9f32e7")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/octet-stream", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Body, err
+}
+
+// Arguments for the GetAssetFromEditExtensionDraft function
+type GetAssetFromEditExtensionDraftArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	DraftId *uuid.UUID
+	// (required)
+	AssetType *string
+	// (required)
+	ExtensionName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetAssetFromNewExtensionDraft(ctx context.Context, args GetAssetFromNewExtensionDraftArgs) (io.ReadCloser, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.DraftId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.DraftId"}
+	}
+	routeValues["draftId"] = (*args.DraftId).String()
+	if args.AssetType == nil || *args.AssetType == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AssetType"}
+	}
+	routeValues["assetType"] = *args.AssetType
+
+	locationId, _ := uuid.Parse("88c0b1c8-b4f1-498a-9b2a-8446ef9f32e7")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/octet-stream", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Body, err
+}
+
+// Arguments for the GetAssetFromNewExtensionDraft function
+type GetAssetFromNewExtensionDraftArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	DraftId *uuid.UUID
+	// (required)
+	AssetType *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetAssetWithToken(ctx context.Context, args GetAssetWithTokenArgs) (io.ReadCloser, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.Version == nil || *args.Version == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Version"}
+	}
+	routeValues["version"] = *args.Version
+	if args.AssetType == nil || *args.AssetType == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AssetType"}
+	}
+	routeValues["assetType"] = *args.AssetType
+	if args.AssetToken != nil && *args.AssetToken != "" {
+		routeValues["assetToken"] = *args.AssetToken
+	}
+
+	queryParams := url.Values{}
+	if args.AccountToken != nil {
+		queryParams.Add("accountToken", *args.AccountToken)
+	}
+	if args.AcceptDefault != nil {
+		queryParams.Add("acceptDefault", strconv.FormatBool(*args.AcceptDefault))
+	}
+	additionalHeaders := make(map[string]string)
+	if args.AccountTokenHeader != nil {
+		additionalHeaders["X-Market-AccountToken"] = *args.AccountTokenHeader
+	}
+	locationId, _ := uuid.Parse("364415a1-0077-4a41-a7a0-06edd4497492")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/octet-stream", additionalHeaders)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Body, err
+}
+
+// Arguments for the GetAssetWithToken function
+type GetAssetWithTokenArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	Version *string
+	// (required)
+	AssetType *string
+	// (optional)
+	AssetToken *string
+	// (optional)
+	AccountToken *string
+	// (optional)
+	AcceptDefault *bool
+	// (optional) Header to pass the account token
+	AccountTokenHeader *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetCategories(ctx context.Context, args GetCategoriesArgs) (*[]string, error) {
+	queryParams := url.Values{}
+	if args.Languages != nil {
+		queryParams.Add("languages", *args.Languages)
+	}
+	locationId, _ := uuid.Parse("e0a5a71e-3ac3-43a0-ae7d-0bb5c3046a2a")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", nil, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue []string
+	err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetCategories function
+type GetCategoriesArgs struct {
+	// (optional)
+	Languages *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetCategoryDetails(ctx context.Context, args GetCategoryDetailsArgs) (*CategoriesResult, error) {
+	routeValues := make(map[string]string)
+	if args.CategoryName == nil || *args.CategoryName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.CategoryName"}
+	}
+	routeValues["categoryName"] = *args.CategoryName
+
+	queryParams := url.Values{}
+	if args.Languages != nil {
+		queryParams.Add("languages", *args.Languages)
+	}
+	if args.Product != nil {
+		queryParams.Add("product", *args.Product)
+	}
+	locationId, _ := uuid.Parse("75d3c04d-84d2-4973-acd2-22627587dabc")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue CategoriesResult
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetCategoryDetails function
+type GetCategoryDetailsArgs struct {
+	// (required)
+	CategoryName *string
+	// (optional)
+	Languages *string
+	// (optional)
+	Product *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetCategoryTree(ctx context.Context, args GetCategoryTreeArgs) (*ProductCategory, error) {
+	routeValues := make(map[string]string)
+	if args.Product == nil || *args.Product == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Product"}
+	}
+	routeValues["product"] = *args.Product
+	if args.CategoryId == nil || *args.CategoryId == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.CategoryId"}
+	}
+	routeValues["categoryId"] = *args.CategoryId
+
+	queryParams := url.Values{}
+	if args.Lcid != nil {
+		queryParams.Add("lcid", strconv.Itoa(*args.Lcid))
+	}
+	if args.Source != nil {
+		queryParams.Add("source", *args.Source)
+	}
+	if args.ProductVersion != nil {
+		queryParams.Add("productVersion", *args.ProductVersion)
+	}
+	if args.Skus != nil {
+		queryParams.Add("skus", *args.Skus)
+	}
+	if args.SubSkus != nil {
+		queryParams.Add("subSkus", *args.SubSkus)
+	}
+	if args.ProductArchitecture != nil {
+		queryParams.Add("productArchitecture", *args.ProductArchitecture)
+	}
+	locationId, _ := uuid.Parse("1102bb42-82b0-4955-8d8a-435d6b4cedd3")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ProductCategory
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetCategoryTree function
+type GetCategoryTreeArgs struct {
+	// (required)
+	Product *string
+	// (required)
+	CategoryId *string
+	// (optional)
+	Lcid *int
+	// (optional)
+	Source *string
+	// (optional)
+	ProductVersion *string
+	// (optional)
+	Skus *string
+	// (optional)
+	SubSkus *string
+	// (optional)
+	ProductArchitecture *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetCertificate(ctx context.Context, args GetCertificateArgs) (io.ReadCloser, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.Version != nil && *args.Version != "" {
+		routeValues["version"] = *args.Version
+	}
+
+	locationId, _ := uuid.Parse("e905ad6a-3f1f-4d08-9f6d-7d357ff8b7d0")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/octet-stream", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Body, err
+}
+
+// Arguments for the GetCertificate function
+type GetCertificateArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (optional)
+	Version *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetContentVerificationLog(ctx context.Context, args GetContentVerificationLogArgs) (io.ReadCloser, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	locationId, _ := uuid.Parse("c0f1c7c4-3557-4ffb-b774-1e48c4865e99")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/octet-stream", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Body, err
+}
+
+// Arguments for the GetContentVerificationLog function
+type GetContentVerificationLogArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetExtension(ctx context.Context, args GetExtensionArgs) (*PublishedExtension, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	queryParams := url.Values{}
+	if args.Version != nil {
+		queryParams.Add("version", *args.Version)
+	}
+	if args.Flags != nil {
+		queryParams.Add("flags", string(*args.Flags))
+	}
+	if args.AccountToken != nil {
+		queryParams.Add("accountToken", *args.AccountToken)
+	}
+	additionalHeaders := make(map[string]string)
+	if args.AccountTokenHeader != nil {
+		additionalHeaders["X-Market-AccountToken"] = *args.AccountTokenHeader
+	}
+	locationId, _ := uuid.Parse("e11ea35a-16fe-4b80-ab11-c4cab88a0966")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.2", routeValues, queryParams, nil, "", "application/json", additionalHeaders)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue PublishedExtension
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetExtension function
+type GetExtensionArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (optional)
+	Version *string
+	// (optional)
+	Flags *ExtensionQueryFlags
+	// (optional)
+	AccountToken *string
+	// (optional) Header to pass the account token
+	AccountTokenHeader *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetExtensionById(ctx context.Context, args GetExtensionByIdArgs) (*PublishedExtension, error) {
+	routeValues := make(map[string]string)
+	if args.ExtensionId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ExtensionId"}
+	}
+	routeValues["extensionId"] = (*args.ExtensionId).String()
+
+	queryParams := url.Values{}
+	if args.Version != nil {
+		queryParams.Add("version", *args.Version)
+	}
+	if args.Flags != nil {
+		queryParams.Add("flags", string(*args.Flags))
+	}
+	locationId, _ := uuid.Parse("a41192c8-9525-4b58-bc86-179fa549d80d")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.2", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue PublishedExtension
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetExtensionById function
+type GetExtensionByIdArgs struct {
+	// (required)
+	ExtensionId *uuid.UUID
+	// (optional)
+	Version *string
+	// (optional)
+	Flags *ExtensionQueryFlags
+}
+
+// [Preview API]
+func (client *ClientImpl) GetExtensionDailyStats(ctx context.Context, args GetExtensionDailyStatsArgs) (*ExtensionDailyStats, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	queryParams := url.Values{}
+	if args.Days != nil {
+		queryParams.Add("days", strconv.Itoa(*args.Days))
+	}
+	if args.Aggregate != nil {
+		queryParams.Add("aggregate", string(*args.Aggregate))
+	}
+	if args.AfterDate != nil {
+		queryParams.Add("afterDate", (*args.AfterDate).AsQueryParameter())
+	}
+	locationId, _ := uuid.Parse("ae06047e-51c5-4fb4-ab65-7be488544416")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionDailyStats
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetExtensionDailyStats function
+type GetExtensionDailyStatsArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (optional)
+	Days *int
+	// (optional)
+	Aggregate *ExtensionStatsAggregateType
+	// (optional)
+	AfterDate *azuredevops.Time
+}
+
+// [Preview API] This route/location id only supports HTTP POST anonymously, so that the page view daily stat can be incremented from Marketplace client. Trying to call GET on this route should result in an exception. Without this explicit implementation, calling GET on this public route invokes the above GET implementation GetExtensionDailyStats.
+func (client *ClientImpl) GetExtensionDailyStatsAnonymous(ctx context.Context, args GetExtensionDailyStatsAnonymousArgs) (*ExtensionDailyStats, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.Version == nil || *args.Version == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Version"}
+	}
+	routeValues["version"] = *args.Version
+
+	locationId, _ := uuid.Parse("4fa7adb6-ca65-4075-a232-5f28323288ea")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionDailyStats
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetExtensionDailyStatsAnonymous function
+type GetExtensionDailyStatsAnonymousArgs struct {
+	// (required) Name of the publisher
+	PublisherName *string
+	// (required) Name of the extension
+	ExtensionName *string
+	// (required) Version of the extension
+	Version *string
+}
+
+// [Preview API] Get install/uninstall events of an extension. If both count and afterDate parameters are specified, count takes precedence.
+func (client *ClientImpl) GetExtensionEvents(ctx context.Context, args GetExtensionEventsArgs) (*ExtensionEvents, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	queryParams := url.Values{}
+	if args.Count != nil {
+		queryParams.Add("count", strconv.Itoa(*args.Count))
+	}
+	if args.AfterDate != nil {
+		queryParams.Add("afterDate", (*args.AfterDate).AsQueryParameter())
+	}
+	if args.Include != nil {
+		queryParams.Add("include", *args.Include)
+	}
+	if args.IncludeProperty != nil {
+		queryParams.Add("includeProperty", *args.IncludeProperty)
+	}
+	locationId, _ := uuid.Parse("3d13c499-2168-4d06-bef4-14aba185dcd5")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionEvents
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetExtensionEvents function
+type GetExtensionEventsArgs struct {
+	// (required) Name of the publisher
+	PublisherName *string
+	// (required) Name of the extension
+	ExtensionName *string
+	// (optional) Count of events to fetch, applies to each event type.
+	Count *int
+	// (optional) Fetch events that occurred on or after this date
+	AfterDate *azuredevops.Time
+	// (optional) Filter options. Supported values: install, uninstall, review, acquisition, sales. Default is to fetch all types of events
+	Include *string
+	// (optional) Event properties to include. Currently only 'lastContactDetails' is supported for uninstall events
+	IncludeProperty *string
+}
+
+// [Preview API] Returns extension reports
+func (client *ClientImpl) GetExtensionReports(ctx context.Context, args GetExtensionReportsArgs) (interface{}, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	queryParams := url.Values{}
+	if args.Days != nil {
+		queryParams.Add("days", strconv.Itoa(*args.Days))
+	}
+	if args.Count != nil {
+		queryParams.Add("count", strconv.Itoa(*args.Count))
+	}
+	if args.AfterDate != nil {
+		queryParams.Add("afterDate", (*args.AfterDate).AsQueryParameter())
+	}
+	locationId, _ := uuid.Parse("79e0c74f-157f-437e-845f-74fbb4121d4c")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue interface{}
+	err = client.Client.UnmarshalBody(resp, responseValue)
+	return responseValue, err
+}
+
+// Arguments for the GetExtensionReports function
+type GetExtensionReportsArgs struct {
+	// (required) Name of the publisher who published the extension
+	PublisherName *string
+	// (required) Name of the extension
+	ExtensionName *string
+	// (optional) Last n days report. If afterDate and days are specified, days will take priority
+	Days *int
+	// (optional) Number of events to be returned
+	Count *int
+	// (optional) Use if you want to fetch events newer than the specified date
+	AfterDate *azuredevops.Time
+}
+
+// [Preview API] Get all setting entries for the given user/all-users scope
+func (client *ClientImpl) GetGalleryUserSettings(ctx context.Context, args GetGalleryUserSettingsArgs) (*map[string]interface{}, error) {
+	routeValues := make(map[string]string)
+	if args.UserScope == nil || *args.UserScope == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.UserScope"}
+	}
+	routeValues["userScope"] = *args.UserScope
+	if args.Key != nil && *args.Key != "" {
+		routeValues["key"] = *args.Key
+	}
+
+	locationId, _ := uuid.Parse("9b75ece3-7960-401c-848b-148ac01ca350")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue map[string]interface{}
+	err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetGalleryUserSettings function
+type GetGalleryUserSettingsArgs struct {
+	// (required) User-Scope at which to get the value. Should be "me" for the current user or "host" for all users.
+	UserScope *string
+	// (optional) Optional key under which to filter all the entries
+	Key *string
+}
+
+// [Preview API] This endpoint gets hit when you download a VSTS extension from the Web UI
+func (client *ClientImpl) GetPackage(ctx context.Context, args GetPackageArgs) (io.ReadCloser, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.Version == nil || *args.Version == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Version"}
+	}
+	routeValues["version"] = *args.Version
+
+	queryParams := url.Values{}
+	if args.AccountToken != nil {
+		queryParams.Add("accountToken", *args.AccountToken)
+	}
+	if args.AcceptDefault != nil {
+		queryParams.Add("acceptDefault", strconv.FormatBool(*args.AcceptDefault))
+	}
+	additionalHeaders := make(map[string]string)
+	if args.AccountTokenHeader != nil {
+		additionalHeaders["X-Market-AccountToken"] = *args.AccountTokenHeader
+	}
+	locationId, _ := uuid.Parse("7cb576f8-1cae-4c4b-b7b1-e4af5759e965")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/octet-stream", additionalHeaders)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Body, err
+}
+
+// Arguments for the GetPackage function
+type GetPackageArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	Version *string
+	// (optional)
+	AccountToken *string
+	// (optional)
+	AcceptDefault *bool
+	// (optional) Header to pass the account token
+	AccountTokenHeader *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetPublisher(ctx context.Context, args GetPublisherArgs) (*Publisher, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	queryParams := url.Values{}
+	if args.Flags != nil {
+		queryParams.Add("flags", strconv.Itoa(*args.Flags))
+	}
+	locationId, _ := uuid.Parse("4ddec66a-e4f6-4f5d-999e-9e77710d7ff4")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue Publisher
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetPublisher function
+type GetPublisherArgs struct {
+	// (required)
+	PublisherName *string
+	// (optional)
+	Flags *int
+}
+
+// [Preview API] Get publisher asset like logo as a stream
+func (client *ClientImpl) GetPublisherAsset(ctx context.Context, args GetPublisherAssetArgs) (io.ReadCloser, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	queryParams := url.Values{}
+	if args.AssetType != nil {
+		queryParams.Add("assetType", *args.AssetType)
+	}
+	locationId, _ := uuid.Parse("21143299-34f9-4c62-8ca8-53da691192f9")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/octet-stream", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Body, err
+}
+
+// Arguments for the GetPublisherAsset function
+type GetPublisherAssetArgs struct {
+	// (required) Internal name of the publisher
+	PublisherName *string
+	// (optional) Type of asset. Default value is 'logo'.
+	AssetType *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetPublisherWithoutToken(ctx context.Context, args GetPublisherWithoutTokenArgs) (*Publisher, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	locationId, _ := uuid.Parse("215a2ed8-458a-4850-ad5a-45f1dabc3461")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue Publisher
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetPublisherWithoutToken function
+type GetPublisherWithoutTokenArgs struct {
+	// (required)
+	PublisherName *string
+}
+
+// [Preview API] Returns a list of questions with their responses associated with an extension.
+func (client *ClientImpl) GetQuestions(ctx context.Context, args GetQuestionsArgs) (*QuestionsResult, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	queryParams := url.Values{}
+	if args.Count != nil {
+		queryParams.Add("count", strconv.Itoa(*args.Count))
+	}
+	if args.Page != nil {
+		queryParams.Add("page", strconv.Itoa(*args.Page))
+	}
+	if args.AfterDate != nil {
+		queryParams.Add("afterDate", (*args.AfterDate).AsQueryParameter())
+	}
+	locationId, _ := uuid.Parse("c010d03d-812c-4ade-ae07-c1862475eda5")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue QuestionsResult
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetQuestions function
+type GetQuestionsArgs struct {
+	// (required) Name of the publisher who published the extension.
+	PublisherName *string
+	// (required) Name of the extension.
+	ExtensionName *string
+	// (optional) Number of questions to retrieve (defaults to 10).
+	Count *int
+	// (optional) Page number from which set of questions are to be retrieved.
+	Page *int
+	// (optional) If provided, results questions are returned which were posted after this date
+	AfterDate *azuredevops.Time
+}
+
+// [Preview API] Returns a list of reviews associated with an extension
+func (client *ClientImpl) GetReviews(ctx context.Context, args GetReviewsArgs) (*ReviewsResult, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	queryParams := url.Values{}
+	if args.Count != nil {
+		queryParams.Add("count", strconv.Itoa(*args.Count))
+	}
+	if args.FilterOptions != nil {
+		queryParams.Add("filterOptions", string(*args.FilterOptions))
+	}
+	if args.BeforeDate != nil {
+		queryParams.Add("beforeDate", (*args.BeforeDate).AsQueryParameter())
+	}
+	if args.AfterDate != nil {
+		queryParams.Add("afterDate", (*args.AfterDate).AsQueryParameter())
+	}
+	locationId, _ := uuid.Parse("5b3f819f-f247-42ad-8c00-dd9ab9ab246d")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ReviewsResult
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetReviews function
+type GetReviewsArgs struct {
+	// (required) Name of the publisher who published the extension
+	PublisherName *string
+	// (required) Name of the extension
+	ExtensionName *string
+	// (optional) Number of reviews to retrieve (defaults to 5)
+	Count *int
+	// (optional) FilterOptions to filter out empty reviews etcetera, defaults to none
+	FilterOptions *ReviewFilterOptions
+	// (optional) Use if you want to fetch reviews older than the specified date, defaults to null
+	BeforeDate *azuredevops.Time
+	// (optional) Use if you want to fetch reviews newer than the specified date, defaults to null
+	AfterDate *azuredevops.Time
+}
+
+// [Preview API] Returns a summary of the reviews
+func (client *ClientImpl) GetReviewsSummary(ctx context.Context, args GetReviewsSummaryArgs) (*ReviewSummary, error) {
+	routeValues := make(map[string]string)
+	if args.PubName == nil || *args.PubName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PubName"}
+	}
+	routeValues["pubName"] = *args.PubName
+	if args.ExtName == nil || *args.ExtName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtName"}
+	}
+	routeValues["extName"] = *args.ExtName
+
+	queryParams := url.Values{}
+	if args.BeforeDate != nil {
+		queryParams.Add("beforeDate", (*args.BeforeDate).AsQueryParameter())
+	}
+	if args.AfterDate != nil {
+		queryParams.Add("afterDate", (*args.AfterDate).AsQueryParameter())
+	}
+	locationId, _ := uuid.Parse("b7b44e21-209e-48f0-ae78-04727fc37d77")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ReviewSummary
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetReviewsSummary function
+type GetReviewsSummaryArgs struct {
+	// (required) Name of the publisher who published the extension
+	PubName *string
+	// (required) Name of the extension
+	ExtName *string
+	// (optional) Use if you want to fetch summary of reviews older than the specified date, defaults to null
+	BeforeDate *azuredevops.Time
+	// (optional) Use if you want to fetch summary of reviews newer than the specified date, defaults to null
+	AfterDate *azuredevops.Time
+}
+
+// [Preview API]
+func (client *ClientImpl) GetRootCategories(ctx context.Context, args GetRootCategoriesArgs) (*ProductCategoriesResult, error) {
+	routeValues := make(map[string]string)
+	if args.Product == nil || *args.Product == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Product"}
+	}
+	routeValues["product"] = *args.Product
+
+	queryParams := url.Values{}
+	if args.Lcid != nil {
+		queryParams.Add("lcid", strconv.Itoa(*args.Lcid))
+	}
+	if args.Source != nil {
+		queryParams.Add("source", *args.Source)
+	}
+	if args.ProductVersion != nil {
+		queryParams.Add("productVersion", *args.ProductVersion)
+	}
+	if args.Skus != nil {
+		queryParams.Add("skus", *args.Skus)
+	}
+	if args.SubSkus != nil {
+		queryParams.Add("subSkus", *args.SubSkus)
+	}
+	locationId, _ := uuid.Parse("31fba831-35b2-46f6-a641-d05de5a877d8")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ProductCategoriesResult
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetRootCategories function
+type GetRootCategoriesArgs struct {
+	// (required)
+	Product *string
+	// (optional)
+	Lcid *int
+	// (optional)
+	Source *string
+	// (optional)
+	ProductVersion *string
+	// (optional)
+	Skus *string
+	// (optional)
+	SubSkus *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetSigningKey(ctx context.Context, args GetSigningKeyArgs) (*string, error) {
+	routeValues := make(map[string]string)
+	if args.KeyType == nil || *args.KeyType == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.KeyType"}
+	}
+	routeValues["keyType"] = *args.KeyType
+
+	locationId, _ := uuid.Parse("92ed5cf4-c38b-465a-9059-2f2fb7c624b5")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue string
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the GetSigningKey function
+type GetSigningKeyArgs struct {
+	// (required)
+	KeyType *string
+}
+
+// [Preview API]
+func (client *ClientImpl) GetVerificationLog(ctx context.Context, args GetVerificationLogArgs) (io.ReadCloser, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.Version == nil || *args.Version == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Version"}
+	}
+	routeValues["version"] = *args.Version
+
+	queryParams := url.Values{}
+	if args.TargetPlatform != nil {
+		queryParams.Add("targetPlatform", *args.TargetPlatform)
+	}
+	locationId, _ := uuid.Parse("c5523abe-b843-437f-875b-5833064efe4d")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/octet-stream", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Body, err
+}
+
+// Arguments for the GetVerificationLog function
+type GetVerificationLogArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	Version *string
+	// (optional)
+	TargetPlatform *string
+}
+
+// [Preview API] Increments a daily statistic associated with the extension
+func (client *ClientImpl) IncrementExtensionDailyStat(ctx context.Context, args IncrementExtensionDailyStatArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.Version == nil || *args.Version == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Version"}
+	}
+	routeValues["version"] = *args.Version
+
+	queryParams := url.Values{}
+	if args.StatType == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "statType"}
+	}
+	queryParams.Add("statType", *args.StatType)
+	if args.TargetPlatform != nil {
+		queryParams.Add("targetPlatform", *args.TargetPlatform)
+	}
+	locationId, _ := uuid.Parse("4fa7adb6-ca65-4075-a232-5f28323288ea")
+	_, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the IncrementExtensionDailyStat function
+type IncrementExtensionDailyStatArgs struct {
+	// (required) Name of the publisher
+	PublisherName *string
+	// (required) Name of the extension
+	ExtensionName *string
+	// (required) Version of the extension
+	Version *string
+	// (required) Type of stat to increment
+	StatType *string
+	// (optional)
+	TargetPlatform *string
+}
+
+// [Preview API]
+func (client *ClientImpl) PerformEditExtensionDraftOperation(ctx context.Context, args PerformEditExtensionDraftOperationArgs) (*ExtensionDraft, error) {
+	if args.DraftPatch == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.DraftPatch"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.DraftId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.DraftId"}
+	}
+	routeValues["draftId"] = (*args.DraftId).String()
+
+	body, marshalErr := json.Marshal(*args.DraftPatch)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("02b33873-4e61-496e-83a2-59d1df46b7d8")
+	resp, err := client.Client.Send(ctx, http.MethodPatch, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionDraft
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the PerformEditExtensionDraftOperation function
+type PerformEditExtensionDraftOperationArgs struct {
+	// (required)
+	DraftPatch *ExtensionDraftPatch
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	DraftId *uuid.UUID
+}
+
+// [Preview API]
+func (client *ClientImpl) PerformNewExtensionDraftOperation(ctx context.Context, args PerformNewExtensionDraftOperationArgs) (*ExtensionDraft, error) {
+	if args.DraftPatch == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.DraftPatch"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.DraftId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.DraftId"}
+	}
+	routeValues["draftId"] = (*args.DraftId).String()
+
+	body, marshalErr := json.Marshal(*args.DraftPatch)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("b3ab127d-ebb9-4d22-b611-4e09593c8d79")
+	resp, err := client.Client.Send(ctx, http.MethodPatch, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionDraft
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the PerformNewExtensionDraftOperation function
+type PerformNewExtensionDraftOperationArgs struct {
+	// (required)
+	DraftPatch *ExtensionDraftPatch
+	// (required)
+	PublisherName *string
+	// (required)
+	DraftId *uuid.UUID
+}
+
+// [Preview API] API endpoint to publish extension install/uninstall events. This is meant to be invoked by EMS only for sending us data related to install/uninstall of an extension.
+func (client *ClientImpl) PublishExtensionEvents(ctx context.Context, args PublishExtensionEventsArgs) error {
+	if args.ExtensionEvents == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.ExtensionEvents"}
+	}
+	body, marshalErr := json.Marshal(*args.ExtensionEvents)
+	if marshalErr != nil {
+		return marshalErr
+	}
+	locationId, _ := uuid.Parse("0bf2bd3a-70e0-4d5d-8bf7-bd4a9c2ab6e7")
+	_, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the PublishExtensionEvents function
+type PublishExtensionEventsArgs struct {
+	// (required)
+	ExtensionEvents *[]ExtensionEvents
+}
+
+// [Preview API]
+func (client *ClientImpl) QueryAssociatedAzurePublisher(ctx context.Context, args QueryAssociatedAzurePublisherArgs) (*AzurePublisher, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	locationId, _ := uuid.Parse("efd202a6-9d87-4ebc-9229-d2b8ae2fdb6d")
+	resp, err := client.Client.Send(ctx, http.MethodGet, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue AzurePublisher
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the QueryAssociatedAzurePublisher function
+type QueryAssociatedAzurePublisherArgs struct {
+	// (required)
+	PublisherName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) QueryExtensions(ctx context.Context, args QueryExtensionsArgs) (*ExtensionQueryResult, error) {
+	if args.ExtensionQuery == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ExtensionQuery"}
+	}
+	queryParams := url.Values{}
+	if args.AccountToken != nil {
+		queryParams.Add("accountToken", *args.AccountToken)
+	}
+	additionalHeaders := make(map[string]string)
+	if args.AccountTokenHeader != nil {
+		additionalHeaders["X-Market-AccountToken"] = *args.AccountTokenHeader
+	}
+	body, marshalErr := json.Marshal(*args.ExtensionQuery)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("eb9d5ee1-6d43-456b-b80e-8a96fbc014b6")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", nil, queryParams, bytes.NewReader(body), "application/json", "application/json", additionalHeaders)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionQueryResult
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the QueryExtensions function
+type QueryExtensionsArgs struct {
+	// (required)
+	ExtensionQuery *ExtensionQuery
+	// (optional)
+	AccountToken *string
+	// (optional) Header to pass the account token
+	AccountTokenHeader *string
+}
+
+// [Preview API]
+func (client *ClientImpl) QueryPublishers(ctx context.Context, args QueryPublishersArgs) (*PublisherQueryResult, error) {
+	if args.PublisherQuery == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.PublisherQuery"}
+	}
+	body, marshalErr := json.Marshal(*args.PublisherQuery)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("2ad6ee0a-b53f-4034-9d1d-d009fda1212e")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue PublisherQueryResult
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the QueryPublishers function
+type QueryPublishersArgs struct {
+	// (required)
+	PublisherQuery *PublisherQuery
+}
+
+// [Preview API] Flags a concern with an existing question for an extension.
+func (client *ClientImpl) ReportQuestion(ctx context.Context, args ReportQuestionArgs) (*Concern, error) {
+	if args.Concern == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Concern"}
+	}
+	routeValues := make(map[string]string)
+	if args.PubName == nil || *args.PubName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PubName"}
+	}
+	routeValues["pubName"] = *args.PubName
+	if args.ExtName == nil || *args.ExtName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtName"}
+	}
+	routeValues["extName"] = *args.ExtName
+	if args.QuestionId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.QuestionId"}
+	}
+	routeValues["questionId"] = strconv.FormatUint(*args.QuestionId, 10)
+
+	body, marshalErr := json.Marshal(*args.Concern)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("784910cd-254a-494d-898b-0728549b2f10")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue Concern
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the ReportQuestion function
+type ReportQuestionArgs struct {
+	// (required) User reported concern with a question for the extension.
+	Concern *Concern
+	// (required) Name of the publisher who published the extension.
+	PubName *string
+	// (required) Name of the extension.
+	ExtName *string
+	// (required) Identifier of the question to be updated for the extension.
+	QuestionId *uint64
+}
+
+// [Preview API]
+func (client *ClientImpl) RequestAcquisition(ctx context.Context, args RequestAcquisitionArgs) (*ExtensionAcquisitionRequest, error) {
+	if args.AcquisitionRequest == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.AcquisitionRequest"}
+	}
+	body, marshalErr := json.Marshal(*args.AcquisitionRequest)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("3adb1f2d-e328-446e-be73-9f6d98071c45")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionAcquisitionRequest
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the RequestAcquisition function
+type RequestAcquisitionArgs struct {
+	// (required)
+	AcquisitionRequest *ExtensionAcquisitionRequest
+}
+
+// [Preview API] Send Notification
+func (client *ClientImpl) SendNotifications(ctx context.Context, args SendNotificationsArgs) error {
+	if args.NotificationData == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.NotificationData"}
+	}
+	body, marshalErr := json.Marshal(*args.NotificationData)
+	if marshalErr != nil {
+		return marshalErr
+	}
+	locationId, _ := uuid.Parse("eab39817-413c-4602-a49f-07ad00844980")
+	_, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", nil, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the SendNotifications function
+type SendNotificationsArgs struct {
+	// (required) Denoting the data needed to send notification
+	NotificationData *NotificationsData
+}
+
+// [Preview API] Set all setting entries for the given user/all-users scope
+func (client *ClientImpl) SetGalleryUserSettings(ctx context.Context, args SetGalleryUserSettingsArgs) error {
+	if args.Entries == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.Entries"}
+	}
+	routeValues := make(map[string]string)
+	if args.UserScope == nil || *args.UserScope == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.UserScope"}
+	}
+	routeValues["userScope"] = *args.UserScope
+
+	body, marshalErr := json.Marshal(*args.Entries)
+	if marshalErr != nil {
+		return marshalErr
+	}
+	locationId, _ := uuid.Parse("9b75ece3-7960-401c-848b-148ac01ca350")
+	_, err := client.Client.Send(ctx, http.MethodPatch, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the SetGalleryUserSettings function
+type SetGalleryUserSettingsArgs struct {
+	// (required) A key-value pair of all settings that need to be set
+	Entries *map[string]interface{}
+	// (required) User-Scope at which to get the value. Should be "me" for the current user or "host" for all users.
+	UserScope *string
+}
+
+// [Preview API]
+func (client *ClientImpl) ShareExtension(ctx context.Context, args ShareExtensionArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.AccountName == nil || *args.AccountName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AccountName"}
+	}
+	routeValues["accountName"] = *args.AccountName
+
+	locationId, _ := uuid.Parse("a1e66d8f-f5de-4d16-8309-91a4e015ee46")
+	_, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the ShareExtension function
+type ShareExtensionArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	AccountName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) ShareExtensionById(ctx context.Context, args ShareExtensionByIdArgs) error {
+	routeValues := make(map[string]string)
+	if args.ExtensionId == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.ExtensionId"}
+	}
+	routeValues["extensionId"] = (*args.ExtensionId).String()
+	if args.AccountName == nil || *args.AccountName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AccountName"}
+	}
+	routeValues["accountName"] = *args.AccountName
+
+	locationId, _ := uuid.Parse("1f19631b-a0b4-4a03-89c2-d79785d24360")
+	_, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the ShareExtensionById function
+type ShareExtensionByIdArgs struct {
+	// (required)
+	ExtensionId *uuid.UUID
+	// (required)
+	AccountName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) ShareExtensionWithHost(ctx context.Context, args ShareExtensionWithHostArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.HostType == nil || *args.HostType == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.HostType"}
+	}
+	routeValues["hostType"] = *args.HostType
+	if args.HostName == nil || *args.HostName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.HostName"}
+	}
+	routeValues["hostName"] = *args.HostName
+
+	locationId, _ := uuid.Parse("328a3af8-d124-46e9-9483-01690cd415b9")
+	_, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the ShareExtensionWithHost function
+type ShareExtensionWithHostArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	HostType *string
+	// (required)
+	HostName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) UnshareExtension(ctx context.Context, args UnshareExtensionArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.AccountName == nil || *args.AccountName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AccountName"}
+	}
+	routeValues["accountName"] = *args.AccountName
+
+	locationId, _ := uuid.Parse("a1e66d8f-f5de-4d16-8309-91a4e015ee46")
+	_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the UnshareExtension function
+type UnshareExtensionArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	AccountName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) UnshareExtensionById(ctx context.Context, args UnshareExtensionByIdArgs) error {
+	routeValues := make(map[string]string)
+	if args.ExtensionId == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.ExtensionId"}
+	}
+	routeValues["extensionId"] = (*args.ExtensionId).String()
+	if args.AccountName == nil || *args.AccountName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.AccountName"}
+	}
+	routeValues["accountName"] = *args.AccountName
+
+	locationId, _ := uuid.Parse("1f19631b-a0b4-4a03-89c2-d79785d24360")
+	_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the UnshareExtensionById function
+type UnshareExtensionByIdArgs struct {
+	// (required)
+	ExtensionId *uuid.UUID
+	// (required)
+	AccountName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) UnshareExtensionWithHost(ctx context.Context, args UnshareExtensionWithHostArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.HostType == nil || *args.HostType == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.HostType"}
+	}
+	routeValues["hostType"] = *args.HostType
+	if args.HostName == nil || *args.HostName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.HostName"}
+	}
+	routeValues["hostName"] = *args.HostName
+
+	locationId, _ := uuid.Parse("328a3af8-d124-46e9-9483-01690cd415b9")
+	_, err := client.Client.Send(ctx, http.MethodDelete, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the UnshareExtensionWithHost function
+type UnshareExtensionWithHostArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	HostType *string
+	// (required)
+	HostName *string
+}
+
+// [Preview API] REST endpoint to update an extension.
+func (client *ClientImpl) UpdateExtension(ctx context.Context, args UpdateExtensionArgs) (*PublishedExtension, error) {
+	if args.UploadStream == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.UploadStream"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	queryParams := url.Values{}
+	if args.ExtensionType != nil {
+		queryParams.Add("extensionType", *args.ExtensionType)
+	}
+	if args.ReCaptchaToken != nil {
+		queryParams.Add("reCaptchaToken", *args.ReCaptchaToken)
+	}
+	if args.BypassScopeCheck != nil {
+		queryParams.Add("bypassScopeCheck", strconv.FormatBool(*args.BypassScopeCheck))
+	}
+	locationId, _ := uuid.Parse("e11ea35a-16fe-4b80-ab11-c4cab88a0966")
+	resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "7.1-preview.2", routeValues, queryParams, args.UploadStream, "application/octet-stream", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue PublishedExtension
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdateExtension function
+type UpdateExtensionArgs struct {
+	// (required) Stream to upload
+	UploadStream io.Reader
+	// (required) Name of the publisher
+	PublisherName *string
+	// (required) Name of the extension
+	ExtensionName *string
+	// (optional)
+	ExtensionType *string
+	// (optional)
+	ReCaptchaToken *string
+	// (optional) This parameter decides if the scope change check needs to be invoked or not
+	BypassScopeCheck *bool
+}
+
+// [Preview API]
+func (client *ClientImpl) UpdateExtensionById(ctx context.Context, args UpdateExtensionByIdArgs) (*PublishedExtension, error) {
+	routeValues := make(map[string]string)
+	if args.ExtensionId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ExtensionId"}
+	}
+	routeValues["extensionId"] = (*args.ExtensionId).String()
+
+	queryParams := url.Values{}
+	if args.ReCaptchaToken != nil {
+		queryParams.Add("reCaptchaToken", *args.ReCaptchaToken)
+	}
+	locationId, _ := uuid.Parse("a41192c8-9525-4b58-bc86-179fa549d80d")
+	resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "7.1-preview.2", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue PublishedExtension
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdateExtensionById function
+type UpdateExtensionByIdArgs struct {
+	// (required)
+	ExtensionId *uuid.UUID
+	// (optional)
+	ReCaptchaToken *string
+}
+
+// [Preview API]
+func (client *ClientImpl) UpdateExtensionProperties(ctx context.Context, args UpdateExtensionPropertiesArgs) (*PublishedExtension, error) {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	queryParams := url.Values{}
+	if args.Flags == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "flags"}
+	}
+	queryParams.Add("flags", string(*args.Flags))
+	locationId, _ := uuid.Parse("e11ea35a-16fe-4b80-ab11-c4cab88a0966")
+	resp, err := client.Client.Send(ctx, http.MethodPatch, locationId, "7.1-preview.2", routeValues, queryParams, nil, "", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue PublishedExtension
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdateExtensionProperties function
+type UpdateExtensionPropertiesArgs struct {
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	Flags *PublishedExtensionFlags
+}
+
+// [Preview API]
+func (client *ClientImpl) UpdateExtensionStatistics(ctx context.Context, args UpdateExtensionStatisticsArgs) error {
+	if args.ExtensionStatisticsUpdate == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.ExtensionStatisticsUpdate"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+
+	body, marshalErr := json.Marshal(*args.ExtensionStatisticsUpdate)
+	if marshalErr != nil {
+		return marshalErr
+	}
+	locationId, _ := uuid.Parse("a0ea3204-11e9-422d-a9ca-45851cc41400")
+	_, err := client.Client.Send(ctx, http.MethodPatch, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the UpdateExtensionStatistics function
+type UpdateExtensionStatisticsArgs struct {
+	// (required)
+	ExtensionStatisticsUpdate *ExtensionStatisticUpdate
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) UpdatePayloadInDraftForEditExtension(ctx context.Context, args UpdatePayloadInDraftForEditExtensionArgs) (*ExtensionDraft, error) {
+	if args.UploadStream == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.UploadStream"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.DraftId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.DraftId"}
+	}
+	routeValues["draftId"] = (*args.DraftId).String()
+
+	additionalHeaders := make(map[string]string)
+	if args.FileName != nil {
+		additionalHeaders["X-Market-UploadFileName"] = *args.FileName
+	}
+	locationId, _ := uuid.Parse("02b33873-4e61-496e-83a2-59d1df46b7d8")
+	resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "7.1-preview.1", routeValues, nil, args.UploadStream, "application/octet-stream", "application/json", additionalHeaders)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionDraft
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdatePayloadInDraftForEditExtension function
+type UpdatePayloadInDraftForEditExtensionArgs struct {
+	// (required) Stream to upload
+	UploadStream io.Reader
+	// (required)
+	PublisherName *string
+	// (required)
+	ExtensionName *string
+	// (required)
+	DraftId *uuid.UUID
+	// (optional) Header to pass the filename of the uploaded data
+	FileName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) UpdatePayloadInDraftForNewExtension(ctx context.Context, args UpdatePayloadInDraftForNewExtensionArgs) (*ExtensionDraft, error) {
+	if args.UploadStream == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.UploadStream"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.DraftId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.DraftId"}
+	}
+	routeValues["draftId"] = (*args.DraftId).String()
+
+	additionalHeaders := make(map[string]string)
+	if args.FileName != nil {
+		additionalHeaders["X-Market-UploadFileName"] = *args.FileName
+	}
+	locationId, _ := uuid.Parse("b3ab127d-ebb9-4d22-b611-4e09593c8d79")
+	resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "7.1-preview.1", routeValues, nil, args.UploadStream, "application/octet-stream", "application/json", additionalHeaders)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ExtensionDraft
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdatePayloadInDraftForNewExtension function
+type UpdatePayloadInDraftForNewExtensionArgs struct {
+	// (required) Stream to upload
+	UploadStream io.Reader
+	// (required)
+	PublisherName *string
+	// (required)
+	DraftId *uuid.UUID
+	// (optional) Header to pass the filename of the uploaded data
+	FileName *string
+}
+
+// [Preview API]
+func (client *ClientImpl) UpdatePublisher(ctx context.Context, args UpdatePublisherArgs) (*Publisher, error) {
+	if args.Publisher == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Publisher"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	body, marshalErr := json.Marshal(*args.Publisher)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("4ddec66a-e4f6-4f5d-999e-9e77710d7ff4")
+	resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue Publisher
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdatePublisher function
+type UpdatePublisherArgs struct {
+	// (required)
+	Publisher *Publisher
+	// (required)
+	PublisherName *string
+}
+
+// [Preview API] Update publisher asset like logo. It accepts asset file as an octet stream and file name is passed in header values.
+func (client *ClientImpl) UpdatePublisherAsset(ctx context.Context, args UpdatePublisherAssetArgs) (*map[string]string, error) {
+	if args.UploadStream == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.UploadStream"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	queryParams := url.Values{}
+	if args.AssetType != nil {
+		queryParams.Add("assetType", *args.AssetType)
+	}
+	additionalHeaders := make(map[string]string)
+	if args.FileName != nil {
+		additionalHeaders["X-Market-UploadFileName"] = *args.FileName
+	}
+	locationId, _ := uuid.Parse("21143299-34f9-4c62-8ca8-53da691192f9")
+	resp, err := client.Client.Send(ctx, http.MethodPut, locationId, "7.1-preview.1", routeValues, queryParams, args.UploadStream, "application/octet-stream", "application/json", additionalHeaders)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue map[string]string
+	err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdatePublisherAsset function
+type UpdatePublisherAssetArgs struct {
+	// (required) Stream to upload
+	UploadStream io.Reader
+	// (required) Internal name of the publisher
+	PublisherName *string
+	// (optional) Type of asset. Default value is 'logo'.
+	AssetType *string
+	// (optional) Header to pass the filename of the uploaded data
+	FileName *string
+}
+
+// [Preview API] Endpoint to add/modify publisher membership. Currently Supports only addition/modification of 1 user at a time Works only for adding members of same tenant.
+func (client *ClientImpl) UpdatePublisherMembers(ctx context.Context, args UpdatePublisherMembersArgs) (*[]PublisherRoleAssignment, error) {
+	if args.RoleAssignments == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.RoleAssignments"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	queryParams := url.Values{}
+	if args.LimitToCallerIdentityDomain != nil {
+		queryParams.Add("limitToCallerIdentityDomain", strconv.FormatBool(*args.LimitToCallerIdentityDomain))
+	}
+	body, marshalErr := json.Marshal(*args.RoleAssignments)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("4ddec66a-e4f6-4f5d-999e-9e77710d7ff4")
+	resp, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, queryParams, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue []PublisherRoleAssignment
+	err = client.Client.UnmarshalCollectionBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdatePublisherMembers function
+type UpdatePublisherMembersArgs struct {
+	// (required) List of user identifiers(email address) and role to be added. Currently only one entry is supported.
+	RoleAssignments *[]PublisherUserRoleAssignmentRef
+	// (required) The name/id of publisher to which users have to be added
+	PublisherName *string
+	// (optional) Should cross tenant addtions be allowed or not.
+	LimitToCallerIdentityDomain *bool
+}
+
+// [Preview API] Updates an existing question for an extension.
+func (client *ClientImpl) UpdateQuestion(ctx context.Context, args UpdateQuestionArgs) (*Question, error) {
+	if args.Question == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Question"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.QuestionId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.QuestionId"}
+	}
+	routeValues["questionId"] = strconv.FormatUint(*args.QuestionId, 10)
+
+	body, marshalErr := json.Marshal(*args.Question)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("6d1d9741-eca8-4701-a3a5-235afc82dfa4")
+	resp, err := client.Client.Send(ctx, http.MethodPatch, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue Question
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdateQuestion function
+type UpdateQuestionArgs struct {
+	// (required) Updated question to be set for the extension.
+	Question *Question
+	// (required) Name of the publisher who published the extension.
+	PublisherName *string
+	// (required) Name of the extension.
+	ExtensionName *string
+	// (required) Identifier of the question to be updated for the extension.
+	QuestionId *uint64
+}
+
+// [Preview API] Updates an existing response for a given question for an extension.
+func (client *ClientImpl) UpdateResponse(ctx context.Context, args UpdateResponseArgs) (*Response, error) {
+	if args.Response == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.Response"}
+	}
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+	if args.ExtensionName == nil || *args.ExtensionName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtensionName"}
+	}
+	routeValues["extensionName"] = *args.ExtensionName
+	if args.QuestionId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.QuestionId"}
+	}
+	routeValues["questionId"] = strconv.FormatUint(*args.QuestionId, 10)
+	if args.ResponseId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ResponseId"}
+	}
+	routeValues["responseId"] = strconv.FormatUint(*args.ResponseId, 10)
+
+	body, marshalErr := json.Marshal(*args.Response)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("7f8ae5e0-46b0-438f-b2e8-13e8513517bd")
+	resp, err := client.Client.Send(ctx, http.MethodPatch, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue Response
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdateResponse function
+type UpdateResponseArgs struct {
+	// (required) Updated response to be set for the extension.
+	Response *Response
+	// (required) Name of the publisher who published the extension.
+	PublisherName *string
+	// (required) Name of the extension.
+	ExtensionName *string
+	// (required) Identifier of the question for which response is to be updated for the extension.
+	QuestionId *uint64
+	// (required) Identifier of the response which has to be updated.
+	ResponseId *uint64
+}
+
+// [Preview API] Updates or Flags a review
+func (client *ClientImpl) UpdateReview(ctx context.Context, args UpdateReviewArgs) (*ReviewPatch, error) {
+	if args.ReviewPatch == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ReviewPatch"}
+	}
+	routeValues := make(map[string]string)
+	if args.PubName == nil || *args.PubName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PubName"}
+	}
+	routeValues["pubName"] = *args.PubName
+	if args.ExtName == nil || *args.ExtName == "" {
+		return nil, &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ExtName"}
+	}
+	routeValues["extName"] = *args.ExtName
+	if args.ReviewId == nil {
+		return nil, &azuredevops.ArgumentNilError{ArgumentName: "args.ReviewId"}
+	}
+	routeValues["reviewId"] = strconv.FormatUint(*args.ReviewId, 10)
+
+	body, marshalErr := json.Marshal(*args.ReviewPatch)
+	if marshalErr != nil {
+		return nil, marshalErr
+	}
+	locationId, _ := uuid.Parse("e6e85b9d-aa70-40e6-aa28-d0fbf40b91a3")
+	resp, err := client.Client.Send(ctx, http.MethodPatch, locationId, "7.1-preview.1", routeValues, nil, bytes.NewReader(body), "application/json", "application/json", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	var responseValue ReviewPatch
+	err = client.Client.UnmarshalBody(resp, &responseValue)
+	return &responseValue, err
+}
+
+// Arguments for the UpdateReview function
+type UpdateReviewArgs struct {
+	// (required) ReviewPatch object which contains the changes to be applied to the review
+	ReviewPatch *ReviewPatch
+	// (required) Name of the publisher who published the extension
+	PubName *string
+	// (required) Name of the extension
+	ExtName *string
+	// (required) Id of the review which needs to be updated
+	ReviewId *uint64
+}
+
+// [Preview API]
+func (client *ClientImpl) UpdateVSCodeWebExtensionStatistics(ctx context.Context, args UpdateVSCodeWebExtensionStatisticsArgs) error {
+	routeValues := make(map[string]string)
+	if args.ItemName == nil || *args.ItemName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.ItemName"}
+	}
+	routeValues["itemName"] = *args.ItemName
+	if args.Version == nil || *args.Version == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.Version"}
+	}
+	routeValues["version"] = *args.Version
+	if args.StatType == nil {
+		return &azuredevops.ArgumentNilError{ArgumentName: "args.StatType"}
+	}
+	routeValues["statType"] = string(*args.StatType)
+
+	locationId, _ := uuid.Parse("205c91a8-7841-4fd3-ae4f-5a745d5a8df5")
+	_, err := client.Client.Send(ctx, http.MethodPost, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the UpdateVSCodeWebExtensionStatistics function
+type UpdateVSCodeWebExtensionStatisticsArgs struct {
+	// (required)
+	ItemName *string
+	// (required)
+	Version *string
+	// (required)
+	StatType *VSCodeWebExtensionStatisicsType
+}
+
+// [Preview API]
+func (client *ClientImpl) VerifyDomainToken(ctx context.Context, args VerifyDomainTokenArgs) error {
+	routeValues := make(map[string]string)
+	if args.PublisherName == nil || *args.PublisherName == "" {
+		return &azuredevops.ArgumentNilOrEmptyError{ArgumentName: "args.PublisherName"}
+	}
+	routeValues["publisherName"] = *args.PublisherName
+
+	locationId, _ := uuid.Parse("67a609ef-fa74-4b52-8664-78d76f7b3634")
+	_, err := client.Client.Send(ctx, http.MethodPut, locationId, "7.1-preview.1", routeValues, nil, nil, "", "application/json", nil)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Arguments for the VerifyDomainToken function
+type VerifyDomainTokenArgs struct {
+	// (required)
+	PublisherName *string
+}
diff --git a/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/gallery/models.go b/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/gallery/models.go
new file mode 100644
index 00000000..b2793a38
--- /dev/null
+++ b/vendor/github.com/microsoft/azure-devops-go-api/azuredevops/v7/gallery/models.go
@@ -0,0 +1,1598 @@
+// --------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+// --------------------------------------------------------------------------------------------
+// Generated file, DO NOT EDIT
+// Changes may cause incorrect behavior and will be lost if the code is regenerated.
+// --------------------------------------------------------------------------------------------
+
+package gallery
+
+import (
+	"github.com/google/uuid"
+	"github.com/microsoft/azure-devops-go-api/azuredevops/v7"
+	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/webapi"
+)
+
+// How the acquisition is assigned
+type AcquisitionAssignmentType string
+
+type acquisitionAssignmentTypeValuesType struct {
+	None AcquisitionAssignmentType
+	Me   AcquisitionAssignmentType
+	All  AcquisitionAssignmentType
+}
+
+var AcquisitionAssignmentTypeValues = acquisitionAssignmentTypeValuesType{
+	None: "none",
+	// Just assign for me
+	Me: "me",
+	// Assign for all users in the account
+	All: "all",
+}
+
+type AcquisitionOperation struct {
+	// State of the AcquisitionOperation for the current user
+	OperationState *AcquisitionOperationState `json:"operationState,omitempty"`
+	// AcquisitionOperationType: install, request, buy, etc...
+	OperationType *AcquisitionOperationType `json:"operationType,omitempty"`
+	// Optional reason to justify current state. Typically used with Disallow state.
+	Reason *string `json:"reason,omitempty"`
+}
+
+type AcquisitionOperationState string
+
+type acquisitionOperationStateValuesType struct {
+	Disallow  AcquisitionOperationState
+	Allow     AcquisitionOperationState
+	Completed AcquisitionOperationState
+}
+
+var AcquisitionOperationStateValues = acquisitionOperationStateValuesType{
+	// Not allowed to use this AcquisitionOperation
+	Disallow: "disallow",
+	// Allowed to use this AcquisitionOperation
+	Allow: "allow",
+	// Operation has already been completed and is no longer available
+	Completed: "completed",
+}
+
+// Set of different types of operations that can be requested.
+type AcquisitionOperationType string
+
+type acquisitionOperationTypeValuesType struct {
+	Get             AcquisitionOperationType
+	Install         AcquisitionOperationType
+	Buy             AcquisitionOperationType
+	Try             AcquisitionOperationType
+	Request         AcquisitionOperationType
+	None            AcquisitionOperationType
+	PurchaseRequest AcquisitionOperationType
+}
+
+var AcquisitionOperationTypeValues = acquisitionOperationTypeValuesType{
+	// Not yet used
+	Get: "get",
+	// Install this extension into the host provided
+	Install: "install",
+	// Buy licenses for this extension and install into the host provided
+	Buy: "buy",
+	// Try this extension
+	Try: "try",
+	// Request this extension for installation
+	Request: "request",
+	// No action found
+	None: "none",
+	// Request admins for purchasing extension
+	PurchaseRequest: "purchaseRequest",
+}
+
+// Market item acquisition options (install, buy, etc) for an installation target.
+type AcquisitionOptions struct {
+	// Default Operation for the ItemId in this target
+	DefaultOperation *AcquisitionOperation `json:"defaultOperation,omitempty"`
+	// The item id that this options refer to
+	ItemId *string `json:"itemId,omitempty"`
+	// Operations allowed for the ItemId in this target
+	Operations *[]AcquisitionOperation `json:"operations,omitempty"`
+	// The target that this options refer to
+	Target *string `json:"target,omitempty"`
+}
+
+type Answers struct {
+	// Gets or sets the vs marketplace extension name
+	VsMarketplaceExtensionName *string `json:"vsMarketplaceExtensionName,omitempty"`
+	// Gets or sets the vs marketplace publisher name
+	VsMarketplacePublisherName *string `json:"vsMarketplacePublisherName,omitempty"`
+}
+
+type AssetDetails struct {
+	// Gets or sets the Answers, which contains vs marketplace extension name and publisher name
+	Answers *Answers `json:"answers,omitempty"`
+	// Gets or sets the VS publisher Id
+	PublisherNaturalIdentifier *string `json:"publisherNaturalIdentifier,omitempty"`
+}
+
+type AzurePublisher struct {
+	AzurePublisherId *string `json:"azurePublisherId,omitempty"`
+	PublisherName    *string `json:"publisherName,omitempty"`
+}
+
+type AzureRestApiRequestModel struct {
+	// Gets or sets the Asset details
+	AssetDetails *AssetDetails `json:"assetDetails,omitempty"`
+	// Gets or sets the asset id
+	AssetId *string `json:"assetId,omitempty"`
+	// Gets or sets the asset version
+	AssetVersion *uint64 `json:"assetVersion,omitempty"`
+	// Gets or sets the customer support email
+	CustomerSupportEmail *string `json:"customerSupportEmail,omitempty"`
+	// Gets or sets the integration contact email
+	IntegrationContactEmail *string `json:"integrationContactEmail,omitempty"`
+	// Gets or sets the asset version
+	Operation *string `json:"operation,omitempty"`
+	// Gets or sets the plan identifier if any.
+	PlanId *string `json:"planId,omitempty"`
+	// Gets or sets the publisher id
+	PublisherId *string `json:"publisherId,omitempty"`
+	// Gets or sets the resource type
+	Type *string `json:"type,omitempty"`
+}
+
+type AzureRestApiResponseModel struct {
+	// Gets or sets the Asset details
+	AssetDetails *AssetDetails `json:"assetDetails,omitempty"`
+	// Gets or sets the asset id
+	AssetId *string `json:"assetId,omitempty"`
+	// Gets or sets the asset version
+	AssetVersion *uint64 `json:"assetVersion,omitempty"`
+	// Gets or sets the customer support email
+	CustomerSupportEmail *string `json:"customerSupportEmail,omitempty"`
+	// Gets or sets the integration contact email
+	IntegrationContactEmail *string `json:"integrationContactEmail,omitempty"`
+	// Gets or sets the asset version
+	Operation *string `json:"operation,omitempty"`
+	// Gets or sets the plan identifier if any.
+	PlanId *string `json:"planId,omitempty"`
+	// Gets or sets the publisher id
+	PublisherId *string `json:"publisherId,omitempty"`
+	// Gets or sets the resource type
+	Type *string `json:"type,omitempty"`
+	// Gets or sets the Asset operation status
+	OperationStatus *RestApiResponseStatusModel `json:"operationStatus,omitempty"`
+}
+
+// This is the set of categories in response to the get category query
+type CategoriesResult struct {
+	Categories *[]ExtensionCategory `json:"categories,omitempty"`
+}
+
+// Definition of one title of a category
+type CategoryLanguageTitle struct {
+	// The language for which the title is applicable
+	Lang *string `json:"lang,omitempty"`
+	// The language culture id of the lang parameter
+	Lcid *int `json:"lcid,omitempty"`
+	// Actual title to be shown on the UI
+	Title *string `json:"title,omitempty"`
+}
+
+// The structure of a Concern Rather than defining a separate data structure having same fields as QnAItem, we are inheriting from the QnAItem.
+type Concern struct {
+	// Time when the review was first created
+	CreatedDate *azuredevops.Time `json:"createdDate,omitempty"`
+	// Unique identifier of a QnA item
+	Id *uint64 `json:"id,omitempty"`
+	// Get status of item
+	Status *QnAItemStatus `json:"status,omitempty"`
+	// Text description of the QnA item
+	Text *string `json:"text,omitempty"`
+	// Time when the review was edited/updated
+	UpdatedDate *azuredevops.Time `json:"updatedDate,omitempty"`
+	// User details for the item.
+	User *UserIdentityRef `json:"user,omitempty"`
+	// Category of the concern
+	Category *ConcernCategory `json:"category,omitempty"`
+}
+
+type ConcernCategory string
+
+type concernCategoryValuesType struct {
+	General ConcernCategory
+	Abusive ConcernCategory
+	Spam    ConcernCategory
+}
+
+var ConcernCategoryValues = concernCategoryValuesType{
+	General: "general",
+	Abusive: "abusive",
+	Spam:    "spam",
+}
+
+// Stores Last Contact Date
+type CustomerLastContact struct {
+	// account for which customer was last contacted
+	Account *string `json:"account,omitempty"`
+	// Date on which the customer was last contacted
+	LastContactDate *azuredevops.Time `json:"lastContactDate,omitempty"`
+}
+
+// An entity representing the data required to create a Customer Support Request.
+type CustomerSupportRequest struct {
+	// Display name of extension in concern
+	DisplayName *string `json:"displayName,omitempty"`
+	// Email of user making the support request
+	EmailId *string `json:"emailId,omitempty"`
+	// Extension name
+	ExtensionName *string `json:"extensionName,omitempty"`
+	// Link to the extension details page
+	ExtensionURL *string `json:"extensionURL,omitempty"`
+	// User-provided support request message.
+	Message *string `json:"message,omitempty"`
+	// Publisher name
+	PublisherName *string `json:"publisherName,omitempty"`
+	// Reason for support request
+	Reason         *string `json:"reason,omitempty"`
+	ReCaptchaToken *string `json:"reCaptchaToken,omitempty"`
+	// VSID of the user making the support request
+	ReporterVSID *string `json:"reporterVSID,omitempty"`
+	// Review under concern
+	Review *Review `json:"review,omitempty"`
+	// The UI source through which the request was made
+	SourceLink *string `json:"sourceLink,omitempty"`
+}
+
+type DraftPatchOperation string
+
+type draftPatchOperationValuesType struct {
+	Publish DraftPatchOperation
+	Cancel  DraftPatchOperation
+}
+
+var DraftPatchOperationValues = draftPatchOperationValuesType{
+	Publish: "publish",
+	Cancel:  "cancel",
+}
+
+type DraftStateType string
+
+type draftStateTypeValuesType struct {
+	Unpublished DraftStateType
+	Published   DraftStateType
+	Cancelled   DraftStateType
+	Error       DraftStateType
+}
+
+var DraftStateTypeValues = draftStateTypeValuesType{
+	Unpublished: "unpublished",
+	Published:   "published",
+	Cancelled:   "cancelled",
+	Error:       "error",
+}
+
+type EventCounts struct {
+	// Average rating on the day for extension
+	AverageRating *float32 `json:"averageRating,omitempty"`
+	// Number of times the extension was bought in hosted scenario (applies only to VSTS extensions)
+	BuyCount *int `json:"buyCount,omitempty"`
+	// Number of times the extension was bought in connected scenario (applies only to VSTS extensions)
+	ConnectedBuyCount *int `json:"connectedBuyCount,omitempty"`
+	// Number of times the extension was installed in connected scenario (applies only to VSTS extensions)
+	ConnectedInstallCount *int `json:"connectedInstallCount,omitempty"`
+	// Number of times the extension was installed
+	InstallCount *uint64 `json:"installCount,omitempty"`
+	// Number of times the extension was installed as a trial (applies only to VSTS extensions)
+	TryCount *int `json:"tryCount,omitempty"`
+	// Number of times the extension was uninstalled (applies only to VSTS extensions)
+	UninstallCount *int `json:"uninstallCount,omitempty"`
+	// Number of times the extension was downloaded (applies to VSTS extensions and VSCode marketplace click installs)
+	WebDownloadCount *uint64 `json:"webDownloadCount,omitempty"`
+	// Number of detail page views
+	WebPageViews *uint64 `json:"webPageViews,omitempty"`
+}
+
+// Contract for handling the extension acquisition process
+type ExtensionAcquisitionRequest struct {
+	// How the item is being assigned
+	AssignmentType *AcquisitionAssignmentType `json:"assignmentType,omitempty"`
+	// The id of the subscription used for purchase
+	BillingId *string `json:"billingId,omitempty"`
+	// The marketplace id (publisherName.extensionName) for the item
+	ItemId *string `json:"itemId,omitempty"`
+	// The type of operation, such as install, request, purchase
+	OperationType *AcquisitionOperationType `json:"operationType,omitempty"`
+	// Additional properties which can be added to the request.
+	Properties interface{} `json:"properties,omitempty"`
+	// How many licenses should be purchased
+	Quantity *int `json:"quantity,omitempty"`
+	// A list of target guids where the item should be acquired (installed, requested, etc.), such as account id
+	Targets *[]string `json:"targets,omitempty"`
+}
+
+type ExtensionBadge struct {
+	Description *string `json:"description,omitempty"`
+	ImgUri      *string `json:"imgUri,omitempty"`
+	Link        *string `json:"link,omitempty"`
+}
+
+type ExtensionCategory struct {
+	// The name of the products with which this category is associated to.
+	AssociatedProducts *[]string `json:"associatedProducts,omitempty"`
+	CategoryId         *int      `json:"categoryId,omitempty"`
+	// This is the internal name for a category
+	CategoryName *string `json:"categoryName,omitempty"`
+	// This parameter is obsolete. Refer to LanguageTitles for language specific titles
+	Language *string `json:"language,omitempty"`
+	// The list of all the titles of this category in various languages
+	LanguageTitles *[]CategoryLanguageTitle `json:"languageTitles,omitempty"`
+	// This is the internal name of the parent if this is associated with a parent
+	ParentCategoryName *string `json:"parentCategoryName,omitempty"`
+}
+
+type ExtensionDailyStat struct {
+	// Stores the event counts
+	Counts *EventCounts `json:"counts,omitempty"`
+	// Generic key/value pair to store extended statistics. Used for sending paid extension stats like Upgrade, Downgrade, Cancel trend etc.
+	ExtendedStats *map[string]interface{} `json:"extendedStats,omitempty"`
+	// Timestamp of this data point
+	StatisticDate *azuredevops.Time `json:"statisticDate,omitempty"`
+	// Version of the extension
+	Version *string `json:"version,omitempty"`
+}
+
+type ExtensionDailyStats struct {
+	// List of extension statistics data points
+	DailyStats *[]ExtensionDailyStat `json:"dailyStats,omitempty"`
+	// Id of the extension, this will never be sent back to the client. For internal use only.
+	ExtensionId *uuid.UUID `json:"extensionId,omitempty"`
+	// Name of the extension
+	ExtensionName *string `json:"extensionName,omitempty"`
+	// Name of the publisher
+	PublisherName *string `json:"publisherName,omitempty"`
+	// Count of stats
+	StatCount *int `json:"statCount,omitempty"`
+}
+
+type ExtensionDeploymentTechnology string
+
+type extensionDeploymentTechnologyValuesType struct {
+	Exe          ExtensionDeploymentTechnology
+	Msi          ExtensionDeploymentTechnology
+	Vsix         ExtensionDeploymentTechnology
+	ReferralLink ExtensionDeploymentTechnology
+}
+
+var ExtensionDeploymentTechnologyValues = extensionDeploymentTechnologyValuesType{
+	Exe:          "exe",
+	Msi:          "msi",
+	Vsix:         "vsix",
+	ReferralLink: "referralLink",
+}
+
+type ExtensionDraft struct {
+	Assets             *[]ExtensionDraftAsset      `json:"assets,omitempty"`
+	CreatedDate        *azuredevops.Time           `json:"createdDate,omitempty"`
+	DraftState         *DraftStateType             `json:"draftState,omitempty"`
+	ExtensionName      *string                     `json:"extensionName,omitempty"`
+	Id                 *uuid.UUID                  `json:"id,omitempty"`
+	LastUpdated        *azuredevops.Time           `json:"lastUpdated,omitempty"`
+	Payload            *ExtensionPayload           `json:"payload,omitempty"`
+	Product            *string                     `json:"product,omitempty"`
+	PublisherName      *string                     `json:"publisherName,omitempty"`
+	ValidationErrors   *[]azuredevops.KeyValuePair `json:"validationErrors,omitempty"`
+	ValidationWarnings *[]azuredevops.KeyValuePair `json:"validationWarnings,omitempty"`
+}
+
+type ExtensionDraftAsset struct {
+	AssetType *string `json:"assetType,omitempty"`
+	Language  *string `json:"language,omitempty"`
+	Source    *string `json:"source,omitempty"`
+}
+
+type ExtensionDraftPatch struct {
+	ExtensionData  *UnpackagedExtensionData `json:"extensionData,omitempty"`
+	Operation      *DraftPatchOperation     `json:"operation,omitempty"`
+	ReCaptchaToken *string                  `json:"reCaptchaToken,omitempty"`
+}
+
+// Stores details of each event
+type ExtensionEvent struct {
+	// Id which identifies each data point uniquely
+	Id         *uint64     `json:"id,omitempty"`
+	Properties interface{} `json:"properties,omitempty"`
+	// Timestamp of when the event occurred
+	StatisticDate *azuredevops.Time `json:"statisticDate,omitempty"`
+	// Version of the extension
+	Version *string `json:"version,omitempty"`
+}
+
+// Container object for all extension events. Stores all install and uninstall events related to an extension. The events container is generic so can store data of any type of event. New event types can be added without altering the contract.
+type ExtensionEvents struct {
+	// Generic container for events data. The dictionary key denotes the type of event and the list contains properties related to that event
+	Events *map[string][]ExtensionEvent `json:"events,omitempty"`
+	// Id of the extension, this will never be sent back to the client. This field will mainly be used when EMS calls into Gallery REST API to update install/uninstall events for various extensions in one go.
+	ExtensionId *uuid.UUID `json:"extensionId,omitempty"`
+	// Name of the extension
+	ExtensionName *string `json:"extensionName,omitempty"`
+	// Name of the publisher
+	PublisherName *string `json:"publisherName,omitempty"`
+}
+
+type ExtensionFile struct {
+	AssetType *string `json:"assetType,omitempty"`
+	Language  *string `json:"language,omitempty"`
+	Source    *string `json:"source,omitempty"`
+}
+
+// The FilterResult is the set of extensions that matched a particular query filter.
+type ExtensionFilterResult struct {
+	// This is the set of applications that matched the query filter supplied.
+	Extensions *[]PublishedExtension `json:"extensions,omitempty"`
+	// The PagingToken is returned from a request when more records exist that match the result than were requested or could be returned. A follow-up query with this paging token can be used to retrieve more results.
+	PagingToken *string `json:"pagingToken,omitempty"`
+	// This is the additional optional metadata for the given result. E.g. Total count of results which is useful in case of paged results
+	ResultMetadata *[]ExtensionFilterResultMetadata `json:"resultMetadata,omitempty"`
+}
+
+// ExtensionFilterResultMetadata is one set of metadata for the result e.g. Total count. There can be multiple metadata items for one metadata.
+type ExtensionFilterResultMetadata struct {
+	// The metadata items for the category
+	MetadataItems *[]MetadataItem `json:"metadataItems,omitempty"`
+	// Defines the category of metadata items
+	MetadataType *string `json:"metadataType,omitempty"`
+}
+
+// Represents the component pieces of an extensions fully qualified name, along with the fully qualified name.
+type ExtensionIdentifier struct {
+	// The ExtensionName component part of the fully qualified ExtensionIdentifier
+	ExtensionName *string `json:"extensionName,omitempty"`
+	// The PublisherName component part of the fully qualified ExtensionIdentifier
+	PublisherName *string `json:"publisherName,omitempty"`
+}
+
+// Type of event
+type ExtensionLifecycleEventType string
+
+type extensionLifecycleEventTypeValuesType struct {
+	Uninstall   ExtensionLifecycleEventType
+	Install     ExtensionLifecycleEventType
+	Review      ExtensionLifecycleEventType
+	Acquisition ExtensionLifecycleEventType
+	Sales       ExtensionLifecycleEventType
+	Other       ExtensionLifecycleEventType
+}
+
+var ExtensionLifecycleEventTypeValues = extensionLifecycleEventTypeValuesType{
+	Uninstall:   "uninstall",
+	Install:     "install",
+	Review:      "review",
+	Acquisition: "acquisition",
+	Sales:       "sales",
+	Other:       "other",
+}
+
+// Package that will be used to create or update a published extension
+type ExtensionPackage struct {
+	// Base 64 encoded extension package
+	ExtensionManifest *string `json:"extensionManifest,omitempty"`
+}
+
+type ExtensionPayload struct {
+	Description         *string                        `json:"description,omitempty"`
+	DisplayName         *string                        `json:"displayName,omitempty"`
+	FileName            *string                        `json:"fileName,omitempty"`
+	InstallationTargets *[]InstallationTarget          `json:"installationTargets,omitempty"`
+	IsPreview           *bool                          `json:"isPreview,omitempty"`
+	IsSignedByMicrosoft *bool                          `json:"isSignedByMicrosoft,omitempty"`
+	IsValid             *bool                          `json:"isValid,omitempty"`
+	Metadata            *[]azuredevops.KeyValuePair    `json:"metadata,omitempty"`
+	Type                *ExtensionDeploymentTechnology `json:"type,omitempty"`
+}
+
+// Policy with a set of permissions on extension operations
+type ExtensionPolicy struct {
+	// Permissions on 'Install' operation
+	Install *ExtensionPolicyFlags `json:"install,omitempty"`
+	// Permission on 'Request' operation
+	Request *ExtensionPolicyFlags `json:"request,omitempty"`
+}
+
+// [Flags] Set of flags that can be associated with a given permission over an extension
+type ExtensionPolicyFlags string
+
+type extensionPolicyFlagsValuesType struct {
+	None       ExtensionPolicyFlags
+	Private    ExtensionPolicyFlags
+	Public     ExtensionPolicyFlags
+	Preview    ExtensionPolicyFlags
+	Released   ExtensionPolicyFlags
+	FirstParty ExtensionPolicyFlags
+	All        ExtensionPolicyFlags
+}
+
+var ExtensionPolicyFlagsValues = extensionPolicyFlagsValuesType{
+	// No permission
+	None: "none",
+	// Permission on private extensions
+	Private: "private",
+	// Permission on public extensions
+	Public: "public",
+	// Permission in extensions that are in preview
+	Preview: "preview",
+	// Permission in released extensions
+	Released: "released",
+	// Permission in 1st party extensions
+	FirstParty: "firstParty",
+	// Mask that defines all permissions
+	All: "all",
+}
+
+// An ExtensionQuery is used to search the gallery for a set of extensions that match one of many filter values.
+type ExtensionQuery struct {
+	// When retrieving extensions with a query; frequently the caller only needs a small subset of the assets. The caller may specify a list of asset types that should be returned if the extension contains it. All other assets will not be returned.
+	AssetTypes *[]string `json:"assetTypes,omitempty"`
+	// Each filter is a unique query and will have matching set of extensions returned from the request. Each result will have the same index in the resulting array that the filter had in the incoming query.
+	Filters *[]QueryFilter `json:"filters,omitempty"`
+	// The Flags are used to determine which set of information the caller would like returned for the matched extensions.
+	Flags *ExtensionQueryFlags `json:"flags,omitempty"`
+}
+
+// Type of extension filters that are supported in the queries.
+type ExtensionQueryFilterType string
+
+type extensionQueryFilterTypeValuesType struct {
+	Tag                            ExtensionQueryFilterType
+	DisplayName                    ExtensionQueryFilterType
+	Private                        ExtensionQueryFilterType
+	Id                             ExtensionQueryFilterType
+	Category                       ExtensionQueryFilterType
+	ContributionType               ExtensionQueryFilterType
+	Name                           ExtensionQueryFilterType
+	InstallationTarget             ExtensionQueryFilterType
+	Featured                       ExtensionQueryFilterType
+	SearchText                     ExtensionQueryFilterType
+	FeaturedInCategory             ExtensionQueryFilterType
+	ExcludeWithFlags               ExtensionQueryFilterType
+	IncludeWithFlags               ExtensionQueryFilterType
+	Lcid                           ExtensionQueryFilterType
+	InstallationTargetVersion      ExtensionQueryFilterType
+	InstallationTargetVersionRange ExtensionQueryFilterType
+	VsixMetadata                   ExtensionQueryFilterType
+	PublisherName                  ExtensionQueryFilterType
+	PublisherDisplayName           ExtensionQueryFilterType
+	IncludeWithPublisherFlags      ExtensionQueryFilterType
+	OrganizationSharedWith         ExtensionQueryFilterType
+	ProductArchitecture            ExtensionQueryFilterType
+	TargetPlatform                 ExtensionQueryFilterType
+	ExtensionName                  ExtensionQueryFilterType
+}
+
+var ExtensionQueryFilterTypeValues = extensionQueryFilterTypeValuesType{
+	// The values are used as tags. All tags are treated as "OR" conditions with each other. There may be some value put on the number of matched tags from the query.
+	Tag: "tag",
+	// The Values are an ExtensionName or fragment that is used to match other extension names.
+	DisplayName: "displayName",
+	// The Filter is one or more tokens that define what scope to return private extensions for.
+	Private: "private",
+	// Retrieve a set of extensions based on their id's. The values should be the extension id's encoded as strings.
+	Id: "id",
+	// The category is unlike other filters. It is AND'd with the other filters instead of being a separate query.
+	Category: "category",
+	// Certain contribution types may be indexed to allow for query by type. User defined types can't be indexed at the moment.
+	ContributionType: "contributionType",
+	// Retrieve an set extension based on the name based identifier. This differs from the internal id (which is being deprecated).
+	Name: "name",
+	// The InstallationTarget for an extension defines the target consumer for the extension. This may be something like VS, VSOnline, or VSCode
+	InstallationTarget: "installationTarget",
+	// Query for featured extensions, no value is allowed when using the query type.
+	Featured: "featured",
+	// The SearchText provided by the user to search for extensions
+	SearchText: "searchText",
+	// Query for extensions that are featured in their own category, The filterValue for this is name of category of extensions.
+	FeaturedInCategory: "featuredInCategory",
+	// When retrieving extensions from a query, exclude the extensions which are having the given flags. The value specified for this filter should be a string representing the integer values of the flags to be excluded. In case of multiple flags to be specified, a logical OR of the interger values should be given as value for this filter This should be at most one filter of this type. This only acts as a restrictive filter after. In case of having a particular flag in both IncludeWithFlags and ExcludeWithFlags, excludeFlags will remove the included extensions giving empty result for that flag.
+	ExcludeWithFlags: "excludeWithFlags",
+	// When retrieving extensions from a query, include the extensions which are having the given flags. The value specified for this filter should be a string representing the integer values of the flags to be included. In case of multiple flags to be specified, a logical OR of the integer values should be given as value for this filter This should be at most one filter of this type. This only acts as a restrictive filter after. In case of having a particular flag in both IncludeWithFlags and ExcludeWithFlags, excludeFlags will remove the included extensions giving empty result for that flag. In case of multiple flags given in IncludeWithFlags in ORed fashion, extensions having any of the given flags will be included.
+	IncludeWithFlags: "includeWithFlags",
+	// Filter the extensions based on the LCID values applicable. Any extensions which are not having any LCID values will also be filtered. This is currently only supported for VS extensions.
+	Lcid: "lcid",
+	// Filter to provide the version of the installation target. This filter will be used along with InstallationTarget filter. The value should be a valid version string. Currently supported only if search text is provided.
+	InstallationTargetVersion: "installationTargetVersion",
+	// Filter type for specifying a range of installation target version. The filter will be used along with InstallationTarget filter. The value should be a pair of well formed version values separated by hyphen(-). Currently supported only if search text is provided.
+	InstallationTargetVersionRange: "installationTargetVersionRange",
+	// Filter type for specifying metadata key and value to be used for filtering.
+	VsixMetadata: "vsixMetadata",
+	// Filter to get extensions published by a publisher having supplied internal name
+	PublisherName: "publisherName",
+	// Filter to get extensions published by all publishers having supplied display name
+	PublisherDisplayName: "publisherDisplayName",
+	// When retrieving extensions from a query, include the extensions which have a publisher having the given flags. The value specified for this filter should be a string representing the integer values of the flags to be included. In case of multiple flags to be specified, a logical OR of the integer values should be given as value for this filter There should be at most one filter of this type. This only acts as a restrictive filter after. In case of multiple flags given in IncludeWithFlags in ORed fashion, extensions having any of the given flags will be included.
+	IncludeWithPublisherFlags: "includeWithPublisherFlags",
+	// Filter to get extensions shared with particular organization
+	OrganizationSharedWith: "organizationSharedWith",
+	// Filter to get VS IDE extensions by Product Architecture
+	ProductArchitecture: "productArchitecture",
+	// Filter to get VS Code extensions by target platform.
+	TargetPlatform: "targetPlatform",
+	// Retrieve an extension based on the extensionName.
+	ExtensionName: "extensionName",
+}
+
+// [Flags] Set of flags used to determine which set of information is retrieved when reading published extensions
+type ExtensionQueryFlags string
+
+type extensionQueryFlagsValuesType struct {
+	None                          ExtensionQueryFlags
+	IncludeVersions               ExtensionQueryFlags
+	IncludeFiles                  ExtensionQueryFlags
+	IncludeCategoryAndTags        ExtensionQueryFlags
+	IncludeSharedAccounts         ExtensionQueryFlags
+	IncludeVersionProperties      ExtensionQueryFlags
+	ExcludeNonValidated           ExtensionQueryFlags
+	IncludeInstallationTargets    ExtensionQueryFlags
+	IncludeAssetUri               ExtensionQueryFlags
+	IncludeStatistics             ExtensionQueryFlags
+	IncludeLatestVersionOnly      ExtensionQueryFlags
+	UseFallbackAssetUri           ExtensionQueryFlags
+	IncludeMetadata               ExtensionQueryFlags
+	IncludeMinimalPayloadForVsIde ExtensionQueryFlags
+	IncludeLcids                  ExtensionQueryFlags
+	IncludeSharedOrganizations    ExtensionQueryFlags
+	IncludeNameConflictInfo       ExtensionQueryFlags
+	AllAttributes                 ExtensionQueryFlags
+}
+
+var ExtensionQueryFlagsValues = extensionQueryFlagsValuesType{
+	// None is used to retrieve only the basic extension details.
+	None: "none",
+	// IncludeVersions will return version information for extensions returned
+	IncludeVersions: "includeVersions",
+	// IncludeFiles will return information about which files were found within the extension that were stored independent of the manifest. When asking for files, versions will be included as well since files are returned as a property of the versions.  These files can be retrieved using the path to the file without requiring the entire manifest be downloaded.
+	IncludeFiles: "includeFiles",
+	// Include the Categories and Tags that were added to the extension definition.
+	IncludeCategoryAndTags: "includeCategoryAndTags",
+	// Include the details about which accounts the extension has been shared with if the extension is a private extension.
+	IncludeSharedAccounts: "includeSharedAccounts",
+	// Include properties associated with versions of the extension
+	IncludeVersionProperties: "includeVersionProperties",
+	// Excluding non-validated extensions will remove any extension versions that either are in the process of being validated or have failed validation.
+	ExcludeNonValidated: "excludeNonValidated",
+	// Include the set of installation targets the extension has requested.
+	IncludeInstallationTargets: "includeInstallationTargets",
+	// Include the base uri for assets of this extension
+	IncludeAssetUri: "includeAssetUri",
+	// Include the statistics associated with this extension
+	IncludeStatistics: "includeStatistics",
+	// When retrieving versions from a query, only include the latest version of the extensions that matched. This is useful when the caller doesn't need all the published versions. It will save a significant size in the returned payload.
+	IncludeLatestVersionOnly: "includeLatestVersionOnly",
+	// This flag switches the asset uri to use GetAssetByName instead of CDN When this is used, values of base asset uri and base asset uri fallback are switched When this is used, source of asset files are pointed to Gallery service always even if CDN is available
+	UseFallbackAssetUri: "useFallbackAssetUri",
+	// This flag is used to get all the metadata values associated with the extension. This is not applicable to VSTS or VSCode extensions and usage is only internal.
+	IncludeMetadata: "includeMetadata",
+	// This flag is used to indicate to return very small data for extension required by VS IDE. This flag is only compatible when querying is done by VS IDE
+	IncludeMinimalPayloadForVsIde: "includeMinimalPayloadForVsIde",
+	// This flag is used to get Lcid values associated with the extension. This is not applicable to VSTS or VSCode extensions and usage is only internal
+	IncludeLcids: "includeLcids",
+	// Include the details about which organizations the extension has been shared with if the extension is a private extension.
+	IncludeSharedOrganizations: "includeSharedOrganizations",
+	// Include the details if an extension is in conflict list or not Currently being used for VSCode extensions.
+	IncludeNameConflictInfo: "includeNameConflictInfo",
+	// AllAttributes is designed to be a mask that defines all sub-elements of the extension should be returned.  NOTE: This is not actually All flags. This is now locked to the set defined since changing this enum would be a breaking change and would change the behavior of anyone using it. Try not to use this value when making calls to the service, instead be explicit about the options required.
+	AllAttributes: "allAttributes",
+}
+
+// This is the set of extensions that matched a supplied query through the filters given.
+type ExtensionQueryResult struct {
+	// For each filter supplied in the query, a filter result will be returned in the query result.
+	Results *[]ExtensionFilterResult `json:"results,omitempty"`
+}
+
+type ExtensionShare struct {
+	Id    *string `json:"id,omitempty"`
+	IsOrg *bool   `json:"isOrg,omitempty"`
+	Name  *string `json:"name,omitempty"`
+	Type  *string `json:"type,omitempty"`
+}
+
+type ExtensionStatistic struct {
+	StatisticName *string  `json:"statisticName,omitempty"`
+	Value         *float64 `json:"value,omitempty"`
+}
+
+type ExtensionStatisticOperation string
+
+type extensionStatisticOperationValuesType struct {
+	None      ExtensionStatisticOperation
+	Set       ExtensionStatisticOperation
+	Increment ExtensionStatisticOperation
+	Decrement ExtensionStatisticOperation
+	Delete    ExtensionStatisticOperation
+}
+
+var ExtensionStatisticOperationValues = extensionStatisticOperationValuesType{
+	None:      "none",
+	Set:       "set",
+	Increment: "increment",
+	Decrement: "decrement",
+	Delete:    "delete",
+}
+
+type ExtensionStatisticUpdate struct {
+	ExtensionName *string                      `json:"extensionName,omitempty"`
+	Operation     *ExtensionStatisticOperation `json:"operation,omitempty"`
+	PublisherName *string                      `json:"publisherName,omitempty"`
+	Statistic     *ExtensionStatistic          `json:"statistic,omitempty"`
+}
+
+// Stats aggregation type
+type ExtensionStatsAggregateType string
+
+type extensionStatsAggregateTypeValuesType struct {
+	Daily ExtensionStatsAggregateType
+}
+
+var ExtensionStatsAggregateTypeValues = extensionStatsAggregateTypeValuesType{
+	Daily: "daily",
+}
+
+type ExtensionVersion struct {
+	AssetUri                *string                     `json:"assetUri,omitempty"`
+	Badges                  *[]ExtensionBadge           `json:"badges,omitempty"`
+	FallbackAssetUri        *string                     `json:"fallbackAssetUri,omitempty"`
+	Files                   *[]ExtensionFile            `json:"files,omitempty"`
+	Flags                   *ExtensionVersionFlags      `json:"flags,omitempty"`
+	LastUpdated             *azuredevops.Time           `json:"lastUpdated,omitempty"`
+	Properties              *[]azuredevops.KeyValuePair `json:"properties,omitempty"`
+	TargetPlatform          *string                     `json:"targetPlatform,omitempty"`
+	ValidationResultMessage *string                     `json:"validationResultMessage,omitempty"`
+	Version                 *string                     `json:"version,omitempty"`
+	VersionDescription      *string                     `json:"versionDescription,omitempty"`
+}
+
+// [Flags] Set of flags that can be associated with a given extension version. These flags apply to a specific version of the extension.
+type ExtensionVersionFlags string
+
+type extensionVersionFlagsValuesType struct {
+	None      ExtensionVersionFlags
+	Validated ExtensionVersionFlags
+}
+
+var ExtensionVersionFlagsValues = extensionVersionFlagsValuesType{
+	// No flags exist for this version.
+	None: "none",
+	// The Validated flag for a version means the extension version has passed validation and can be used..
+	Validated: "validated",
+}
+
+// One condition in a QueryFilter.
+type FilterCriteria struct {
+	FilterType *int `json:"filterType,omitempty"`
+	// The value used in the match based on the filter type.
+	Value *string `json:"value,omitempty"`
+}
+
+type InstallationTarget struct {
+	ExtensionVersion    *string `json:"extensionVersion,omitempty"`
+	ProductArchitecture *string `json:"productArchitecture,omitempty"`
+	Target              *string `json:"target,omitempty"`
+	TargetPlatform      *string `json:"targetPlatform,omitempty"`
+	TargetVersion       *string `json:"targetVersion,omitempty"`
+}
+
+// MetadataItem is one value of metadata under a given category of metadata
+type MetadataItem struct {
+	// The count of the metadata item
+	Count *int `json:"count,omitempty"`
+	// The name of the metadata item
+	Name *string `json:"name,omitempty"`
+}
+
+// Information needed for sending mail notification
+type NotificationsData struct {
+	// Notification data needed
+	Data *map[string]interface{} `json:"data,omitempty"`
+	// List of users who should get the notification
+	Identities *map[string]interface{} `json:"identities,omitempty"`
+	// Type of Mail Notification.Can be Qna , review or CustomerContact
+	Type *NotificationTemplateType `json:"type,omitempty"`
+}
+
+// Type of event
+type NotificationTemplateType string
+
+type notificationTemplateTypeValuesType struct {
+	ReviewNotification                NotificationTemplateType
+	QnaNotification                   NotificationTemplateType
+	CustomerContactNotification       NotificationTemplateType
+	PublisherMemberUpdateNotification NotificationTemplateType
+}
+
+var NotificationTemplateTypeValues = notificationTemplateTypeValuesType{
+	// Template type for Review Notification.
+	ReviewNotification: "reviewNotification",
+	// Template type for Qna Notification.
+	QnaNotification: "qnaNotification",
+	// Template type for Customer Contact Notification.
+	CustomerContactNotification: "customerContactNotification",
+	// Template type for Publisher Member Notification.
+	PublisherMemberUpdateNotification: "publisherMemberUpdateNotification",
+}
+
+// PagingDirection is used to define which set direction to move the returned result set based on a previous query.
+type PagingDirection string
+
+type pagingDirectionValuesType struct {
+	Backward PagingDirection
+	Forward  PagingDirection
+}
+
+var PagingDirectionValues = pagingDirectionValuesType{
+	// Backward will return results from earlier in the resultset.
+	Backward: "backward",
+	// Forward will return results from later in the resultset.
+	Forward: "forward",
+}
+
+// This is the set of categories in response to the get category query
+type ProductCategoriesResult struct {
+	Categories *[]ProductCategory `json:"categories,omitempty"`
+}
+
+// This is the interface object to be used by Root Categories and Category Tree APIs for Visual Studio Ide.
+type ProductCategory struct {
+	// Indicator whether this is a leaf or there are children under this category
+	HasChildren *bool              `json:"hasChildren,omitempty"`
+	Children    *[]ProductCategory `json:"children,omitempty"`
+	// Individual Guid of the Category
+	Id *uuid.UUID `json:"id,omitempty"`
+	// Category Title in the requested language
+	Title *string `json:"title,omitempty"`
+}
+
+type PublishedExtension struct {
+	Categories          *[]string                      `json:"categories,omitempty"`
+	DeploymentType      *ExtensionDeploymentTechnology `json:"deploymentType,omitempty"`
+	DisplayName         *string                        `json:"displayName,omitempty"`
+	ExtensionId         *uuid.UUID                     `json:"extensionId,omitempty"`
+	ExtensionName       *string                        `json:"extensionName,omitempty"`
+	Flags               *PublishedExtensionFlags       `json:"flags,omitempty"`
+	InstallationTargets *[]InstallationTarget          `json:"installationTargets,omitempty"`
+	LastUpdated         *azuredevops.Time              `json:"lastUpdated,omitempty"`
+	LongDescription     *string                        `json:"longDescription,omitempty"`
+	// Check if Extension is in conflict list or not. Taking as String and not as boolean because we don't want end customer to see this flag and by making it Boolean it is coming as false for all the cases.
+	PresentInConflictList *string `json:"presentInConflictList,omitempty"`
+	// Date on which the extension was first uploaded.
+	PublishedDate *azuredevops.Time `json:"publishedDate,omitempty"`
+	Publisher     *PublisherFacts   `json:"publisher,omitempty"`
+	// Date on which the extension first went public.
+	ReleaseDate      *azuredevops.Time     `json:"releaseDate,omitempty"`
+	SharedWith       *[]ExtensionShare     `json:"sharedWith,omitempty"`
+	ShortDescription *string               `json:"shortDescription,omitempty"`
+	Statistics       *[]ExtensionStatistic `json:"statistics,omitempty"`
+	Tags             *[]string             `json:"tags,omitempty"`
+	Versions         *[]ExtensionVersion   `json:"versions,omitempty"`
+}
+
+// [Flags] Set of flags that can be associated with a given extension. These flags apply to all versions of the extension and not to a specific version.
+type PublishedExtensionFlags string
+
+type publishedExtensionFlagsValuesType struct {
+	None         PublishedExtensionFlags
+	Disabled     PublishedExtensionFlags
+	BuiltIn      PublishedExtensionFlags
+	Validated    PublishedExtensionFlags
+	Trusted      PublishedExtensionFlags
+	Paid         PublishedExtensionFlags
+	Public       PublishedExtensionFlags
+	MultiVersion PublishedExtensionFlags
+	System       PublishedExtensionFlags
+	Preview      PublishedExtensionFlags
+	Unpublished  PublishedExtensionFlags
+	Trial        PublishedExtensionFlags
+	Locked       PublishedExtensionFlags
+	Hidden       PublishedExtensionFlags
+}
+
+var PublishedExtensionFlagsValues = publishedExtensionFlagsValuesType{
+	// No flags exist for this extension.
+	None: "none",
+	// The Disabled flag for an extension means the extension can't be changed and won't be used by consumers. The disabled flag is managed by the service and can't be supplied by the Extension Developers.
+	Disabled: "disabled",
+	// BuiltIn Extension are available to all Tenants. An explicit registration is not required. This attribute is reserved and can't be supplied by Extension Developers.  BuiltIn extensions are by definition Public. There is no need to set the public flag for extensions marked BuiltIn.
+	BuiltIn: "builtIn",
+	// This extension has been validated by the service. The extension meets the requirements specified. This attribute is reserved and can't be supplied by the Extension Developers. Validation is a process that ensures that all contributions are well formed. They meet the requirements defined by the contribution type they are extending. Note this attribute will be updated asynchronously as the extension is validated by the developer of the contribution type. There will be restricted access to the extension while this process is performed.
+	Validated: "validated",
+	// Trusted extensions are ones that are given special capabilities. These tend to come from Microsoft and can't be published by the general public.  Note: BuiltIn extensions are always trusted.
+	Trusted: "trusted",
+	// The Paid flag indicates that the commerce can be enabled for this extension. Publisher needs to setup Offer/Pricing plan in Azure. If Paid flag is set and a corresponding Offer is not available, the extension will automatically be marked as Preview. If the publisher intends to make the extension Paid in the future, it is mandatory to set the Preview flag. This is currently available only for VSTS extensions only.
+	Paid: "paid",
+	// This extension registration is public, making its visibility open to the public. This means all tenants have the ability to install this extension. Without this flag the extension will be private and will need to be shared with the tenants that can install it.
+	Public: "public",
+	// This extension has multiple versions active at one time and version discovery should be done using the defined "Version Discovery" protocol to determine the version available to a specific user or tenant.  @TODO: Link to Version Discovery Protocol.
+	MultiVersion: "multiVersion",
+	// The system flag is reserved, and cant be used by publishers.
+	System: "system",
+	// The Preview flag indicates that the extension is still under preview (not yet of "release" quality). These extensions may be decorated differently in the gallery and may have different policies applied to them.
+	Preview: "preview",
+	// The Unpublished flag indicates that the extension can't be installed/downloaded. Users who have installed such an extension can continue to use the extension.
+	Unpublished: "unpublished",
+	// The Trial flag indicates that the extension is in Trial version. The flag is right now being used only with respect to Visual Studio extensions.
+	Trial: "trial",
+	// The Locked flag indicates that extension has been locked from Marketplace. Further updates/acquisitions are not allowed on the extension until this is present. This should be used along with making the extension private/unpublished.
+	Locked: "locked",
+	// This flag is set for extensions we want to hide from Marketplace home and search pages. This will be used to override the exposure of builtIn flags.
+	Hidden: "hidden",
+}
+
+type Publisher struct {
+	DisplayName        *string               `json:"displayName,omitempty"`
+	EmailAddress       *[]string             `json:"emailAddress,omitempty"`
+	Extensions         *[]PublishedExtension `json:"extensions,omitempty"`
+	Flags              *PublisherFlags       `json:"flags,omitempty"`
+	LastUpdated        *azuredevops.Time     `json:"lastUpdated,omitempty"`
+	LongDescription    *string               `json:"longDescription,omitempty"`
+	PublisherId        *uuid.UUID            `json:"publisherId,omitempty"`
+	PublisherName      *string               `json:"publisherName,omitempty"`
+	ShortDescription   *string               `json:"shortDescription,omitempty"`
+	State              *PublisherState       `json:"state,omitempty"`
+	Links              interface{}           `json:"_links,omitempty"`
+	Domain             *string               `json:"domain,omitempty"`
+	IsDnsTokenVerified *bool                 `json:"isDnsTokenVerified,omitempty"`
+	IsDomainVerified   *bool                 `json:"isDomainVerified,omitempty"`
+	ReCaptchaToken     *string               `json:"reCaptchaToken,omitempty"`
+}
+
+// Keeping base class separate since publisher DB model class and publisher contract class share these common properties
+type PublisherBase struct {
+	DisplayName      *string               `json:"displayName,omitempty"`
+	EmailAddress     *[]string             `json:"emailAddress,omitempty"`
+	Extensions       *[]PublishedExtension `json:"extensions,omitempty"`
+	Flags            *PublisherFlags       `json:"flags,omitempty"`
+	LastUpdated      *azuredevops.Time     `json:"lastUpdated,omitempty"`
+	LongDescription  *string               `json:"longDescription,omitempty"`
+	PublisherId      *uuid.UUID            `json:"publisherId,omitempty"`
+	PublisherName    *string               `json:"publisherName,omitempty"`
+	ShortDescription *string               `json:"shortDescription,omitempty"`
+	State            *PublisherState       `json:"state,omitempty"`
+}
+
+// High-level information about the publisher, like id's and names
+type PublisherFacts struct {
+	DisplayName      *string         `json:"displayName,omitempty"`
+	Domain           *string         `json:"domain,omitempty"`
+	Flags            *PublisherFlags `json:"flags,omitempty"`
+	IsDomainVerified *bool           `json:"isDomainVerified,omitempty"`
+	PublisherId      *uuid.UUID      `json:"publisherId,omitempty"`
+	PublisherName    *string         `json:"publisherName,omitempty"`
+}
+
+// The FilterResult is the set of publishers that matched a particular query filter.
+type PublisherFilterResult struct {
+	// This is the set of applications that matched the query filter supplied.
+	Publishers *[]Publisher `json:"publishers,omitempty"`
+}
+
+// [Flags]
+type PublisherFlags string
+
+type publisherFlagsValuesType struct {
+	UnChanged    PublisherFlags
+	None         PublisherFlags
+	Disabled     PublisherFlags
+	Verified     PublisherFlags
+	Certified    PublisherFlags
+	ServiceFlags PublisherFlags
+}
+
+var PublisherFlagsValues = publisherFlagsValuesType{
+	// This should never be returned, it is used to represent a publisher who's flags haven't changed during update calls.
+	UnChanged: "unChanged",
+	// No flags exist for this publisher.
+	None: "none",
+	// The Disabled flag for a publisher means the publisher can't be changed and won't be used by consumers, this extends to extensions owned by the publisher as well. The disabled flag is managed by the service and can't be supplied by the Extension Developers.
+	Disabled: "disabled",
+	// A verified publisher is one that Microsoft has done some review of and ensured the publisher meets a set of requirements. The requirements to become a verified publisher are not listed here.  They can be found in public documentation (TBD).
+	Verified: "verified",
+	// A Certified publisher is one that is Microsoft verified and in addition meets a set of requirements for its published extensions. The requirements to become a certified publisher are not listed here.  They can be found in public documentation (TBD).
+	Certified: "certified",
+	// This is the set of flags that can't be supplied by the developer and is managed by the service itself.
+	ServiceFlags: "serviceFlags",
+}
+
+// [Flags]
+type PublisherPermissions string
+
+type publisherPermissionsValuesType struct {
+	Read              PublisherPermissions
+	UpdateExtension   PublisherPermissions
+	CreatePublisher   PublisherPermissions
+	PublishExtension  PublisherPermissions
+	Admin             PublisherPermissions
+	TrustedPartner    PublisherPermissions
+	PrivateRead       PublisherPermissions
+	DeleteExtension   PublisherPermissions
+	EditSettings      PublisherPermissions
+	ViewPermissions   PublisherPermissions
+	ManagePermissions PublisherPermissions
+	DeletePublisher   PublisherPermissions
+}
+
+var PublisherPermissionsValues = publisherPermissionsValuesType{
+	// This gives the bearer the rights to read Publishers and Extensions.
+	Read: "read",
+	// This gives the bearer the rights to update, delete, and share Extensions (but not the ability to create them).
+	UpdateExtension: "updateExtension",
+	// This gives the bearer the rights to create new Publishers at the root of the namespace.
+	CreatePublisher: "createPublisher",
+	// This gives the bearer the rights to create new Extensions within a publisher.
+	PublishExtension: "publishExtension",
+	// Admin gives the bearer the rights to manage restricted attributes of Publishers and Extensions.
+	Admin: "admin",
+	// TrustedPartner gives the bearer the rights to publish a extensions with restricted capabilities.
+	TrustedPartner: "trustedPartner",
+	// PrivateRead is another form of read designed to allow higher privilege accessors the ability to read private extensions.
+	PrivateRead: "privateRead",
+	// This gives the bearer the rights to delete any extension.
+	DeleteExtension: "deleteExtension",
+	// This gives the bearer the rights edit the publisher settings.
+	EditSettings: "editSettings",
+	// This gives the bearer the rights to see all permissions on the publisher.
+	ViewPermissions: "viewPermissions",
+	// This gives the bearer the rights to assign permissions on the publisher.
+	ManagePermissions: "managePermissions",
+	// This gives the bearer the rights to delete the publisher.
+	DeletePublisher: "deletePublisher",
+}
+
+// An PublisherQuery is used to search the gallery for a set of publishers that match one of many filter values.
+type PublisherQuery struct {
+	// Each filter is a unique query and will have matching set of publishers returned from the request. Each result will have the same index in the resulting array that the filter had in the incoming query.
+	Filters *[]QueryFilter `json:"filters,omitempty"`
+	// The Flags are used to determine which set of information the caller would like returned for the matched publishers.
+	Flags *PublisherQueryFlags `json:"flags,omitempty"`
+}
+
+// [Flags] Set of flags used to define the attributes requested when a publisher is returned. Some API's allow the caller to specify the level of detail needed.
+type PublisherQueryFlags string
+
+type publisherQueryFlagsValuesType struct {
+	None                PublisherQueryFlags
+	IncludeExtensions   PublisherQueryFlags
+	IncludeEmailAddress PublisherQueryFlags
+}
+
+var PublisherQueryFlagsValues = publisherQueryFlagsValuesType{
+	// None is used to retrieve only the basic publisher details.
+	None: "none",
+	// Is used to include a list of basic extension details for all extensions published by the requested publisher.
+	IncludeExtensions: "includeExtensions",
+	// Is used to include email address of all the users who are marked as owners for the publisher
+	IncludeEmailAddress: "includeEmailAddress",
+}
+
+// This is the set of publishers that matched a supplied query through the filters given.
+type PublisherQueryResult struct {
+	// For each filter supplied in the query, a filter result will be returned in the query result.
+	Results *[]PublisherFilterResult `json:"results,omitempty"`
+}
+
+// Access definition for a RoleAssignment.
+type PublisherRoleAccess string
+
+type publisherRoleAccessValuesType struct {
+	Assigned  PublisherRoleAccess
+	Inherited PublisherRoleAccess
+}
+
+var PublisherRoleAccessValues = publisherRoleAccessValuesType{
+	// Access has been explicitly set.
+	Assigned: "assigned",
+	// Access has been inherited from a higher scope.
+	Inherited: "inherited",
+}
+
+type PublisherRoleAssignment struct {
+	// Designates the role as explicitly assigned or inherited.
+	Access *PublisherRoleAccess `json:"access,omitempty"`
+	// User friendly description of access assignment.
+	AccessDisplayName *string `json:"accessDisplayName,omitempty"`
+	// The user to whom the role is assigned.
+	Identity *webapi.IdentityRef `json:"identity,omitempty"`
+	// The role assigned to the user.
+	Role *PublisherSecurityRole `json:"role,omitempty"`
+}
+
+type PublisherSecurityRole struct {
+	// Permissions the role is allowed.
+	AllowPermissions *int `json:"allowPermissions,omitempty"`
+	// Permissions the role is denied.
+	DenyPermissions *int `json:"denyPermissions,omitempty"`
+	// Description of user access defined by the role
+	Description *string `json:"description,omitempty"`
+	// User friendly name of the role.
+	DisplayName *string `json:"displayName,omitempty"`
+	// Globally unique identifier for the role.
+	Identifier *string `json:"identifier,omitempty"`
+	// Unique name of the role in the scope.
+	Name *string `json:"name,omitempty"`
+	// Returns the id of the ParentScope.
+	Scope *string `json:"scope,omitempty"`
+}
+
+// [Flags]
+type PublisherState string
+
+type publisherStateValuesType struct {
+	None                  PublisherState
+	VerificationPending   PublisherState
+	CertificationPending  PublisherState
+	CertificationRejected PublisherState
+	CertificationRevoked  PublisherState
+}
+
+var PublisherStateValues = publisherStateValuesType{
+	// No state exists for this publisher.
+	None: "none",
+	// This state indicates that publisher has applied for Marketplace verification (via UI) and still not been certified. This state would be reset once the publisher is verified.
+	VerificationPending: "verificationPending",
+	// This state indicates that publisher has applied for Marketplace certification (via UI) and still not been certified. This state would be reset once the publisher is certified.
+	CertificationPending: "certificationPending",
+	// This state indicates that publisher had applied for Marketplace certification (via UI) but his/her certification got rejected. This state would be reset if and when the publisher is certified.
+	CertificationRejected: "certificationRejected",
+	// This state indicates that publisher was certified on the Marketplace, but his/her certification got revoked. This state would never be reset, even after publisher gets re-certified. It would indicate that the publisher certification was revoked at least once.
+	CertificationRevoked: "certificationRevoked",
+}
+
+type PublisherUserRoleAssignmentRef struct {
+	// The name of the role assigned.
+	RoleName *string `json:"roleName,omitempty"`
+	// Identifier of the user given the role assignment.
+	UniqueName *string `json:"uniqueName,omitempty"`
+	// Unique id of the user given the role assignment.
+	UserId *uuid.UUID `json:"userId,omitempty"`
+}
+
+// The core structure of a QnA item
+type QnAItem struct {
+	// Time when the review was first created
+	CreatedDate *azuredevops.Time `json:"createdDate,omitempty"`
+	// Unique identifier of a QnA item
+	Id *uint64 `json:"id,omitempty"`
+	// Get status of item
+	Status *QnAItemStatus `json:"status,omitempty"`
+	// Text description of the QnA item
+	Text *string `json:"text,omitempty"`
+	// Time when the review was edited/updated
+	UpdatedDate *azuredevops.Time `json:"updatedDate,omitempty"`
+	// User details for the item.
+	User *UserIdentityRef `json:"user,omitempty"`
+}
+
+// [Flags] Denotes the status of the QnA Item
+type QnAItemStatus string
+
+type qnAItemStatusValuesType struct {
+	None             QnAItemStatus
+	UserEditable     QnAItemStatus
+	PublisherCreated QnAItemStatus
+}
+
+var QnAItemStatusValues = qnAItemStatusValuesType{
+	None: "none",
+	// The UserEditable flag indicates whether the item is editable by the logged in user.
+	UserEditable: "userEditable",
+	// The PublisherCreated flag indicates whether the item has been created by extension publisher.
+	PublisherCreated: "publisherCreated",
+}
+
+// A filter used to define a set of extensions to return during a query.
+type QueryFilter struct {
+	// The filter values define the set of values in this query. They are applied based on the QueryFilterType.
+	Criteria *[]FilterCriteria `json:"criteria,omitempty"`
+	// The PagingDirection is applied to a paging token if one exists. If not the direction is ignored, and Forward from the start of the resultset is used. Direction should be left out of the request unless a paging token is used to help prevent future issues.
+	Direction *PagingDirection `json:"direction,omitempty"`
+	// The page number requested by the user. If not provided 1 is assumed by default.
+	PageNumber *int `json:"pageNumber,omitempty"`
+	// The page size defines the number of results the caller wants for this filter. The count can't exceed the overall query size limits.
+	PageSize *int `json:"pageSize,omitempty"`
+	// The paging token is a distinct type of filter and the other filter fields are ignored. The paging token represents the continuation of a previously executed query. The information about where in the result and what fields are being filtered are embedded in the token.
+	PagingToken *string `json:"pagingToken,omitempty"`
+	// Defines the type of sorting to be applied on the results. The page slice is cut of the sorted results only.
+	SortBy *int `json:"sortBy,omitempty"`
+	// Defines the order of sorting, 1 for Ascending, 2 for Descending, else default ordering based on the SortBy value
+	SortOrder *int `json:"sortOrder,omitempty"`
+}
+
+// The structure of the question / thread
+type Question struct {
+	// Time when the review was first created
+	CreatedDate *azuredevops.Time `json:"createdDate,omitempty"`
+	// Unique identifier of a QnA item
+	Id *uint64 `json:"id,omitempty"`
+	// Get status of item
+	Status *QnAItemStatus `json:"status,omitempty"`
+	// Text description of the QnA item
+	Text *string `json:"text,omitempty"`
+	// Time when the review was edited/updated
+	UpdatedDate *azuredevops.Time `json:"updatedDate,omitempty"`
+	// User details for the item.
+	User           *UserIdentityRef `json:"user,omitempty"`
+	ReCaptchaToken *string          `json:"reCaptchaToken,omitempty"`
+	// List of answers in for the question / thread
+	Responses *[]Response `json:"responses,omitempty"`
+}
+
+type QuestionsResult struct {
+	// Flag indicating if there are more QnA threads to be shown (for paging)
+	HasMoreQuestions *bool `json:"hasMoreQuestions,omitempty"`
+	// List of the QnA threads
+	Questions *[]Question `json:"questions,omitempty"`
+}
+
+type RatingCountPerRating struct {
+	// Rating value
+	Rating *byte `json:"rating,omitempty"`
+	// Count of total ratings
+	RatingCount *uint64 `json:"ratingCount,omitempty"`
+}
+
+// The structure of a response
+type Response struct {
+	// Time when the review was first created
+	CreatedDate *azuredevops.Time `json:"createdDate,omitempty"`
+	// Unique identifier of a QnA item
+	Id *uint64 `json:"id,omitempty"`
+	// Get status of item
+	Status *QnAItemStatus `json:"status,omitempty"`
+	// Text description of the QnA item
+	Text *string `json:"text,omitempty"`
+	// Time when the review was edited/updated
+	UpdatedDate *azuredevops.Time `json:"updatedDate,omitempty"`
+	// User details for the item.
+	User           *UserIdentityRef `json:"user,omitempty"`
+	ReCaptchaToken *string          `json:"reCaptchaToken,omitempty"`
+}
+
+// The status of a REST Api response status.
+type RestApiResponseStatus string
+
+type restApiResponseStatusValuesType struct {
+	Completed  RestApiResponseStatus
+	Failed     RestApiResponseStatus
+	Inprogress RestApiResponseStatus
+	Skipped    RestApiResponseStatus
+}
+
+var RestApiResponseStatusValues = restApiResponseStatusValuesType{
+	// The operation is completed.
+	Completed: "completed",
+	// The operation is failed.
+	Failed: "failed",
+	// The operation is in progress.
+	Inprogress: "inprogress",
+	// The operation is in skipped.
+	Skipped: "skipped",
+}
+
+// REST Api Response
+type RestApiResponseStatusModel struct {
+	// Gets or sets the operation details
+	OperationDetails interface{} `json:"operationDetails,omitempty"`
+	// Gets or sets the operation id
+	OperationId *string `json:"operationId,omitempty"`
+	// Gets or sets the completed status percentage
+	PercentageCompleted *int `json:"percentageCompleted,omitempty"`
+	// Gets or sets the status
+	Status *RestApiResponseStatus `json:"status,omitempty"`
+	// Gets or sets the status message
+	StatusMessage *string `json:"statusMessage,omitempty"`
+}
+
+type Review struct {
+	// Admin Reply, if any, for this review
+	AdminReply *ReviewReply `json:"adminReply,omitempty"`
+	// Unique identifier of a review item
+	Id *uint64 `json:"id,omitempty"`
+	// Flag for soft deletion
+	IsDeleted *bool `json:"isDeleted,omitempty"`
+	IsIgnored *bool `json:"isIgnored,omitempty"`
+	// Version of the product for which review was submitted
+	ProductVersion *string `json:"productVersion,omitempty"`
+	// Rating provided by the user
+	Rating         *byte   `json:"rating,omitempty"`
+	ReCaptchaToken *string `json:"reCaptchaToken,omitempty"`
+	// Reply, if any, for this review
+	Reply *ReviewReply `json:"reply,omitempty"`
+	// Text description of the review
+	Text *string `json:"text,omitempty"`
+	// Title of the review
+	Title *string `json:"title,omitempty"`
+	// Time when the review was edited/updated
+	UpdatedDate *azuredevops.Time `json:"updatedDate,omitempty"`
+	// Name of the user
+	UserDisplayName *string `json:"userDisplayName,omitempty"`
+	// Id of the user who submitted the review
+	UserId *uuid.UUID `json:"userId,omitempty"`
+}
+
+// Type of operation
+type ReviewEventOperation string
+
+type reviewEventOperationValuesType struct {
+	Create ReviewEventOperation
+	Update ReviewEventOperation
+	Delete ReviewEventOperation
+}
+
+var ReviewEventOperationValues = reviewEventOperationValuesType{
+	Create: "create",
+	Update: "update",
+	Delete: "delete",
+}
+
+// Properties associated with Review event
+type ReviewEventProperties struct {
+	// Operation performed on Event - Create\Update
+	EventOperation *ReviewEventOperation `json:"eventOperation,omitempty"`
+	// Flag to see if reply is admin reply
+	IsAdminReply *bool `json:"isAdminReply,omitempty"`
+	// Flag to record if the review is ignored
+	IsIgnored *bool `json:"isIgnored,omitempty"`
+	// Rating at the time of event
+	Rating *int `json:"rating,omitempty"`
+	// Reply update date
+	ReplyDate *azuredevops.Time `json:"replyDate,omitempty"`
+	// Publisher reply text or admin reply text
+	ReplyText *string `json:"replyText,omitempty"`
+	// User who responded to the review
+	ReplyUserId *uuid.UUID `json:"replyUserId,omitempty"`
+	// Review Event Type - Review
+	ResourceType *ReviewResourceType `json:"resourceType,omitempty"`
+	// Review update date
+	ReviewDate *azuredevops.Time `json:"reviewDate,omitempty"`
+	// ReviewId of the review  on which the operation is performed
+	ReviewId *uint64 `json:"reviewId,omitempty"`
+	// Text in Review Text
+	ReviewText *string `json:"reviewText,omitempty"`
+	// User display name at the time of review
+	UserDisplayName *string `json:"userDisplayName,omitempty"`
+	// User who gave review
+	UserId *uuid.UUID `json:"userId,omitempty"`
+}
+
+// [Flags] Options to GetReviews query
+type ReviewFilterOptions string
+
+type reviewFilterOptionsValuesType struct {
+	None                 ReviewFilterOptions
+	FilterEmptyReviews   ReviewFilterOptions
+	FilterEmptyUserNames ReviewFilterOptions
+}
+
+var ReviewFilterOptionsValues = reviewFilterOptionsValuesType{
+	// No filtering, all reviews are returned (default option)
+	None: "none",
+	// Filter out review items with empty review text
+	FilterEmptyReviews: "filterEmptyReviews",
+	// Filter out review items with empty usernames
+	FilterEmptyUserNames: "filterEmptyUserNames",
+}
+
+type ReviewPatch struct {
+	// Denotes the patch operation type
+	Operation *ReviewPatchOperation `json:"operation,omitempty"`
+	// Use when patch operation is FlagReview
+	ReportedConcern *UserReportedConcern `json:"reportedConcern,omitempty"`
+	// Use when patch operation is EditReview
+	ReviewItem *Review `json:"reviewItem,omitempty"`
+}
+
+// Denotes the patch operation type
+type ReviewPatchOperation string
+
+type reviewPatchOperationValuesType struct {
+	FlagReview             ReviewPatchOperation
+	UpdateReview           ReviewPatchOperation
+	ReplyToReview          ReviewPatchOperation
+	AdminResponseForReview ReviewPatchOperation
+	DeleteAdminReply       ReviewPatchOperation
+	DeletePublisherReply   ReviewPatchOperation
+}
+
+var ReviewPatchOperationValues = reviewPatchOperationValuesType{
+	// Flag a review
+	FlagReview: "flagReview",
+	// Update an existing review
+	UpdateReview: "updateReview",
+	// Submit a reply for a review
+	ReplyToReview: "replyToReview",
+	// Submit an admin response
+	AdminResponseForReview: "adminResponseForReview",
+	// Delete an Admin Reply
+	DeleteAdminReply: "deleteAdminReply",
+	// Delete Publisher Reply
+	DeletePublisherReply: "deletePublisherReply",
+}
+
+type ReviewReply struct {
+	// Id of the reply
+	Id *uint64 `json:"id,omitempty"`
+	// Flag for soft deletion
+	IsDeleted *bool `json:"isDeleted,omitempty"`
+	// Version of the product when the reply was submitted or updated
+	ProductVersion *string `json:"productVersion,omitempty"`
+	// Content of the reply
+	ReplyText *string `json:"replyText,omitempty"`
+	// Id of the review, to which this reply belongs
+	ReviewId *uint64 `json:"reviewId,omitempty"`
+	// Title of the reply
+	Title *string `json:"title,omitempty"`
+	// Date the reply was submitted or updated
+	UpdatedDate *azuredevops.Time `json:"updatedDate,omitempty"`
+	// Id of the user who left the reply
+	UserId *uuid.UUID `json:"userId,omitempty"`
+}
+
+// Type of event
+type ReviewResourceType string
+
+type reviewResourceTypeValuesType struct {
+	Review         ReviewResourceType
+	PublisherReply ReviewResourceType
+	AdminReply     ReviewResourceType
+}
+
+var ReviewResourceTypeValues = reviewResourceTypeValuesType{
+	Review:         "review",
+	PublisherReply: "publisherReply",
+	AdminReply:     "adminReply",
+}
+
+type ReviewsResult struct {
+	// Flag indicating if there are more reviews to be shown (for paging)
+	HasMoreReviews *bool `json:"hasMoreReviews,omitempty"`
+	// List of reviews
+	Reviews *[]Review `json:"reviews,omitempty"`
+	// Count of total review items
+	TotalReviewCount *uint64 `json:"totalReviewCount,omitempty"`
+}
+
+type ReviewSummary struct {
+	// Average Rating
+	AverageRating *float32 `json:"averageRating,omitempty"`
+	// Count of total ratings
+	RatingCount *uint64 `json:"ratingCount,omitempty"`
+	// Split of count across rating
+	RatingSplit *[]RatingCountPerRating `json:"ratingSplit,omitempty"`
+}
+
+// Defines the sort order that can be defined for Extensions query
+type SortByType string
+
+type sortByTypeValuesType struct {
+	Relevance       SortByType
+	LastUpdatedDate SortByType
+	Title           SortByType
+	Publisher       SortByType
+	InstallCount    SortByType
+	PublishedDate   SortByType
+	AverageRating   SortByType
+	TrendingDaily   SortByType
+	TrendingWeekly  SortByType
+	TrendingMonthly SortByType
+	ReleaseDate     SortByType
+	Author          SortByType
+	WeightedRating  SortByType
+}
+
+var SortByTypeValues = sortByTypeValuesType{
+	// The results will be sorted by relevance in case search query is given, if no search query resutls will be provided as is
+	Relevance: "relevance",
+	// The results will be sorted as per Last Updated date of the extensions with recently updated at the top
+	LastUpdatedDate: "lastUpdatedDate",
+	// Results will be sorted Alphabetically as per the title of the extension
+	Title: "title",
+	// Results will be sorted Alphabetically as per Publisher title
+	Publisher: "publisher",
+	// Results will be sorted by Install Count
+	InstallCount: "installCount",
+	// The results will be sorted as per Published date of the extensions
+	PublishedDate: "publishedDate",
+	// The results will be sorted as per Average ratings of the extensions
+	AverageRating: "averageRating",
+	// The results will be sorted as per Trending Daily Score of the extensions
+	TrendingDaily: "trendingDaily",
+	// The results will be sorted as per Trending weekly Score of the extensions
+	TrendingWeekly: "trendingWeekly",
+	// The results will be sorted as per Trending monthly Score of the extensions
+	TrendingMonthly: "trendingMonthly",
+	// The results will be sorted as per ReleaseDate of the extensions (date on which the extension first went public)
+	ReleaseDate: "releaseDate",
+	// The results will be sorted as per Author defined in the VSix/Metadata. If not defined, publisher name is used This is specifically needed by VS IDE, other (new and old) clients are not encouraged to use this
+	Author: "author",
+	// The results will be sorted as per Weighted Rating of the extension.
+	WeightedRating: "weightedRating",
+}
+
+// Defines the sort order that can be defined for Extensions query
+type SortOrderType string
+
+type sortOrderTypeValuesType struct {
+	Default    SortOrderType
+	Ascending  SortOrderType
+	Descending SortOrderType
+}
+
+var SortOrderTypeValues = sortOrderTypeValuesType{
+	// Results will be sorted in the default order as per the sorting type defined. The default varies for each type, e.g. for Relevance, default is Descending, for Title default is Ascending etc.
+	Default: "default",
+	// The results will be sorted in Ascending order
+	Ascending: "ascending",
+	// The results will be sorted in Descending order
+	Descending: "descending",
+}
+
+type UnpackagedExtensionData struct {
+	Categories            *[]string             `json:"categories,omitempty"`
+	Description           *string               `json:"description,omitempty"`
+	DisplayName           *string               `json:"displayName,omitempty"`
+	DraftId               *uuid.UUID            `json:"draftId,omitempty"`
+	ExtensionName         *string               `json:"extensionName,omitempty"`
+	InstallationTargets   *[]InstallationTarget `json:"installationTargets,omitempty"`
+	IsConvertedToMarkdown *bool                 `json:"isConvertedToMarkdown,omitempty"`
+	IsPreview             *bool                 `json:"isPreview,omitempty"`
+	PricingCategory       *string               `json:"pricingCategory,omitempty"`
+	Product               *string               `json:"product,omitempty"`
+	PublisherName         *string               `json:"publisherName,omitempty"`
+	QnAEnabled            *bool                 `json:"qnAEnabled,omitempty"`
+	ReferralUrl           *string               `json:"referralUrl,omitempty"`
+	RepositoryUrl         *string               `json:"repositoryUrl,omitempty"`
+	Tags                  *[]string             `json:"tags,omitempty"`
+	Version               *string               `json:"version,omitempty"`
+	VsixId                *string               `json:"vsixId,omitempty"`
+}
+
+// Represents the extension policy applied to a given user
+type UserExtensionPolicy struct {
+	// User display name that this policy refers to
+	DisplayName *string `json:"displayName,omitempty"`
+	// The extension policy applied to the user
+	Permissions *ExtensionPolicy `json:"permissions,omitempty"`
+	// User id that this policy refers to
+	UserId *string `json:"userId,omitempty"`
+}
+
+// Identity reference with name and guid
+type UserIdentityRef struct {
+	// User display name
+	DisplayName *string `json:"displayName,omitempty"`
+	// User VSID
+	Id *uuid.UUID `json:"id,omitempty"`
+}
+
+type UserReportedConcern struct {
+	// Category of the concern
+	Category *ConcernCategory `json:"category,omitempty"`
+	// User comment associated with the report
+	ConcernText *string `json:"concernText,omitempty"`
+	// Id of the review which was reported
+	ReviewId *uint64 `json:"reviewId,omitempty"`
+	// Date the report was submitted
+	SubmittedDate *azuredevops.Time `json:"submittedDate,omitempty"`
+	// Id of the user who reported a review
+	UserId *uuid.UUID `json:"userId,omitempty"`
+}
+
+type VSCodeWebExtensionStatisicsType string
+
+type vsCodeWebExtensionStatisicsTypeValuesType struct {
+	Install   VSCodeWebExtensionStatisicsType
+	Update    VSCodeWebExtensionStatisicsType
+	Uninstall VSCodeWebExtensionStatisicsType
+}
+
+var VSCodeWebExtensionStatisicsTypeValues = vsCodeWebExtensionStatisicsTypeValuesType{
+	Install:   "install",
+	Update:    "update",
+	Uninstall: "uninstall",
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c582e7c4..52e78e70 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -283,9 +283,11 @@ github.com/microsoft/azure-devops-go-api/azuredevops/v7/dashboard
 github.com/microsoft/azure-devops-go-api/azuredevops/v7/delegatedauthorization
 github.com/microsoft/azure-devops-go-api/azuredevops/v7/distributedtaskcommon
 github.com/microsoft/azure-devops-go-api/azuredevops/v7/elastic
+github.com/microsoft/azure-devops-go-api/azuredevops/v7/extensionmanagement
 github.com/microsoft/azure-devops-go-api/azuredevops/v7/featuremanagement
 github.com/microsoft/azure-devops-go-api/azuredevops/v7/feed
 github.com/microsoft/azure-devops-go-api/azuredevops/v7/forminput
+github.com/microsoft/azure-devops-go-api/azuredevops/v7/gallery
 github.com/microsoft/azure-devops-go-api/azuredevops/v7/git
 github.com/microsoft/azure-devops-go-api/azuredevops/v7/graph
 github.com/microsoft/azure-devops-go-api/azuredevops/v7/identity
diff --git a/website/docs/r/extension.html.markdown b/website/docs/r/extension.html.markdown
new file mode 100644
index 00000000..f8cd3444
--- /dev/null
+++ b/website/docs/r/extension.html.markdown
@@ -0,0 +1,69 @@
+---
+layout: "azuredevops"
+page_title: "AzureDevops: extension"
+description: |-
+  Manages Extension within Azure DevOps organization.
+---
+
+# azuredevops_extension
+
+Manages extension within Azure DevOps organization.
+
+## Example Usage
+
+### Install Extension
+```hcl
+resource "azuredevops_extension" "example" {
+  extension_id = "extension ID"
+  publisher_id = "publisher ID"
+}
+```
+
+## Argument Reference
+
+The following arguments are supported:
+
+* `extension_id` - (Required) The publisher ID of the extension.
+
+* `publisher_id` - (Required) The extension ID of the extension.
+
+---
+
+* `disabled` - (Optional) Whether to disable the extension.
+
+* `version`- (Optional) The version of the extension.
+
+## Attributes Reference
+
+The following attributes are exported:
+
+* `id` - The ID of the Extension.
+
+* `version` - The version of the Extension.
+
+* `extension_name` - The name of the extension.
+
+* `publisher_name` - The name of the publisher.
+
+* `scope` - List of all oauth scopes required by this extension.
+
+## Relevant Links
+
+- [Azure DevOps Service REST API 7.1 - Extension Management](https://learn.microsoft.com/en-us/rest/api/azure/devops/extensionmanagement/installed-extensions?view=azure-devops-rest-7.1)
+
+## Timeouts
+
+The `timeouts` block allows you to specify [timeouts](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts) for certain actions:
+
+* `create` - (Defaults to 5 minutes) Used when creating the extension.
+* `read` - (Defaults to 2 minute) Used when retrieving the extension.
+* `update` - (Defaults to 5 minutes) Used when updating the extension.
+* `delete` - (Defaults to 5 minutes) Used when deleting the extension.
+
+## Import
+
+Azure DevOps Extension can be imported using the publisher ID and extension ID:
+
+```sh
+terraform import azuredevops_extension.example publisherId/extensionId
+```



Test patch:
diff --git a/azuredevops/internal/acceptancetests/resource_extension_test.go b/azuredevops/internal/acceptancetests/resource_extension_test.go
new file mode 100644
index 00000000..45e56e25
--- /dev/null
+++ b/azuredevops/internal/acceptancetests/resource_extension_test.go
@@ -0,0 +1,265 @@
+package acceptancetests
+
+import (
+	"fmt"
+	"regexp"
+	"strings"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
+	"github.com/microsoft/azure-devops-go-api/azuredevops/v7/extensionmanagement"
+	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/acceptancetests/testutils"
+	"github.com/microsoft/terraform-provider-azuredevops/azuredevops/internal/client"
+)
+
+func TestAccExtension_basic(t *testing.T) {
+	publisherId := "ms-securitydevops"
+	extensionId := "microsoft-security-devops-azdevops"
+	tfNode := "azuredevops_extension.test"
+	resource.Test(t, resource.TestCase{
+		PreCheck:          func() { testutils.PreCheck(t, nil) },
+		ProviderFactories: testutils.GetProviderFactories(),
+		CheckDestroy:      checkExtensionDestroyed,
+		Steps: []resource.TestStep{
+			{
+				Config: hclExtensionBasic(publisherId, extensionId),
+				Check: resource.ComposeTestCheckFunc(
+					checkExtensionExist(extensionId),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_name"),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_name"),
+				),
+			},
+			{
+				ResourceName:      tfNode,
+				ImportState:       true,
+				ImportStateId:     fmt.Sprintf("%s/%s", publisherId, extensionId),
+				ImportStateVerify: true,
+			},
+		},
+	})
+}
+
+func TestAccExtension_complete(t *testing.T) {
+	publisherId := "ms-securitydevops"
+	extensionId := "microsoft-security-devops-azdevops"
+	tfNode := "azuredevops_extension.test"
+	resource.Test(t, resource.TestCase{
+		PreCheck:          func() { testutils.PreCheck(t, nil) },
+		ProviderFactories: testutils.GetProviderFactories(),
+		CheckDestroy:      checkExtensionDestroyed,
+		Steps: []resource.TestStep{
+			{
+				Config: hclExtensionComplete(publisherId, extensionId),
+				Check: resource.ComposeTestCheckFunc(
+					checkExtensionExist(extensionId),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_name"),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_name"),
+					resource.TestCheckResourceAttrSet(tfNode, "scope.#"),
+					resource.TestCheckResourceAttrSet(tfNode, "version"),
+					resource.TestCheckResourceAttrSet(tfNode, "disabled"),
+				),
+			},
+			{
+				ResourceName:      tfNode,
+				ImportState:       true,
+				ImportStateId:     fmt.Sprintf("%s/%s", publisherId, extensionId),
+				ImportStateVerify: true,
+			},
+		},
+	})
+}
+
+func TestAccExtension_update(t *testing.T) {
+	publisherId := "ms-securitydevops"
+	extensionId := "microsoft-security-devops-azdevops"
+	tfNode := "azuredevops_extension.test"
+	resource.Test(t, resource.TestCase{
+		PreCheck:          func() { testutils.PreCheck(t, nil) },
+		ProviderFactories: testutils.GetProviderFactories(),
+		CheckDestroy:      checkExtensionDestroyed,
+		Steps: []resource.TestStep{
+			{
+				Config: hclExtensionBasic(publisherId, extensionId),
+				Check: resource.ComposeTestCheckFunc(
+					checkExtensionExist(extensionId),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_name"),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_name"),
+					resource.TestCheckResourceAttrSet(tfNode, "scope.#"),
+					resource.TestCheckResourceAttrSet(tfNode, "version"),
+					resource.TestCheckResourceAttrSet(tfNode, "disabled"),
+				),
+			},
+			{
+				ResourceName:      tfNode,
+				ImportState:       true,
+				ImportStateId:     fmt.Sprintf("%s/%s", publisherId, extensionId),
+				ImportStateVerify: true,
+			},
+			{
+				Config: hclExtensionUpdate(publisherId, extensionId, true),
+				Check: resource.ComposeTestCheckFunc(
+					checkExtensionExist(extensionId),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_name"),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_name"),
+					resource.TestCheckResourceAttr(tfNode, "disabled", "true"),
+				),
+			},
+			{
+				ResourceName:      tfNode,
+				ImportState:       true,
+				ImportStateId:     fmt.Sprintf("%s/%s", publisherId, extensionId),
+				ImportStateVerify: true,
+			},
+			{
+				Config: hclExtensionUpdate(publisherId, extensionId, false),
+				Check: resource.ComposeTestCheckFunc(
+					checkExtensionExist(extensionId),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_name"),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_name"),
+					resource.TestCheckResourceAttrSet(tfNode, "scope.#"),
+					resource.TestCheckResourceAttr(tfNode, "disabled", "false"),
+				),
+			},
+			{
+				ResourceName:      tfNode,
+				ImportState:       true,
+				ImportStateId:     fmt.Sprintf("%s/%s", publisherId, extensionId),
+				ImportStateVerify: true,
+			},
+		},
+	})
+}
+
+func TestAccExtension_requireImportError(t *testing.T) {
+	publisherId := "ms-securitydevops"
+	extensionId := "microsoft-security-devops-azdevops"
+	tfNode := "azuredevops_extension.test"
+	resource.Test(t, resource.TestCase{
+		PreCheck:          func() { testutils.PreCheck(t, nil) },
+		ProviderFactories: testutils.GetProviderFactories(),
+		CheckDestroy:      checkExtensionDestroyed,
+		Steps: []resource.TestStep{
+			{
+				Config: hclExtensionBasic(publisherId, extensionId),
+				Check: resource.ComposeTestCheckFunc(
+					checkExtensionExist(extensionId),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_id"),
+					resource.TestCheckResourceAttrSet(tfNode, "publisher_name"),
+					resource.TestCheckResourceAttrSet(tfNode, "extension_name"),
+					resource.TestCheckResourceAttrSet(tfNode, "scope.#"),
+					resource.TestCheckResourceAttrSet(tfNode, "version"),
+					resource.TestCheckResourceAttrSet(tfNode, "disabled"),
+				),
+			},
+			{
+				ResourceName:      tfNode,
+				ImportState:       true,
+				ImportStateId:     fmt.Sprintf("%s/%s", publisherId, extensionId),
+				ImportStateVerify: true,
+			},
+			{
+				Config:      hclExtensionImportError(publisherId, extensionId),
+				ExpectError: requiresExtensionImportError(publisherId, extensionId),
+			},
+		},
+	})
+}
+
+func checkExtensionDestroyed(s *terraform.State) error {
+	clients := testutils.GetProvider().Meta().(*client.AggregatedClient)
+	for _, res := range s.RootModule().Resources {
+		if res.Type != "azuredevops_extension" {
+			continue
+		}
+		ids := strings.Split(res.Primary.ID, "/")
+
+		_, err := clients.ExtensionManagementClient.GetInstalledExtensionByName(clients.Ctx, extensionmanagement.GetInstalledExtensionByNameArgs{
+			PublisherName: &ids[0],
+			ExtensionName: &ids[1],
+		})
+
+		if err == nil {
+			return fmt.Errorf(" Extension with Publisher ID=%s , Extension ID: %s should not exist", ids[0], ids[1])
+		}
+	}
+	return nil
+}
+
+func checkExtensionExist(expectedExtensionId string) resource.TestCheckFunc {
+	return func(s *terraform.State) error {
+		res, ok := s.RootModule().Resources["azuredevops_extension.test"]
+		if !ok {
+			return fmt.Errorf(" Did not find `azuredevops_extension` in the TF state")
+		}
+
+		clients := testutils.GetProvider().Meta().(*client.AggregatedClient)
+		ids := strings.Split(res.Primary.ID, "/")
+
+		extension, err := clients.ExtensionManagementClient.GetInstalledExtensionByName(clients.Ctx, extensionmanagement.GetInstalledExtensionByNameArgs{
+			PublisherName: &ids[0],
+			ExtensionName: &ids[1],
+		})
+
+		if err != nil {
+			return fmt.Errorf(" Extension with Publisher ID=%s , Extension ID: %s cannot be found!. Error=%v", ids[0], ids[1], err)
+		}
+
+		if *extension.ExtensionId != expectedExtensionId {
+			return fmt.Errorf(" Extension with Publisher ID=%s has Extension ID=%s, but expected Extension ID=%s", *extension.PublisherId, *extension.ExtensionId, expectedExtensionId)
+		}
+		return nil
+	}
+}
+
+func requiresExtensionImportError(publisherId, extensionId string) *regexp.Regexp {
+	message := "Installing extension for Publisher: %s, Name: %s. Error: TF1590010: Extension %s.%s is already installed in this organization"
+	return regexp.MustCompile(fmt.Sprintf(message, publisherId, extensionId, publisherId, extensionId))
+}
+
+func hclExtensionBasic(publisherId, extensionId string) string {
+	return fmt.Sprintf(`
+resource "azuredevops_extension" "test" {
+  publisher_id = "%s"
+  extension_id = "%s"
+}`, publisherId, extensionId)
+}
+
+func hclExtensionComplete(publisherId, extensionId string) string {
+	return fmt.Sprintf(`
+resource "azuredevops_extension" "test" {
+  publisher_id = "%s"
+  extension_id = "%s"
+  disabled     = false
+}`, publisherId, extensionId)
+}
+
+func hclExtensionUpdate(publisherId, extensionId string, disabled bool) string {
+	return fmt.Sprintf(`
+resource "azuredevops_extension" "test" {
+  publisher_id = "%s"
+  extension_id = "%s"
+  disabled     = %t
+}`, publisherId, extensionId, disabled)
+}
+
+func hclExtensionImportError(publisherId, extensionId string) string {
+	return fmt.Sprintf(`
+%s
+
+resource "azuredevops_extension" "import" {
+  publisher_id = azuredevops_extension.test.publisher_id
+  extension_id = azuredevops_extension.test.extension_id
+}`, hclExtensionBasic(publisherId, extensionId))
+}
diff --git a/azuredevops/provider_test.go b/azuredevops/provider_test.go
index 6588942d..c00312d1 100644
--- a/azuredevops/provider_test.go
+++ b/azuredevops/provider_test.go
@@ -56,6 +56,7 @@ func TestProvider_HasChildResources(t *testing.T) {
 		"azuredevops_elastic_pool",
 		"azuredevops_environment",
 		"azuredevops_environment_resource_kubernetes",
+		"azuredevops_extension",
 		"azuredevops_feed",
 		"azuredevops_feed_permission",
 		"azuredevops_feed_retention_policy",