public async Task <APITemplateResource> CreateAPITemplateResourceAsync(APIConfig api, bool isSplit, bool isInitial)
        {
            // create api resource
            APITemplateResource apiTemplateResource = new APITemplateResource()
            {
                name       = MakeResourceName(api),
                type       = ResourceTypeConstants.API,
                apiVersion = GlobalConstants.APIVersion,
                properties = new APITemplateProperties(),
                dependsOn  = new string[] { }
            };

            // add properties depending on whether the template is the initial, subsequent, or unified
            if (!isSplit || !isInitial)
            {
                // add metadata properties for initial and unified templates
                apiTemplateResource.properties.apiVersion                    = api.apiVersion;
                apiTemplateResource.properties.serviceUrl                    = MakeServiceUrl(api);
                apiTemplateResource.properties.type                          = api.type;
                apiTemplateResource.properties.apiType                       = api.type;
                apiTemplateResource.properties.description                   = api.description;
                apiTemplateResource.properties.subscriptionRequired          = api.subscriptionRequired;
                apiTemplateResource.properties.apiRevision                   = api.apiRevision;
                apiTemplateResource.properties.apiRevisionDescription        = api.apiRevisionDescription;
                apiTemplateResource.properties.apiVersionDescription         = api.apiVersionDescription;
                apiTemplateResource.properties.authenticationSettings        = api.authenticationSettings;
                apiTemplateResource.properties.subscriptionKeyParameterNames = api.subscriptionKeyParameterNames;
                apiTemplateResource.properties.path                          = api.suffix;
                apiTemplateResource.properties.isCurrent                     = api.isCurrent;
                apiTemplateResource.properties.displayName                   = string.IsNullOrEmpty(api.displayName) ? api.name : api.displayName;
                apiTemplateResource.properties.protocols                     = this.CreateProtocols(api);
                // set the version set id
                if (api.apiVersionSetId != null)
                {
                    // point to the supplied version set if the apiVersionSetId is provided
                    apiTemplateResource.properties.apiVersionSetId = $"[resourceId('Microsoft.ApiManagement/service/apiVersionSets', parameters('{ParameterNames.ApimServiceName}'), '{api.apiVersionSetId}')]";
                }
                // set the authorization server id
                if (api.authenticationSettings != null && api.authenticationSettings.oAuth2 != null && api.authenticationSettings.oAuth2.authorizationServerId != null &&
                    apiTemplateResource.properties.authenticationSettings != null && apiTemplateResource.properties.authenticationSettings.oAuth2 != null && apiTemplateResource.properties.authenticationSettings.oAuth2.authorizationServerId != null)
                {
                    apiTemplateResource.properties.authenticationSettings.oAuth2.authorizationServerId = api.authenticationSettings.oAuth2.authorizationServerId;
                }
                // set the subscriptionKey Parameter Names
                if (api.subscriptionKeyParameterNames != null)
                {
                    if (api.subscriptionKeyParameterNames.header != null)
                    {
                        apiTemplateResource.properties.subscriptionKeyParameterNames.header = api.subscriptionKeyParameterNames.header;
                    }
                    if (api.subscriptionKeyParameterNames.query != null)
                    {
                        apiTemplateResource.properties.subscriptionKeyParameterNames.query = api.subscriptionKeyParameterNames.query;
                    }
                }
            }
            if (!isSplit || isInitial)
            {
                // add open api spec properties for subsequent and unified templates
                string format;
                string value;

                // determine if the open api spec is remote or local, yaml or json
                bool isJSON = false;
                bool isUrl  = IsUri(api, out var _);

                string fileContents = null;
                if (!isUrl || api.openApiSpecFormat == OpenApiSpecFormat.Unspecified)
                {
                    fileContents = await this.fileReader.RetrieveFileContentsAsync(api.openApiSpec);
                }

                value = isUrl
                    ? api.openApiSpec
                    : fileContents
                ;

                bool isVersionThree = false;
                if (api.openApiSpecFormat == OpenApiSpecFormat.Unspecified)
                {
                    isJSON = this.fileReader.isJSON(fileContents);

                    if (isJSON == true)
                    {
                        var openAPISpecReader = new OpenAPISpecReader();
                        isVersionThree = await openAPISpecReader.isJSONOpenAPISpecVersionThreeAsync(api.openApiSpec);
                    }
                    format = GetOpenApiSpecFormat(isUrl, isJSON, isVersionThree);
                }

                else
                {
                    isJSON = IsOpenApiSpecJson(api.openApiSpecFormat);
                    format = GetOpenApiSpecFormat(isUrl, api.openApiSpecFormat);
                }

                // if the title needs to be modified
                // we need to embed the OpenAPI definition

                if (!string.IsNullOrEmpty(api.displayName))
                {
                    format = GetOpenApiSpecFormat(false, isJSON, isVersionThree);

                    // download definition

                    if (isUrl)
                    {
                        using (var client = new WebClient())
                            value = client.DownloadString(value);
                    }

                    // update title

                    value = new OpenApi(value, format)
                            .SetTitle(api.displayName)
                            .GetDefinition()
                    ;
                }

                // set the version set id
                if (api.apiVersionSetId != null)
                {
                    // point to the supplied version set if the apiVersionSetId is provided
                    apiTemplateResource.properties.apiVersionSetId = $"[resourceId('Microsoft.ApiManagement/service/apiVersionSets', parameters('{ParameterNames.ApimServiceName}'), '{api.apiVersionSetId}')]";
                }
                apiTemplateResource.properties.format = format;
                apiTemplateResource.properties.value  = value;
                apiTemplateResource.properties.path   = api.suffix;
                if (!String.IsNullOrEmpty(api.serviceUrl))
                {
                    apiTemplateResource.properties.serviceUrl = MakeServiceUrl(api);
                }
            }
            return(apiTemplateResource);
        }
        public async Task <APITemplateResource> CreateAPITemplateResourceAsync(APIConfig api, bool isSplit, bool isInitial)
        {
            // create api resource
            APITemplateResource apiTemplateResource = new APITemplateResource()
            {
                name       = $"[concat(parameters('ApimServiceName'), '/{api.name}')]",
                type       = ResourceTypeConstants.API,
                apiVersion = GlobalConstants.APIVersion,
                properties = new APITemplateProperties(),
                dependsOn  = new string[] { }
            };

            // add properties depending on whether the template is the initial, subsequent, or unified
            if (!isSplit || isInitial)
            {
                // add metadata properties for initial and unified templates
                apiTemplateResource.properties.apiVersion             = api.apiVersion;
                apiTemplateResource.properties.serviceUrl             = api.serviceUrl;
                apiTemplateResource.properties.type                   = api.type;
                apiTemplateResource.properties.apiType                = api.type;
                apiTemplateResource.properties.description            = api.description;
                apiTemplateResource.properties.subscriptionRequired   = api.subscriptionRequired;
                apiTemplateResource.properties.apiRevision            = api.apiRevision;
                apiTemplateResource.properties.apiRevisionDescription = api.apiRevisionDescription;
                apiTemplateResource.properties.apiVersionDescription  = api.apiVersionDescription;
                apiTemplateResource.properties.authenticationSettings = api.authenticationSettings;
                apiTemplateResource.properties.path                   = api.suffix;
                apiTemplateResource.properties.isCurrent              = api.isCurrent;
                apiTemplateResource.properties.displayName            = api.name;
                apiTemplateResource.properties.protocols              = this.CreateProtocols(api);
                // set the version set id
                if (api.apiVersionSetId != null)
                {
                    // point to the supplied version set if the apiVersionSetId is provided
                    apiTemplateResource.properties.apiVersionSetId = $"[resourceId('Microsoft.ApiManagement/service/apiVersionSets', parameters('ApimServiceName'), '{api.apiVersionSetId}')]";
                }
                // set the authorization server id
                if (api.authenticationSettings != null && api.authenticationSettings.oAuth2 != null && api.authenticationSettings.oAuth2.authorizationServerId != null &&
                    apiTemplateResource.properties.authenticationSettings != null && apiTemplateResource.properties.authenticationSettings.oAuth2 != null && apiTemplateResource.properties.authenticationSettings.oAuth2.authorizationServerId != null)
                {
                    apiTemplateResource.properties.authenticationSettings.oAuth2.authorizationServerId = api.authenticationSettings.oAuth2.authorizationServerId;
                }
            }
            if (!isSplit || !isInitial)
            {
                // add open api spec properties for subsequent and unified templates
                string format;
                string value;

                // determine if the open api spec is remote or local, yaml or json
                Uri    uriResult;
                string fileContents = await this.fileReader.RetrieveFileContentsAsync(api.openApiSpec);

                bool isJSON = this.fileReader.isJSON(fileContents);
                bool isUrl  = Uri.TryCreate(api.openApiSpec, UriKind.Absolute, out uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);

                if (isUrl == true)
                {
                    value = api.openApiSpec;
                    if (isJSON == true)
                    {
                        // open api spec is remote json file, use swagger-link-json for v2 and openapi-link for v3
                        OpenAPISpecReader openAPISpecReader = new OpenAPISpecReader();
                        bool isVersionThree = await openAPISpecReader.isJSONOpenAPISpecVersionThreeAsync(api.openApiSpec);

                        format = isVersionThree == false ? "swagger-link-json" : "openapi-link";
                    }
                    else
                    {
                        // open api spec is remote yaml file
                        format = "openapi-link";
                    }
                }
                else
                {
                    value = fileContents;
                    if (isJSON == true)
                    {
                        // open api spec is local json file, use swagger-json for v2 and openapi+json for v3
                        OpenAPISpecReader openAPISpecReader = new OpenAPISpecReader();
                        bool isVersionThree = await openAPISpecReader.isJSONOpenAPISpecVersionThreeAsync(api.openApiSpec);

                        format = isVersionThree == false ? "swagger-json" : "openapi+json";
                    }
                    else
                    {
                        // open api spec is local yaml file
                        format = "openapi";
                    }
                }
                apiTemplateResource.properties.format = format;
                apiTemplateResource.properties.value  = value;
                apiTemplateResource.properties.path   = api.suffix;
            }
            return(apiTemplateResource);
        }
        public async Task <APITemplateResource> CreateAPITemplateResourceAsync(APIConfig api, bool isSplit, bool isInitial, bool mergeTemplates = false)
        {
            // create api resource
            APITemplateResource apiTemplateResource = new APITemplateResource()
            {
                name       = MakeResourceName(api),
                type       = ResourceTypeConstants.API,
                apiVersion = GlobalConstants.APIVersion,
                properties = new APITemplateProperties(),
                dependsOn  = new string[] { }
            };

            // add properties depending on whether the template is the initial, subsequent, or unified
            if (!isSplit || !isInitial)
            {
                // add metadata properties for initial and unified templates
                apiTemplateResource.properties.apiVersion                    = api.apiVersion;
                apiTemplateResource.properties.serviceUrl                    = $"[parameters('{ParameterNames.ServiceUrl}')]";
                apiTemplateResource.properties.type                          = api.type;
                apiTemplateResource.properties.apiType                       = api.type;
                apiTemplateResource.properties.description                   = api.description;
                apiTemplateResource.properties.subscriptionRequired          = api.subscriptionRequired;
                apiTemplateResource.properties.apiRevision                   = api.apiRevision;
                apiTemplateResource.properties.apiRevisionDescription        = api.apiRevisionDescription;
                apiTemplateResource.properties.apiVersionDescription         = api.apiVersionDescription;
                apiTemplateResource.properties.authenticationSettings        = api.authenticationSettings;
                apiTemplateResource.properties.subscriptionKeyParameterNames = api.subscriptionKeyParameterNames;
                apiTemplateResource.properties.path                          = api.suffix;
                apiTemplateResource.properties.isCurrent                     = api.isCurrent;
                apiTemplateResource.properties.displayName                   = string.IsNullOrEmpty(api.displayName) ? api.name : api.displayName;
                apiTemplateResource.properties.protocols                     = this.CreateProtocols(api);
                // set the version set id
                if (api.apiVersionSetId != null)
                {
                    // point to the supplied version set if the apiVersionSetId is provided
                    apiTemplateResource.properties.apiVersionSetId = $"[resourceId('Microsoft.ApiManagement/service/apiVersionSets', parameters('{ParameterNames.ApimServiceName}'), '{api.apiVersionSetId}')]";
                }
                // set the authorization server id
                if (api.authenticationSettings != null && api.authenticationSettings.oAuth2 != null && api.authenticationSettings.oAuth2.authorizationServerId != null &&
                    apiTemplateResource.properties.authenticationSettings != null && apiTemplateResource.properties.authenticationSettings.oAuth2 != null && apiTemplateResource.properties.authenticationSettings.oAuth2.authorizationServerId != null)
                {
                    apiTemplateResource.properties.authenticationSettings.oAuth2.authorizationServerId = api.authenticationSettings.oAuth2.authorizationServerId;
                }
                // set the subscriptionKey Parameter Names
                if (api.subscriptionKeyParameterNames != null)
                {
                    if (api.subscriptionKeyParameterNames.header != null)
                    {
                        apiTemplateResource.properties.subscriptionKeyParameterNames.header = api.subscriptionKeyParameterNames.header;
                    }
                    if (api.subscriptionKeyParameterNames.query != null)
                    {
                        apiTemplateResource.properties.subscriptionKeyParameterNames.query = api.subscriptionKeyParameterNames.query;
                    }
                }
            }
            if (!isSplit || isInitial)
            {
                // add open api spec properties for subsequent and unified templates
                string format;
                string value;

                // determine if the open api spec is remote or local, yaml or json
                Uri    uriResult;
                string fileContents = await this.fileReader.RetrieveFileContentsAsync(api.openApiSpec);

                bool isJSON = this.fileReader.isJSON(fileContents);
                bool isUrl  = Uri.TryCreate(api.openApiSpec, UriKind.Absolute, out uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);

                value = isUrl
                    ? api.openApiSpec
                    : fileContents
                ;

                bool isVersionThree = false;
                if (isJSON == true)
                {
                    // open api spec is remote json file, use swagger-link-json for v2 and openapi-link for v3
                    OpenAPISpecReader openAPISpecReader = new OpenAPISpecReader();
                    isVersionThree = await openAPISpecReader.isJSONOpenAPISpecVersionThreeAsync(api.openApiSpec);
                }

                format = isUrl
                    ? (isJSON ? (isVersionThree ? "openapi-link" : "swagger-link-json") : "openapi-link")
                    : (isJSON ? (isVersionThree ? "openapi+json" : "swagger-json") : "openapi")
                ;

                // if the title needs to be modified
                // we need to embed the OpenAPI definition

                if (!string.IsNullOrEmpty(api.displayName))
                {
                    format = (isJSON ? (isVersionThree ? "openapi+json" : "swagger-json") : "openapi");

                    // download definition

                    if (isUrl)
                    {
                        using (var client = new WebClient())
                            value = client.DownloadString(value);
                    }

                    // update title

                    value = new OpenApi(value, format)
                            .SetTitle(api.displayName)
                            .GetDefinition()
                    ;
                }
                // set the version set id
                if (api.apiVersionSetId != null)
                {
                    // point to the supplied version set if the apiVersionSetId is provided
                    apiTemplateResource.properties.apiVersionSetId = $"[resourceId('Microsoft.ApiManagement/service/apiVersionSets', parameters('{ParameterNames.ApimServiceName}'), '{api.apiVersionSetId}')]";
                }
                apiTemplateResource.properties.apiVersion = api.apiVersion;
                apiTemplateResource.properties.format     = format;
                apiTemplateResource.properties.value      = value;
                apiTemplateResource.properties.path       = api.suffix;
                apiTemplateResource.properties.serviceUrl = $"[parameters('{ParameterNames.ServiceUrl}')]";
                if (mergeTemplates)
                {
                    apiTemplateResource.dependsOn = apiTemplateResource.dependsOn.Append($"[resourceId('Microsoft.ApiManagement/service/apiVersionSets', parameters('{ParameterNames.ApimServiceName}'), '{api.apiVersionSetId}')]").ToArray();
                }
            }
            return(apiTemplateResource);
        }