/* jshint latedef:false */
/* jshint forin:false */
/* jshint noempty:false */

// 
// Copyright (c) Microsoft and contributors.  All rights reserved.
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//   http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// 
// See the License for the specific language governing permissions and
// limitations under the License.
// 

// Warning: This code was generated by a tool.
// 
// Changes to this file may cause incorrect behavior and will be lost if the
// code is regenerated.

'use strict';

var util = require('util');
var azureCommon = require('azure-common');
var xml = azureCommon.xml2js;
var js2xml = azureCommon.js2xml;
var Service = azureCommon.Service;
var WebResource = azureCommon.WebResource;

var StoreManagementClient = ( /** @lends StoreManagementClient */ function() {
  /**
   * @class
   * The Windows Azure Store API is a REST API for managing Windows Azure Store
   * add-ins.
   * Initializes a new instance of the StoreManagementClient class.
   * @constructor
   * 
   * @param {SubscriptionCloudCredentials} credentials Gets subscription
   * credentials which uniquely identify Microsoft Azure subscription. The
   * subscription ID forms part of the URI for every service call.
   * 
   * @param {string} [credentials.subscriptionId]
   * 
   * @param {string} [baseUri] Gets the URI used as the base for all cloud
   * service requests.
   * 
   * @param {Array} filters
   */
  function StoreManagementClient(credentials, baseUri, filters) {
    if (credentials === null || credentials === undefined) {
      throw new Error('credentials cannot be null.');
    }
    
    StoreManagementClient['super_'].call(this, credentials, filters);
    
    this.credentials = credentials;
    this.baseUri = baseUri;
    if (this.baseUri === null || this.baseUri === undefined) {
      this.baseUri = 'https://management.core.windows.net';
    }
    if (this.apiVersion === null || this.apiVersion === undefined) {
      this.apiVersion = '2013-06-01';
    }
    if (this.longRunningOperationInitialTimeout === null || this.longRunningOperationInitialTimeout === undefined) {
      this.longRunningOperationInitialTimeout = -1;
    }
    if (this.longRunningOperationRetryTimeout === null || this.longRunningOperationRetryTimeout === undefined) {
      this.longRunningOperationRetryTimeout = -1;
    }
    /**
     * Provides an instance of the [AddOnOperations](-AddOnOperations.html)
     * object.
     * @type {object}
     */
    this.addOns = new AddOnOperations(this);
    /**
     * Provides an instance of the
     * [CloudServiceOperations](-CloudServiceOperations.html) object.
     * @type {object}
     */
    this.cloudServices = new CloudServiceOperations(this);
  }
  
  util.inherits(StoreManagementClient, Service);
  
  /**
   * The Get Operation Status operation returns the status of thespecified
   * operation. After calling an asynchronous operation, you can call Get
   * Operation Status to determine whether the operation has succeeded,
   * failed, or is still in progress.  (see
   * http://msdn.microsoft.com/en-us/library/windowsazure/ee460783.aspx for
   * more information)
   * 
   * @param {string} requestId The request ID for the request you wish to
   * track. The request ID is returned in the x-ms-request-id response header
   * for every request.
   * 
   * @param {function} callback
   * 
   * @returns {Stream} The response stream.
   */
  StoreManagementClient.prototype.getOperationStatus = function(requestId, callback) {
    if (callback === null || callback === undefined) {
      throw new Error('callback cannot be null.');
    }
    // Validate
    if (requestId === null || requestId === undefined) {
      return callback(new Error('requestId cannot be null.'));
    }
    
    // Tracing
    
    // Construct URL
    var url2 = '';
    url2 = url2 + '/';
    if (this.credentials.subscriptionId !== null && this.credentials.subscriptionId !== undefined) {
      url2 = url2 + encodeURIComponent(this.credentials.subscriptionId);
    }
    url2 = url2 + '/operations/';
    url2 = url2 + encodeURIComponent(requestId);
    var baseUrl = this.baseUri;
    // Trim '/' character from the end of baseUrl and beginning of url.
    if (baseUrl[baseUrl.length - 1] === '/') {
      baseUrl = baseUrl.substring(0, (baseUrl.length - 1) + 0);
    }
    if (url2[0] === '/') {
      url2 = url2.substring(1);
    }
    url2 = baseUrl + '/' + url2;
    url2 = url2.replace(' ', '%20');
    
    // Create HTTP transport objects
    var httpRequest = new WebResource();
    httpRequest.method = 'GET';
    httpRequest.headers = {};
    httpRequest.url = url2;
    
    // Set Headers
    httpRequest.headers['x-ms-version'] = '2013-06-01';
    
    // Send Request
    return this.pipeline(httpRequest, function (err, response, body) {
      if (err !== null && err !== undefined) {
        return callback(err);
      }
      var statusCode = response.statusCode;
      if (statusCode !== 200) {
        var error = new Error(body);
        error.statusCode = response.statusCode;
        return callback(error);
      }
      
      // Create Result
      var result = null;
      // Deserialize Response
      if (statusCode === 200) {
        var responseContent = body;
        result = {};
        var options = {};
        options.trim = false;
        options.strict = false;
        xml.parseString(responseContent, options, function (err2, responseDoc) {
          if (err2 !== null && err2 !== undefined) {
            return callback(err2);
          }
          
          var operationElement = js2xml.getElement(responseDoc, responseDoc, 'OPERATION', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
          if (operationElement !== null && operationElement !== undefined) {
            var idElement = js2xml.getElement(responseDoc, operationElement, 'ID', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
            if (idElement !== null && idElement !== undefined) {
              var idInstance = idElement;
              result.id = idInstance;
            }
            
            var statusElement = js2xml.getElement(responseDoc, operationElement, 'STATUS', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
            if (statusElement !== null && statusElement !== undefined && statusElement.length !== 0) {
              var statusInstance = statusElement;
              result.status = statusInstance;
            }
            
            var httpStatusCodeElement = js2xml.getElement(responseDoc, operationElement, 'HTTPSTATUSCODE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
            if (httpStatusCodeElement !== null && httpStatusCodeElement !== undefined && httpStatusCodeElement.length !== 0) {
              var httpStatusCodeInstance = httpStatusCodeElement;
              result.httpStatusCode = httpStatusCodeInstance;
            }
            
            var errorElement = js2xml.getElement(responseDoc, operationElement, 'ERROR', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
            if (errorElement !== null && errorElement !== undefined) {
              var errorInstance = {};
              result.error = errorInstance;
              
              var codeElement = js2xml.getElement(responseDoc, errorElement, 'CODE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
              if (codeElement !== null && codeElement !== undefined) {
                var codeInstance = codeElement;
                errorInstance.code = codeInstance;
              }
              
              var messageElement = js2xml.getElement(responseDoc, errorElement, 'MESSAGE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
              if (messageElement !== null && messageElement !== undefined) {
                var messageInstance = messageElement;
                errorInstance.message = messageInstance;
              }
            }
          }
          
        });
      }
      result.statusCode = statusCode;
      result.requestId = response.headers['x-ms-request-id'];
      
      return callback(null, result);
    });
  };
  
  return StoreManagementClient;
})();
exports.StoreManagementClient = StoreManagementClient;

var AddOnOperations = ( /** @lends AddOnOperations */ function() {
  /**
   * @class
   * Provides REST operations for working with Store add-ins from the Windows
   * Azure store service.
   * __NOTE__: An instance of this class is automatically created for an
   * instance of the [StoreManagementClient] {@link
   * StoreManagementClient~StoreManagementClient}.
   * See [addOns] {@link StoreManagementClient~StoreManagementClient#addOns}.
   * Initializes a new instance of the AddOnOperations class.
   * @constructor
   * 
   * @param {StoreManagementClient} client Reference to the service client.
   */
  function AddOnOperations(client) {
    this.client = client;
  }
  
  /**
   * The Create Store Item operation creates Windows Azure Store entries in a
   * Windows Azure subscription.
   * 
   * @param {string} cloudServiceName The name of the cloud service to which
   * this store item will be assigned.
   * 
   * @param {string} resourceName The name of this resource.
   * 
   * @param {string} addOnName The add on name.
   * 
   * @param {AddOnCreateParameters} parameters Parameters used to specify how
   * the Create procedure will function.
   * 
   * @param {string} parameters.type The type of store item to be created.
   * 
   * @param {string} parameters.plan The selected plan for this store addon.
   * 
   * @param {string} [parameters.promotionCode] The promotion code for this
   * store addon.
   * 
   * @param {function} callback
   * 
   * @returns {Stream} The response stream.
   */
  AddOnOperations.prototype.beginCreating = function(cloudServiceName, resourceName, addOnName, parameters, callback) {
    if (callback === null || callback === undefined) {
      throw new Error('callback cannot be null.');
    }
    // Validate
    if (cloudServiceName === null || cloudServiceName === undefined) {
      return callback(new Error('cloudServiceName cannot be null.'));
    }
    if (resourceName === null || resourceName === undefined) {
      return callback(new Error('resourceName cannot be null.'));
    }
    if (addOnName === null || addOnName === undefined) {
      return callback(new Error('addOnName cannot be null.'));
    }
    if (parameters === null || parameters === undefined) {
      return callback(new Error('parameters cannot be null.'));
    }
    if (parameters.plan === null || parameters.plan === undefined) {
      return callback(new Error('parameters.plan cannot be null.'));
    }
    if (parameters.type === null || parameters.type === undefined) {
      return callback(new Error('parameters.type cannot be null.'));
    }
    
    // Tracing
    
    // Construct URL
    var url2 = '';
    url2 = url2 + '/';
    if (this.client.credentials.subscriptionId !== null && this.client.credentials.subscriptionId !== undefined) {
      url2 = url2 + encodeURIComponent(this.client.credentials.subscriptionId);
    }
    url2 = url2 + '/CloudServices/';
    url2 = url2 + encodeURIComponent(cloudServiceName);
    url2 = url2 + '/resources/';
    url2 = url2 + encodeURIComponent(parameters.type);
    url2 = url2 + '/';
    url2 = url2 + encodeURIComponent(resourceName);
    url2 = url2 + '/';
    url2 = url2 + encodeURIComponent(addOnName);
    var baseUrl = this.client.baseUri;
    // Trim '/' character from the end of baseUrl and beginning of url.
    if (baseUrl[baseUrl.length - 1] === '/') {
      baseUrl = baseUrl.substring(0, (baseUrl.length - 1) + 0);
    }
    if (url2[0] === '/') {
      url2 = url2.substring(1);
    }
    url2 = baseUrl + '/' + url2;
    url2 = url2.replace(' ', '%20');
    
    // Create HTTP transport objects
    var httpRequest = new WebResource();
    httpRequest.method = 'PUT';
    httpRequest.headers = {};
    httpRequest.url = url2;
    
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/xml';
    httpRequest.headers['x-ms-version'] = '2013-06-01';
    
    // Serialize Request
    var requestContent = null;
    var requestDoc = {};
    
    var resourceElement = js2xml.createElement('Resource', 'http://schemas.microsoft.com/windowsazure');
    js2xml.addChildElement(requestDoc, resourceElement);
    
    var typeElement = js2xml.createElement('Type', 'http://schemas.microsoft.com/windowsazure');
    js2xml.setElementValue(typeElement, parameters.type);
    js2xml.addChildElement(resourceElement, typeElement);
    
    var planElement = js2xml.createElement('Plan', 'http://schemas.microsoft.com/windowsazure');
    js2xml.setElementValue(planElement, parameters.plan);
    js2xml.addChildElement(resourceElement, planElement);
    
    if (parameters.promotionCode !== null && parameters.promotionCode !== undefined) {
      var promotionCodeElement = js2xml.createElement('PromotionCode', 'http://schemas.microsoft.com/windowsazure');
      js2xml.setElementValue(promotionCodeElement, parameters.promotionCode);
      js2xml.addChildElement(resourceElement, promotionCodeElement);
    }
    
    requestContent = js2xml.serializeDocument(requestDoc);
    httpRequest.body = requestContent;
    httpRequest.headers['Content-Length'] = Buffer.isBuffer(requestContent) ? requestContent.length : Buffer.byteLength(requestContent, 'UTF8');
    // Send Request
    return this.client.pipeline(httpRequest, function (err, response, body) {
      if (err !== null && err !== undefined) {
        return callback(err);
      }
      var statusCode = response.statusCode;
      if (statusCode !== 202) {
        var error = new Error(body);
        error.statusCode = response.statusCode;
        return callback(error);
      }
      
      // Create Result
      var result = null;
      // Deserialize Response
      result = {};
      result.statusCode = statusCode;
      result.requestId = response.headers['x-ms-request-id'];
      
      return callback(null, result);
    });
  };
  
  /**
   * The Delete Store Item operation deletes Windows Azure Store entries that
   * re provisioned for a subscription.
   * 
   * @param {string} cloudServiceName The name of the cloud service to which
   * this store item will be assigned.
   * 
   * @param {string} resourceProviderNamespace The namespace in which this
   * store item resides.
   * 
   * @param {string} resourceProviderType The type of store item to be deleted.
   * 
   * @param {string} resourceProviderName The name of this resource provider.
   * 
   * @param {function} callback
   * 
   * @returns {Stream} The response stream.
   */
  AddOnOperations.prototype.beginDeleting = function(cloudServiceName, resourceProviderNamespace, resourceProviderType, resourceProviderName, callback) {
    if (callback === null || callback === undefined) {
      throw new Error('callback cannot be null.');
    }
    // Validate
    if (cloudServiceName === null || cloudServiceName === undefined) {
      return callback(new Error('cloudServiceName cannot be null.'));
    }
    if (resourceProviderNamespace === null || resourceProviderNamespace === undefined) {
      return callback(new Error('resourceProviderNamespace cannot be null.'));
    }
    if (resourceProviderType === null || resourceProviderType === undefined) {
      return callback(new Error('resourceProviderType cannot be null.'));
    }
    if (resourceProviderName === null || resourceProviderName === undefined) {
      return callback(new Error('resourceProviderName cannot be null.'));
    }
    
    // Tracing
    
    // Construct URL
    var url2 = '';
    url2 = url2 + '/';
    if (this.client.credentials.subscriptionId !== null && this.client.credentials.subscriptionId !== undefined) {
      url2 = url2 + encodeURIComponent(this.client.credentials.subscriptionId);
    }
    url2 = url2 + '/CloudServices/';
    url2 = url2 + encodeURIComponent(cloudServiceName);
    url2 = url2 + '/resources/';
    url2 = url2 + encodeURIComponent(resourceProviderNamespace);
    url2 = url2 + '/';
    url2 = url2 + encodeURIComponent(resourceProviderType);
    url2 = url2 + '/';
    url2 = url2 + encodeURIComponent(resourceProviderName);
    var baseUrl = this.client.baseUri;
    // Trim '/' character from the end of baseUrl and beginning of url.
    if (baseUrl[baseUrl.length - 1] === '/') {
      baseUrl = baseUrl.substring(0, (baseUrl.length - 1) + 0);
    }
    if (url2[0] === '/') {
      url2 = url2.substring(1);
    }
    url2 = baseUrl + '/' + url2;
    url2 = url2.replace(' ', '%20');
    
    // Create HTTP transport objects
    var httpRequest = new WebResource();
    httpRequest.method = 'DELETE';
    httpRequest.headers = {};
    httpRequest.url = url2;
    
    // Set Headers
    httpRequest.headers['x-ms-version'] = '2013-06-01';
    
    // Send Request
    return this.client.pipeline(httpRequest, function (err, response, body) {
      if (err !== null && err !== undefined) {
        return callback(err);
      }
      var statusCode = response.statusCode;
      if (statusCode !== 202) {
        var error = new Error(body);
        error.statusCode = response.statusCode;
        return callback(error);
      }
      
      // Create Result
      var result = null;
      // Deserialize Response
      result = {};
      result.statusCode = statusCode;
      result.requestId = response.headers['x-ms-request-id'];
      
      return callback(null, result);
    });
  };
  
  /**
   * The Create Store Item operation creates Windows Azure Store entries in a
   * Windows Azure subscription.
   * 
   * @param {string} cloudServiceName The name of the cloud service to which
   * this store item will be assigned.
   * 
   * @param {string} resourceName The name of this resource.
   * 
   * @param {string} addOnName The add on name.
   * 
   * @param {AddOnCreateParameters} parameters Parameters used to specify how
   * the Create procedure will function.
   * 
   * @param {string} parameters.type The type of store item to be created.
   * 
   * @param {string} parameters.plan The selected plan for this store addon.
   * 
   * @param {string} [parameters.promotionCode] The promotion code for this
   * store addon.
   * 
   * @param {function} callback
   * 
   * @returns {Stream} The response stream.
   */
  AddOnOperations.prototype.create = function(cloudServiceName, resourceName, addOnName, parameters, callback) {
    if (callback === null || callback === undefined) {
      throw new Error('callback cannot be null.');
    }
    var client2 = this.client;
    
    return client2.addOns.beginCreating(cloudServiceName, resourceName, addOnName, parameters, function (err, result) {
      if (err !== null && err !== undefined) {
        return callback(err);
      }
      if (result.status === 'Succeeded') {
        return callback(null, result);
      }
      var delayInSeconds = 30;
      if (client2.longRunningOperationInitialTimeout >= 0) {
        delayInSeconds = client2.longRunningOperationInitialTimeout;
      }
      
      var pollOperation = function () {
        setTimeout(function () {
          return client2.getOperationStatus(result.requestId, function (err2, result2) {
            if (err2 !== null && err2 !== undefined) {
              return callback(err2);
            } else {
              if (result2.status !== 'InProgress') {
                if (result2.status !== 'Succeeded') {
                  if (result2.error !== null && result2.error !== undefined) {
                    var ex = new Error(result2.error.code + ' : ' + result2.error.message);
                    ex.error = new Error();
                    ex.error.code = result2.error.code;
                    ex.error.message = result2.error.message;
                    return callback(ex);
                  } else {
                    var ex = new Error('');
                    return callback(ex);
                  }
                }
                
                return callback(null, result2);
              } else {
                delayInSeconds = 30;
                if (client2.longRunningOperationRetryTimeout >= 0) {
                  delayInSeconds = client2.longRunningOperationRetryTimeout;
                }
                pollOperation();
              }
            }
          });
        }, delayInSeconds * 1000);
      };
      
      pollOperation();
    });
  };
  
  /**
   * The Delete Store Item operation deletes Windows Azure Storeentries that
   * are provisioned for a subscription.
   * 
   * @param {string} cloudServiceName The name of the cloud service to which
   * this store item will be assigned.
   * 
   * @param {string} resourceProviderNamespace The namespace in which this
   * store item resides.
   * 
   * @param {string} resourceProviderType The type of store item to be deleted.
   * 
   * @param {string} resourceProviderName The name of this resource provider.
   * 
   * @param {function} callback
   * 
   * @returns {Stream} The response stream.
   */
  AddOnOperations.prototype.deleteMethod = function(cloudServiceName, resourceProviderNamespace, resourceProviderType, resourceProviderName, callback) {
    if (callback === null || callback === undefined) {
      throw new Error('callback cannot be null.');
    }
    var client2 = this.client;
    
    return client2.addOns.beginDeleting(cloudServiceName, resourceProviderNamespace, resourceProviderType, resourceProviderName, function (err, result) {
      if (err !== null && err !== undefined) {
        return callback(err);
      }
      if (result.status === 'Succeeded') {
        return callback(null, result);
      }
      var delayInSeconds = 30;
      if (client2.longRunningOperationInitialTimeout >= 0) {
        delayInSeconds = client2.longRunningOperationInitialTimeout;
      }
      
      var pollOperation = function () {
        setTimeout(function () {
          return client2.getOperationStatus(result.requestId, function (err2, result2) {
            if (err2 !== null && err2 !== undefined) {
              return callback(err2);
            } else {
              if (result2.status !== 'InProgress') {
                if (result2.status !== 'Succeeded') {
                  if (result2.error !== null && result2.error !== undefined) {
                    var ex = new Error(result2.error.code + ' : ' + result2.error.message);
                    ex.error = new Error();
                    ex.error.code = result2.error.code;
                    ex.error.message = result2.error.message;
                    return callback(ex);
                  } else {
                    var ex = new Error('');
                    return callback(ex);
                  }
                }
                
                return callback(null, result2);
              } else {
                delayInSeconds = 30;
                if (client2.longRunningOperationRetryTimeout >= 0) {
                  delayInSeconds = client2.longRunningOperationRetryTimeout;
                }
                pollOperation();
              }
            }
          });
        }, delayInSeconds * 1000);
      };
      
      pollOperation();
    });
  };
  
  /**
   * The Update Store Item operation creates Windows Azure Store entries in a
   * Windows Azure subscription.
   * 
   * @param {string} cloudServiceName The name of the cloud service to which
   * this store item will be assigned.
   * 
   * @param {string} resourceName The name of this resource.
   * 
   * @param {string} addOnName The addon name.
   * 
   * @param {AddOnUpdateParameters} parameters Parameters used to specify how
   * the Create procedure will function.
   * 
   * @param {string} parameters.type The type of store item to be created.
   * 
   * @param {string} parameters.plan The selected plan for this store addon.
   * 
   * @param {string} [parameters.promotionCode] The promotion code for this
   * store addon.
   * 
   * @param {function} callback
   * 
   * @returns {Stream} The response stream.
   */
  AddOnOperations.prototype.update = function(cloudServiceName, resourceName, addOnName, parameters, callback) {
    if (callback === null || callback === undefined) {
      throw new Error('callback cannot be null.');
    }
    // Validate
    if (cloudServiceName === null || cloudServiceName === undefined) {
      return callback(new Error('cloudServiceName cannot be null.'));
    }
    if (resourceName === null || resourceName === undefined) {
      return callback(new Error('resourceName cannot be null.'));
    }
    if (addOnName === null || addOnName === undefined) {
      return callback(new Error('addOnName cannot be null.'));
    }
    if (parameters === null || parameters === undefined) {
      return callback(new Error('parameters cannot be null.'));
    }
    if (parameters.plan === null || parameters.plan === undefined) {
      return callback(new Error('parameters.plan cannot be null.'));
    }
    if (parameters.type === null || parameters.type === undefined) {
      return callback(new Error('parameters.type cannot be null.'));
    }
    
    // Tracing
    
    // Construct URL
    var url2 = '';
    url2 = url2 + '/';
    if (this.client.credentials.subscriptionId !== null && this.client.credentials.subscriptionId !== undefined) {
      url2 = url2 + encodeURIComponent(this.client.credentials.subscriptionId);
    }
    url2 = url2 + '/CloudServices/';
    url2 = url2 + encodeURIComponent(cloudServiceName);
    url2 = url2 + '/resources/';
    url2 = url2 + encodeURIComponent(parameters.type);
    url2 = url2 + '/';
    url2 = url2 + encodeURIComponent(resourceName);
    url2 = url2 + '/';
    url2 = url2 + encodeURIComponent(addOnName);
    var baseUrl = this.client.baseUri;
    // Trim '/' character from the end of baseUrl and beginning of url.
    if (baseUrl[baseUrl.length - 1] === '/') {
      baseUrl = baseUrl.substring(0, (baseUrl.length - 1) + 0);
    }
    if (url2[0] === '/') {
      url2 = url2.substring(1);
    }
    url2 = baseUrl + '/' + url2;
    url2 = url2.replace(' ', '%20');
    
    // Create HTTP transport objects
    var httpRequest = new WebResource();
    httpRequest.method = 'PUT';
    httpRequest.headers = {};
    httpRequest.url = url2;
    
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/xml';
    httpRequest.headers['If-Match'] = '*';
    httpRequest.headers['x-ms-version'] = '2013-06-01';
    
    // Serialize Request
    var requestContent = null;
    var requestDoc = {};
    
    var resourceElement = js2xml.createElement('Resource', 'http://schemas.microsoft.com/windowsazure');
    js2xml.addChildElement(requestDoc, resourceElement);
    
    var typeElement = js2xml.createElement('Type', 'http://schemas.microsoft.com/windowsazure');
    js2xml.setElementValue(typeElement, parameters.type);
    js2xml.addChildElement(resourceElement, typeElement);
    
    var planElement = js2xml.createElement('Plan', 'http://schemas.microsoft.com/windowsazure');
    js2xml.setElementValue(planElement, parameters.plan);
    js2xml.addChildElement(resourceElement, planElement);
    
    if (parameters.promotionCode !== null && parameters.promotionCode !== undefined) {
      var promotionCodeElement = js2xml.createElement('PromotionCode', 'http://schemas.microsoft.com/windowsazure');
      js2xml.setElementValue(promotionCodeElement, parameters.promotionCode);
      js2xml.addChildElement(resourceElement, promotionCodeElement);
    }
    
    requestContent = js2xml.serializeDocument(requestDoc);
    httpRequest.body = requestContent;
    httpRequest.headers['Content-Length'] = Buffer.isBuffer(requestContent) ? requestContent.length : Buffer.byteLength(requestContent, 'UTF8');
    // Send Request
    return this.client.pipeline(httpRequest, function (err, response, body) {
      if (err !== null && err !== undefined) {
        return callback(err);
      }
      var statusCode = response.statusCode;
      if (statusCode !== 202) {
        var error = new Error(body);
        error.statusCode = response.statusCode;
        return callback(error);
      }
      
      // Create Result
      var result = null;
      // Deserialize Response
      result = {};
      result.statusCode = statusCode;
      result.requestId = response.headers['x-ms-request-id'];
      
      return callback(null, result);
    });
  };
  
  return AddOnOperations;
})();

var CloudServiceOperations = ( /** @lends CloudServiceOperations */ function() {
  /**
   * @class
   * Provides REST operations for working with cloud services from the Windows
   * Azure store service.
   * __NOTE__: An instance of this class is automatically created for an
   * instance of the [StoreManagementClient] {@link
   * StoreManagementClient~StoreManagementClient}.
   * See [cloudServices] {@link
   * StoreManagementClient~StoreManagementClient#cloudServices}.
   * Initializes a new instance of the CloudServiceOperations class.
   * @constructor
   * 
   * @param {StoreManagementClient} client Reference to the service client.
   */
  function CloudServiceOperations(client) {
    this.client = client;
  }
  
  /**
   * The Create Cloud Service operation creates a Windows Azure cloud service
   * in a Windows Azure subscription.
   * 
   * @param {CloudServiceCreateParameters} parameters Parameters used to
   * specify how the Create procedure will function.
   * 
   * @param {string} parameters.name The name of the cloud service to be
   * created.
   * 
   * @param {string} parameters.label The label of the cloud service to be
   * created.
   * 
   * @param {string} parameters.description The description for the cloud
   * service to be created.
   * 
   * @param {string} parameters.geoRegion The geographical region to create the
   * cloud service in.
   * 
   * @param {function} callback
   * 
   * @returns {Stream} The response stream.
   */
  CloudServiceOperations.prototype.beginCreating = function(parameters, callback) {
    if (callback === null || callback === undefined) {
      throw new Error('callback cannot be null.');
    }
    // Validate
    if (parameters === null || parameters === undefined) {
      return callback(new Error('parameters cannot be null.'));
    }
    if (parameters.description === null || parameters.description === undefined) {
      return callback(new Error('parameters.description cannot be null.'));
    }
    if (parameters.geoRegion === null || parameters.geoRegion === undefined) {
      return callback(new Error('parameters.geoRegion cannot be null.'));
    }
    if (parameters.label === null || parameters.label === undefined) {
      return callback(new Error('parameters.label cannot be null.'));
    }
    if (parameters.name === null || parameters.name === undefined) {
      return callback(new Error('parameters.name cannot be null.'));
    }
    
    // Tracing
    
    // Construct URL
    var url2 = '';
    url2 = url2 + '/';
    if (this.client.credentials.subscriptionId !== null && this.client.credentials.subscriptionId !== undefined) {
      url2 = url2 + encodeURIComponent(this.client.credentials.subscriptionId);
    }
    url2 = url2 + '/CloudServices/';
    url2 = url2 + encodeURIComponent(parameters.name);
    url2 = url2 + '/';
    var baseUrl = this.client.baseUri;
    // Trim '/' character from the end of baseUrl and beginning of url.
    if (baseUrl[baseUrl.length - 1] === '/') {
      baseUrl = baseUrl.substring(0, (baseUrl.length - 1) + 0);
    }
    if (url2[0] === '/') {
      url2 = url2.substring(1);
    }
    url2 = baseUrl + '/' + url2;
    url2 = url2.replace(' ', '%20');
    
    // Create HTTP transport objects
    var httpRequest = new WebResource();
    httpRequest.method = 'PUT';
    httpRequest.headers = {};
    httpRequest.url = url2;
    
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/xml';
    httpRequest.headers['x-ms-version'] = '2013-06-01';
    
    // Serialize Request
    var requestContent = null;
    var requestDoc = {};
    
    var cloudServiceElement = js2xml.createElement('CloudService', 'http://schemas.microsoft.com/windowsazure');
    js2xml.addChildElement(requestDoc, cloudServiceElement);
    
    var nameElement = js2xml.createElement('Name', 'http://schemas.microsoft.com/windowsazure');
    js2xml.setElementValue(nameElement, parameters.name);
    js2xml.addChildElement(cloudServiceElement, nameElement);
    
    var labelElement = js2xml.createElement('Label', 'http://schemas.microsoft.com/windowsazure');
    js2xml.setElementValue(labelElement, parameters.label);
    js2xml.addChildElement(cloudServiceElement, labelElement);
    
    var descriptionElement = js2xml.createElement('Description', 'http://schemas.microsoft.com/windowsazure');
    js2xml.setElementValue(descriptionElement, parameters.description);
    js2xml.addChildElement(cloudServiceElement, descriptionElement);
    
    var geoRegionElement = js2xml.createElement('GeoRegion', 'http://schemas.microsoft.com/windowsazure');
    js2xml.setElementValue(geoRegionElement, parameters.geoRegion);
    js2xml.addChildElement(cloudServiceElement, geoRegionElement);
    
    requestContent = js2xml.serializeDocument(requestDoc);
    httpRequest.body = requestContent;
    httpRequest.headers['Content-Length'] = Buffer.isBuffer(requestContent) ? requestContent.length : Buffer.byteLength(requestContent, 'UTF8');
    // Send Request
    return this.client.pipeline(httpRequest, function (err, response, body) {
      if (err !== null && err !== undefined) {
        return callback(err);
      }
      var statusCode = response.statusCode;
      if (statusCode !== 202) {
        var error = new Error(body);
        error.statusCode = response.statusCode;
        return callback(error);
      }
      
      // Create Result
      var result = null;
      // Deserialize Response
      result = {};
      result.statusCode = statusCode;
      result.requestId = response.headers['x-ms-request-id'];
      
      return callback(null, result);
    });
  };
  
  /**
   * The Create Cloud Service operation creates a Windows Azure cloud service
   * in a Windows Azure subscription.
   * 
   * @param {CloudServiceCreateParameters} parameters Parameters used to
   * specify how the Create procedure will function.
   * 
   * @param {string} parameters.name The name of the cloud service to be
   * created.
   * 
   * @param {string} parameters.label The label of the cloud service to be
   * created.
   * 
   * @param {string} parameters.description The description for the cloud
   * service to be created.
   * 
   * @param {string} parameters.geoRegion The geographical region to create the
   * cloud service in.
   * 
   * @param {function} callback
   * 
   * @returns {Stream} The response stream.
   */
  CloudServiceOperations.prototype.create = function(parameters, callback) {
    if (callback === null || callback === undefined) {
      throw new Error('callback cannot be null.');
    }
    var client2 = this.client;
    
    return client2.cloudServices.beginCreating(parameters, function (err, result) {
      if (err !== null && err !== undefined) {
        return callback(err);
      }
      if (result.status === 'Succeeded') {
        return callback(null, result);
      }
      var delayInSeconds = 30;
      if (client2.longRunningOperationInitialTimeout >= 0) {
        delayInSeconds = client2.longRunningOperationInitialTimeout;
      }
      
      var pollOperation = function () {
        setTimeout(function () {
          return client2.getOperationStatus(result.requestId, function (err2, result2) {
            if (err2 !== null && err2 !== undefined) {
              return callback(err2);
            } else {
              if (result2.status !== 'InProgress') {
                if (result2.status !== 'Succeeded') {
                  if (result2.error !== null && result2.error !== undefined) {
                    var ex = new Error(result2.error.code + ' : ' + result2.error.message);
                    ex.error = new Error();
                    ex.error.code = result2.error.code;
                    ex.error.message = result2.error.message;
                    return callback(ex);
                  } else {
                    var ex = new Error('');
                    return callback(ex);
                  }
                }
                
                return callback(null, result2);
              } else {
                delayInSeconds = 30;
                if (client2.longRunningOperationRetryTimeout >= 0) {
                  delayInSeconds = client2.longRunningOperationRetryTimeout;
                }
                pollOperation();
              }
            }
          });
        }, delayInSeconds * 1000);
      };
      
      pollOperation();
    });
  };
  
  /**
   * The List Cloud Services operation enumerates Windows Azure Store entries
   * that are provisioned for a subscription.
   * 
   * @param {function} callback
   * 
   * @returns {Stream} The response stream.
   */
  CloudServiceOperations.prototype.list = function(callback) {
    if (callback === null || callback === undefined) {
      throw new Error('callback cannot be null.');
    }
    // Validate
    
    // Tracing
    
    // Construct URL
    var url2 = '';
    url2 = url2 + '/';
    if (this.client.credentials.subscriptionId !== null && this.client.credentials.subscriptionId !== undefined) {
      url2 = url2 + encodeURIComponent(this.client.credentials.subscriptionId);
    }
    url2 = url2 + '/CloudServices/';
    var baseUrl = this.client.baseUri;
    // Trim '/' character from the end of baseUrl and beginning of url.
    if (baseUrl[baseUrl.length - 1] === '/') {
      baseUrl = baseUrl.substring(0, (baseUrl.length - 1) + 0);
    }
    if (url2[0] === '/') {
      url2 = url2.substring(1);
    }
    url2 = baseUrl + '/' + url2;
    url2 = url2.replace(' ', '%20');
    
    // Create HTTP transport objects
    var httpRequest = new WebResource();
    httpRequest.method = 'GET';
    httpRequest.headers = {};
    httpRequest.url = url2;
    
    // Set Headers
    httpRequest.headers['x-ms-version'] = '2013-06-01';
    
    // Send Request
    return this.client.pipeline(httpRequest, function (err, response, body) {
      if (err !== null && err !== undefined) {
        return callback(err);
      }
      var statusCode = response.statusCode;
      if (statusCode !== 200) {
        var error = new Error(body);
        error.statusCode = response.statusCode;
        return callback(error);
      }
      
      // Create Result
      var result = null;
      // Deserialize Response
      if (statusCode === 200) {
        var responseContent = body;
        result = { cloudServices: [] };
        var options = {};
        options.trim = false;
        options.strict = false;
        xml.parseString(responseContent, options, function (err2, responseDoc) {
          if (err2 !== null && err2 !== undefined) {
            return callback(err2);
          }
          
          var cloudServicesSequenceElement = js2xml.getElement(responseDoc, responseDoc, 'CLOUDSERVICES', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
          if (cloudServicesSequenceElement !== null && cloudServicesSequenceElement !== undefined) {
            for (var loweredIndex1 = 0; loweredIndex1 < js2xml.getElements(responseDoc, cloudServicesSequenceElement, 'CLOUDSERVICE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE').length; loweredIndex1 = loweredIndex1 + 1) {
              var cloudServicesElement = js2xml.getElements(responseDoc, cloudServicesSequenceElement, 'CLOUDSERVICE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE')[loweredIndex1];
              var cloudServiceInstance = { resources: [] };
              result.cloudServices.push(cloudServiceInstance);
              
              var nameElement = js2xml.getElement(responseDoc, cloudServicesElement, 'NAME', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
              if (nameElement !== null && nameElement !== undefined) {
                var nameInstance = nameElement;
                cloudServiceInstance.name = nameInstance;
              }
              
              var labelElement = js2xml.getElement(responseDoc, cloudServicesElement, 'LABEL', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
              if (labelElement !== null && labelElement !== undefined) {
                var labelInstance = new Buffer(labelElement, 'base64').toString('utf8');
                cloudServiceInstance.label = labelInstance;
              }
              
              var descriptionElement = js2xml.getElement(responseDoc, cloudServicesElement, 'DESCRIPTION', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
              if (descriptionElement !== null && descriptionElement !== undefined) {
                var descriptionInstance = descriptionElement;
                cloudServiceInstance.description = descriptionInstance;
              }
              
              var geoRegionElement = js2xml.getElement(responseDoc, cloudServicesElement, 'GEOREGION', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
              if (geoRegionElement !== null && geoRegionElement !== undefined) {
                var geoRegionInstance = geoRegionElement;
                cloudServiceInstance.geoRegion = geoRegionInstance;
              }
              
              var resourcesSequenceElement = js2xml.getElement(responseDoc, cloudServicesElement, 'RESOURCES', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
              if (resourcesSequenceElement !== null && resourcesSequenceElement !== undefined) {
                for (var loweredIndex2 = 0; loweredIndex2 < js2xml.getElements(responseDoc, resourcesSequenceElement, 'RESOURCE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE').length; loweredIndex2 = loweredIndex2 + 1) {
                  var resourcesElement = js2xml.getElements(responseDoc, resourcesSequenceElement, 'RESOURCE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE')[loweredIndex2];
                  var resourceInstance = { outputItems: {}, usageLimits: [] };
                  cloudServiceInstance.resources.push(resourceInstance);
                  
                  var resourceProviderNamespaceElement = js2xml.getElement(responseDoc, resourcesElement, 'RESOURCEPROVIDERNAMESPACE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                  if (resourceProviderNamespaceElement !== null && resourceProviderNamespaceElement !== undefined) {
                    var resourceProviderNamespaceInstance = resourceProviderNamespaceElement;
                    resourceInstance.namespace = resourceProviderNamespaceInstance;
                  }
                  
                  var typeElement = js2xml.getElement(responseDoc, resourcesElement, 'TYPE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                  if (typeElement !== null && typeElement !== undefined) {
                    var typeInstance = typeElement;
                    resourceInstance.type = typeInstance;
                  }
                  
                  var nameElement2 = js2xml.getElement(responseDoc, resourcesElement, 'NAME', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                  if (nameElement2 !== null && nameElement2 !== undefined) {
                    var nameInstance2 = nameElement2;
                    resourceInstance.name = nameInstance2;
                  }
                  
                  var planElement = js2xml.getElement(responseDoc, resourcesElement, 'PLAN', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                  if (planElement !== null && planElement !== undefined) {
                    var planInstance = planElement;
                    resourceInstance.plan = planInstance;
                  }
                  
                  var schemaVersionElement = js2xml.getElement(responseDoc, resourcesElement, 'SCHEMAVERSION', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                  if (schemaVersionElement !== null && schemaVersionElement !== undefined) {
                    var schemaVersionInstance = schemaVersionElement;
                    resourceInstance.schemaVersion = schemaVersionInstance;
                  }
                  
                  var eTagElement = js2xml.getElement(responseDoc, resourcesElement, 'ETAG', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                  if (eTagElement !== null && eTagElement !== undefined) {
                    var eTagInstance = eTagElement;
                    resourceInstance.eTag = eTagInstance;
                  }
                  
                  var stateElement = js2xml.getElement(responseDoc, resourcesElement, 'STATE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                  if (stateElement !== null && stateElement !== undefined) {
                    var stateInstance = stateElement;
                    resourceInstance.state = stateInstance;
                  }
                  
                  var usageMetersSequenceElement = js2xml.getElement(responseDoc, resourcesElement, 'USAGEMETERS', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                  if (usageMetersSequenceElement !== null && usageMetersSequenceElement !== undefined) {
                    for (var loweredIndex3 = 0; loweredIndex3 < js2xml.getElements(responseDoc, usageMetersSequenceElement, 'USAGEMETER', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE').length; loweredIndex3 = loweredIndex3 + 1) {
                      var usageMetersElement = js2xml.getElements(responseDoc, usageMetersSequenceElement, 'USAGEMETER', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE')[loweredIndex3];
                      var usageMeterInstance = {};
                      resourceInstance.usageLimits.push(usageMeterInstance);
                      
                      var nameElement3 = js2xml.getElement(responseDoc, usageMetersElement, 'NAME', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                      if (nameElement3 !== null && nameElement3 !== undefined) {
                        var nameInstance3 = nameElement3;
                        usageMeterInstance.name = nameInstance3;
                      }
                      
                      var unitElement = js2xml.getElement(responseDoc, usageMetersElement, 'UNIT', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                      if (unitElement !== null && unitElement !== undefined) {
                        var unitInstance = unitElement;
                        usageMeterInstance.unit = unitInstance;
                      }
                      
                      var includedElement = js2xml.getElement(responseDoc, usageMetersElement, 'INCLUDED', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                      if (includedElement !== null && includedElement !== undefined && includedElement.length !== 0) {
                        var includedInstance = parseInt(includedElement, 10);
                        usageMeterInstance.amountIncluded = includedInstance;
                      }
                      
                      var usedElement = js2xml.getElement(responseDoc, usageMetersElement, 'USED', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                      if (usedElement !== null && usedElement !== undefined && usedElement.length !== 0) {
                        var usedInstance = parseInt(usedElement, 10);
                        usageMeterInstance.amountUsed = usedInstance;
                      }
                    }
                  }
                  
                  var outputItemsSequenceElement = js2xml.getElement(responseDoc, resourcesElement, 'OUTPUTITEMS', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                  if (outputItemsSequenceElement !== null && outputItemsSequenceElement !== undefined) {
                    for (var loweredIndex4 = 0; loweredIndex4 < js2xml.getElements(responseDoc, outputItemsSequenceElement, 'OUTPUTITEM', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE').length; loweredIndex4 = loweredIndex4 + 1) {
                      var outputItemsElement = js2xml.getElements(responseDoc, outputItemsSequenceElement, 'OUTPUTITEM', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE')[loweredIndex4];
                      var outputItemsKey = js2xml.getElement(responseDoc, outputItemsElement, 'KEY', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                      var outputItemsValue = js2xml.getElement(responseDoc, outputItemsElement, 'VALUE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                      resourceInstance.outputItems[outputItemsKey] = outputItemsValue;
                    }
                  }
                  
                  var operationStatusElement = js2xml.getElement(responseDoc, resourcesElement, 'OPERATIONSTATUS', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                  if (operationStatusElement !== null && operationStatusElement !== undefined) {
                    var operationStatusInstance = {};
                    resourceInstance.status = operationStatusInstance;
                    
                    var typeElement2 = js2xml.getElement(responseDoc, operationStatusElement, 'TYPE', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                    if (typeElement2 !== null && typeElement2 !== undefined) {
                      var typeInstance2 = typeElement2;
                      operationStatusInstance.type = typeInstance2;
                    }
                    
                    var resultElement = js2xml.getElement(responseDoc, operationStatusElement, 'RESULT', 'HTTP://SCHEMAS.MICROSOFT.COM/WINDOWSAZURE');
                    if (resultElement !== null && resultElement !== undefined) {
                      var resultInstance = resultElement;
                      operationStatusInstance.result = resultInstance;
                    }
                  }
                }
              }
            }
          }
          
        });
      }
      result.statusCode = statusCode;
      result.requestId = response.headers['x-ms-request-id'];
      
      return callback(null, result);
    });
  };
  
  return CloudServiceOperations;
})();
